diff options
Diffstat (limited to 'doc/numpybook/capi.lyx')
-rw-r--r-- | doc/numpybook/capi.lyx | 24240 |
1 files changed, 0 insertions, 24240 deletions
diff --git a/doc/numpybook/capi.lyx b/doc/numpybook/capi.lyx deleted file mode 100644 index b14d5c4f5..000000000 --- a/doc/numpybook/capi.lyx +++ /dev/null @@ -1,24240 +0,0 @@ -#LyX 1.5.1 created this file. For more info see http://www.lyx.org/ -\lyxformat 276 -\begin_document -\begin_header -\textclass mybook -\language english -\inputencoding auto -\font_roman default -\font_sans default -\font_typewriter default -\font_default_family default -\font_sc false -\font_osf false -\font_sf_scale 100 -\font_tt_scale 100 -\graphics default -\paperfontsize default -\spacing onehalf -\papersize default -\use_geometry true -\use_amsmath 2 -\use_esint 0 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\leftmargin 1in -\topmargin 1in -\rightmargin 1in -\bottommargin 1in -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\author "" -\author "" -\end_header - -\begin_body - -\begin_layout Part -C-API -\end_layout - -\begin_layout Chapter -New Python Types and C-Structures -\end_layout - -\begin_layout Quotation -Beware of the man who won't be bothered with details. -\end_layout - -\begin_layout Right Address ---- -\emph on -William Feather, Sr. -\end_layout - -\begin_layout Quotation -The truth is out there. -\end_layout - -\begin_layout Right Address ----Chris Carter, The X Files -\end_layout - -\begin_layout Standard -NumPy provides a C-API to enable users to extend the system and get access - to the array object for use in other routines. - The best way to truly understand the C-API is to read the source code. - If you are unfamiliar with (C) source code, however, this can be a daunting - experience at first. - Be assured that the task becomes easier with practice, and you may be surprised - at how simple the C-code can be to understand. - Even if you don't think you can write C-code from scratch, it is much easier - to understand and modify already-written source code then create it -\emph on -de novo -\emph default -. - -\end_layout - -\begin_layout Standard -Python extensions are especially straightforward to understand because they - all have a very similar structure. - Admittedly, NumPy is not a trivial extension to Python, and may take a - little more snooping to grasp. - This is especially true because of the code-generation techniques, which - simplify maintenance of very similar code, but can make the code a little - less readable to beginners. - Still, with a little persistence, the code can be opened to your understanding. - It is my hope, that this guide to the C-API can assist in the process of - becoming familiar with the compiled-level work that can be done with NumPy - in order to squeeze that last bit of necessary speed out of your code. -\end_layout - -\begin_layout Standard -Several new types are defined in the C-code. - Most of these are accessible from Python, but a few are not exposed due - to their limited use. - Every new Python type has an associated PyObject * with an internal structure - that includes a pointer to a -\begin_inset Quotes eld -\end_inset - -method table -\begin_inset Quotes erd -\end_inset - - that defines how the new object behaves in Python. - When you receive a Python object into C code, you always get a pointer - to a -\family typewriter -PyObject -\family default - structure. - Because a -\family typewriter -PyObject -\family default - structure is very generic and defines only -\family typewriter -PyObject_HEAD -\family default -, by itself it is not very interesting. - However, different objects contain more details after the -\family typewriter -PyObject_HEAD -\family default - (but you have to cast to the correct type to access them --- or use accessor - functions or macros). - -\end_layout - -\begin_layout Section -New Python Types Defined -\end_layout - -\begin_layout Standard -Python types are the functional equivalent in C of classes in Python. - By constructing a new Python type you make available a new object for Python. - The ndarray object is an example of a new type defined in C. - New types are defined in C by two basic steps: -\end_layout - -\begin_layout Enumerate -creating a C-structure (usually named Py<Name>Object) that is binary-compatible - with the -\family typewriter -PyObject -\family default - structure itself but holds the additional information needed for that particula -r object; -\end_layout - -\begin_layout Enumerate -populating the -\family typewriter -PyTypeObject -\family default - table (pointed to by the ob_type member of the -\family typewriter -PyObject -\family default - structure) with pointers to functions that implement the desired behavior - for the type. - -\end_layout - -\begin_layout Standard -Instead of special method names which define behavior for Python classes, - there are -\begin_inset Quotes eld -\end_inset - -function tables -\begin_inset Quotes erd -\end_inset - - which point to functions that implement the desired results. - Since Python 2.2, the PyTypeObject itself has become dynamic which allows - C types that can be -\begin_inset Quotes eld -\end_inset - -sub-typed -\begin_inset Quotes erd -\end_inset - - from other C-types in C, and sub-classed in Python. - The children types inherit the attributes and methods from their parent(s). - -\end_layout - -\begin_layout Standard -There are two major new types: the ndarray ( -\family typewriter -PyArray_Type -\family default -) and the ufunc ( -\family typewriter -PyUFunc_Type -\family default -). - Additional types play a supportive role: the -\family typewriter -PyArrayIter_Type -\family default -, the -\family typewriter -PyArrayMultiIter_Type -\family default -, and the -\family typewriter -PyArrayDescr_Type -\family default -. - The -\family typewriter -PyArrayIter_Type -\family default - is the type for a flat iterator for an ndarray (the object that is returned - when getting the flat attribute). - The -\family typewriter -PyArrayMultiIter_Type -\family default - is the type of the object returned when calling -\family typewriter -broadcast -\family default -(). - It handles iteration and broadcasting over a collection of nested sequences. - Also, the -\family typewriter -PyArrayDescr_Type -\family default - is the data-type-descriptor type whose instances describe the data. - Finally, there are 21 new scalar-array types which are new Python scalars - corresponding to each of the fundamental data types available for arrays. - An additional 10 other types are place holders that allow the array scalars - to fit into a hierarchy of actual Python types. - -\end_layout - -\begin_layout Subsection -PyArray_Type -\end_layout - -\begin_layout Standard -The Python type of the ndarray is -\family typewriter -PyArray_Type -\family default - -\begin_inset LatexCommand index -name "PyArray\\_Type" - -\end_inset - -. - In C, every ndarray is a pointer to a -\family typewriter -PyArrayObject -\family default - structure. - The ob_type member of this structure contains a pointer to the -\family typewriter -PyArray_Type -\family default - typeobject. - -\end_layout - -\begin_layout Standard -The -\family typewriter -PyArrayObject -\family default - C-structure contains all of the required information for an array. - All instances of an ndarray (and its subclasses) will have this structure. - For future compatibility, these structure members should normally be accessed - using the provided macros. - If you need a shorter name, then you can make use of -\family typewriter -NPY_AO -\family default - which is defined to be equivalent to -\family typewriter -PyArrayObject -\family default -. -\end_layout - -\begin_layout LyX-Code -typedef struct PyArrayObject { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -char * -\emph default -data; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nd; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp * -\emph default -dimensions; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp * -\emph default -strides; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject * -\emph default -base; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_Descr * -\emph default -descr; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - flags; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject * -\emph default -weakreflist; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArrayObject -\emph default -; -\end_layout - -\begin_layout Description -PyObject_HEAD This is needed by all Python objects. - It consists of (at least) a reference count member ( -\family typewriter -ob_refcnt -\family default -) and a pointer to the typeobject ( -\family typewriter -ob_type -\family default -). - (Other elements may also be present if Python was compiled with special - options see Include/object.h in the Python source tree for more information). - The ob_type member points to a Python type object. - -\end_layout - -\begin_layout Description -data A pointer to the first element of the array. - This pointer can (and normally should) be recast to the data type of the - array. - -\end_layout - -\begin_layout Description -nd An integer providing the number of dimensions for this array. - When nd is 0, the array is sometimes called a rank-0 array. - Such arrays have undefined dimensions and strides and cannot be accessed. - -\family typewriter -NPY_MAXDIMS -\family default - is the largest number of dimensions for any array. -\end_layout - -\begin_layout Description -dimensions An array of integers providing the shape in each dimension as - long as nd -\begin_inset Formula $\geq$ -\end_inset - -1. - The integer is always large enough to hold a pointer on the platform, so - the dimension size is only limited by memory. - -\end_layout - -\begin_layout Description -strides An array of integers providing for each dimension the number of - bytes that must be skipped to get to the next element in that dimension. - -\end_layout - -\begin_layout Description -base This member is used to hold a pointer to another Python object that - is related to this array. - There are two use cases: 1) If this array does not own its own memory, - then base points to the Python object that owns it (perhaps another array - object), 2) If this array has the -\family typewriter -NPY_UPDATEIFCOPY -\family default - flag set, then this array is a working copy of a -\begin_inset Quotes eld -\end_inset - -misbehaved -\begin_inset Quotes erd -\end_inset - - array. - As soon as this array is deleted, the array pointed to by base will be - updated with the contents of this array. - -\end_layout - -\begin_layout Description -descr A pointer to a data-type descriptor object (see below). - The data-type descriptor object is an instance of a new built-in type which - allows a generic description of memory. - There is a descriptor structure for each data type supported. - This descriptor structure contains useful information about the type as - well as a pointer to a table of function pointers to implement specific - functionality. -\end_layout - -\begin_layout Description -flags Flags indicating how the memory pointed to by data is to be interpreted. - Possible flags are -\family typewriter -NPY_C_CONTIGUOUS -\family default -, -\family typewriter -NPY_F_CONTIGUOUS -\family default -, -\family typewriter -NPY_OWNDATA -\family default -, -\family typewriter -NPY_ALIGNED -\family default -, -\family typewriter -NPY_WRITEABLE -\family default -, and -\family typewriter -NPY_UPDATEIFCOPY -\family default -. -\end_layout - -\begin_layout Description -weakreflist This member allows array objects to have weak references (using - the weakref module). - -\end_layout - -\begin_layout Subsection -PyArrayDescr_Type -\end_layout - -\begin_layout Standard -The -\family typewriter -PyArrayDescr_Type -\family default - -\begin_inset LatexCommand index -name "PyArrayDescr\\_Type" - -\end_inset - - is the built-in type of the data-type-descriptor objects used to describe - how the bytes comprising the array are to be interpreted. - There are 21 statically-defined -\family typewriter -PyArray_Descr -\family default - objects for the built-in data-types. - While these participate in reference counting, their reference count should - never reach zero. - There is also a dynamic table of user-defined -\family typewriter -PyArray_Descr -\family default - objects that is also maintained. - Once a data-type-descriptor object is -\begin_inset Quotes eld -\end_inset - -registered -\begin_inset Quotes erd -\end_inset - - it should never be deallocated either. - The function -\family typewriter -PyArray_DescrFromType -\family default -(...) can be used to retrieve a -\family typewriter -PyArray_Descr -\family default - object from an enumerated type-number (either built-in or user-defined). - The format of the structure that lies at the heart of the -\family typewriter -PyArrayDescr_Type -\family default - is. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -PyTypeObject * -\emph default -typeobj; -\end_layout - -\begin_layout LyX-Code - -\emph on -char -\emph default - kind; -\end_layout - -\begin_layout LyX-Code - -\emph on -char -\emph default - type; -\end_layout - -\begin_layout LyX-Code - -\emph on -char -\emph default - byteorder; -\end_layout - -\begin_layout LyX-Code - -\emph on -char -\emph default - unused; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - flags; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - type_num; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - elsize; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - alignment; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ArrayDescr -\emph default - *subarray; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject -\emph default - *fields; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ArrFuncs -\emph default - *f; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArray_Descr -\emph default -; -\end_layout - -\begin_layout Description -typeobj Pointer to a typeobject that is the corresponding Python type for - the elements of this array. - For the builtin types, this points to the corresponding array scalar. - For user-defined types, this should point to a user-defined typeobject. - This typeobject can either inherit from array scalars or not. - If it does not inherit from array scalars, then the -\family typewriter -NPY_USE_GETITEM -\family default - and -\family typewriter -NPY_USE_SETITEM -\family default - flags should be set in the -\family typewriter -flags -\family default - member. -\end_layout - -\begin_layout Description -kind A character code indicating the kind of array (using the array interface - typestring notation). - A 'b' represents Boolean, a 'i' represents signed integer, a 'u' represents - unsigned integer, 'f' represents floating point, 'c' represents complex - floating point, 'S' represents 8-bit character string, 'U' represents 32-bit/ch -aracter unicode string, and 'V' repesents arbitrary. - -\end_layout - -\begin_layout Description -type A traditional character code indicating the data type. - -\end_layout - -\begin_layout Description -byteorder A character indicating the byte-order: '>' (big-endian), '<' (little-e -ndian), '=' (native), '|' (irrelevant, ignore). - All builtin data-types have byteorder '='. - -\end_layout - -\begin_layout Description -flags A data-type bit-flag that determines if the data-type exhibits - object-array like behavior. - Each bit in this member is a flag which are named as: -\end_layout - -\begin_deeper -\begin_layout Description -NPY_ITEM_REFCOUNT\InsetSpace ~ -(NPY_ITEM_HASOBJECT) Indicates that items of this data-type - must be reference counted (using -\family typewriter -Py_INCREF -\family default - and -\family typewriter -Py_DECREF -\family default -). - -\end_layout - -\begin_layout Description -NPY_ITEM_LISTPICKLE Indicates arrays of this data-type must be converted - to a list before pickling. - -\end_layout - -\begin_layout Description -NPY_ITEM_IS_POINTER Indicates the item is a pointer to some other data-type -\end_layout - -\begin_layout Description -NPY_NEEDS_INIT Indicates memory for this data-type must be initialized (set - to 0) on creation. - -\end_layout - -\begin_layout Description -NPY_NEEDS_PYAPI Indicates this data-type requires the Python C-API during - access (so don't give up the GIL if array access is going to be needed). - -\end_layout - -\begin_layout Description -NPY_USE_GETITEM On array access use the -\family typewriter -f->getitem -\family default - function pointer instead of the standard conversion to an array scalar. - Must use if you don't define an array scalar to go along with the data-type. - -\end_layout - -\begin_layout Description -NPY_USE_SETITEM When creating a 0-d array from an array scalar use -\family typewriter -f->setitem -\family default - instead of the standard copy from an array scalar. - Must use if you don't define an array scalar to go along with the data-type. - -\end_layout - -\begin_layout Description -NPY_FROM_FIELDS The bits that are inherited for the parent data-type if - these bits are set in any field of the data-type. - Currently ( -\family typewriter -NPY_NEEDS_INIT -\family default - | -\family typewriter -NPY_LIST_PICKLE -\family default - | -\family typewriter -NPY_ITEM_REFCOUNT -\family default - | -\family typewriter -NPY_NEEDS_PYAPI -\family default -). - -\end_layout - -\begin_layout Description -NPY_OBJECT_DTYPE_FLAGS Bits set for the object data-type: ( -\family typewriter -NPY_LIST_PICKLE -\family default - | -\family typewriter -NPY_USE_GETITEM -\family default - | -\family typewriter -NPY_ITEM_IS_POINTER -\family default - | -\family typewriter -NPY_REFCOUNT -\family default - | -\family typewriter -NPY_NEEDS_INIT -\family default - | -\family typewriter -NPY_NEEDS_PYAPI -\family default -). - -\end_layout - -\begin_layout Description -PyDataType_FLAGCHK ( -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - flags) Return true if all the given flags are set for the data-type object. - -\end_layout - -\begin_layout Description -PyDataType_REFCHK ( -\family typewriter -PyArray_Descr* -\family default - dtype) Equivalent to -\family typewriter -PyDataType_FLAGCHK -\family default -( -\emph on -dtype -\emph default -, -\family typewriter -NPY_ITEM_REFCOUNT -\family default -). -\end_layout - -\end_deeper -\begin_layout Description -type_num A number that uniquely identifies the data type. - For new data-types, this number is assigned when the data-type is registered. -\end_layout - -\begin_layout Description -elsize For data types that are always the same size (such as long), this - holds the size of the data type. - For flexible data types where different arrays can have a different elementsize -, this should be 0. -\end_layout - -\begin_layout Description -alignment A number providing alignment information for this data type. - Specifically, it shows how far from the start of a 2-element structure - (whose first element is a -\family typewriter -char -\family default -), the compiler places an item of this type: -\family typewriter -offsetof(struct {char c; type v;}, v) -\end_layout - -\begin_layout Description -subarray If this is non- -\family typewriter -NULL -\family default -, then this data-type descriptor is a C-style contiguous array of another - data-type descriptor. - In other-words, each element that this descriptor describes is actually - an array of some other base descriptor. - This is most useful as the data-type descriptor for a field in another - data-type descriptor. - The fields member should be -\family typewriter -NULL -\family default - if this is non- -\family typewriter -NULL -\family default - (the fields member of the base descriptor can be non- -\family typewriter -NULL -\family default - however). - The -\family typewriter -PyArray_ArrayDescr -\family default - structure is defined using -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_Descr -\emph default - *base; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject -\emph default - *shape; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArray_ArrayDescr; -\end_layout - -\begin_layout Description -\InsetSpace ~ - The elements of this structure are: -\end_layout - -\begin_deeper -\begin_layout Description -base The data-type-descriptor object of the base-type. - -\end_layout - -\begin_layout Description -shape The shape (always C-style contiguous) of the sub-array as a Python - tuple. - -\end_layout - -\end_deeper -\begin_layout Description -fields If this is non-NULL, then this data-type-descriptor has fields described - by a Python dictionary whose keys are names (and also titles if given) - and whose values are tuples that describe the fields. - Recall that a data-type-descriptor always describes a fixed-length set - of bytes. - A field is a named sub-region of that total, fixed-length collection. - A field is described by a tuple composed of another data-type-descriptor - and a byte offset. - Optionally, the tuple may contain a title which is normally a Python string. - These tuples are placed in this dictionary keyed by name (and also title - if given). - -\end_layout - -\begin_layout Description -f A pointer to a structure containing functions that the type needs to implement - internal features. - These functions are not the same thing as the universal functions (ufuncs) - described later. - Their signatures can vary arbitrarily. - Not all of these function pointers must be defined for a given type. - The required members are -\family typewriter -nonzero -\family default -, -\family typewriter -copyswap -\family default -, -\family typewriter -copyswapn -\family default -, -\family typewriter -setitem -\family default -, -\family typewriter -getitem -\family default -, and -\family typewriter -cast -\family default -. - These are assumed to be non- -\family typewriter -NULL -\family default - and -\family typewriter -NULL -\family default - entries will cause a program crash. - The other functions may be -\family typewriter -NULL -\family default - which will just mean reduced functionality for that data-type. - (Also, the nonzero function will be filled in with a default function if - it is -\family typewriter -NULL -\family default - when you register a user-defined data-type). -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - -\emph on - PyArray_VectorUnaryFunc -\emph default - -\emph on -* -\emph default -cast[NPY_NTYPES]; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_GetItemFunc * -\emph default -getitem; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_SetItemFunc * -\emph default -setitem; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_CopySwapNFunc * -\emph default -copyswapn; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_CopySwapFunc * -\emph default -copyswap; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_CompareFunc * -\emph default -compare; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ArgFunc * -\emph default -argmax; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_DotFunc * -\emph default -dotfunc; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ScanFunc * -\emph default -scanfunc; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_FromStrFunc -\emph default - *fromstr; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_NonzeroFunc * -\emph default -nonzero; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_FillFunc -\emph default - *fill; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_FillWithScalarFunc -\emph default - *fillwithscalar; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_SortFunc -\emph default - *sort[NPY_NSORTS]; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ArgSortFunc -\emph default - *argsort[NPY_NSORTS]; -\newline - -\emph on -PyObject -\emph default - *castdict; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArray_ScalarKindFunc -\emph default - *scalarkind; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - **cancastscalarkindto; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - *cancastto; -\end_layout - -\begin_layout LyX-Code - -\shape italic -int -\shape default - listpickle -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArray_ArrFuncs -\emph default -; -\end_layout - -\begin_layout Description -\InsetSpace ~ - The concept of a behaved segment is used in the description of the function - pointers. - A behaved segment is one that is aligned and in native machine byte-order - for the data-type. - The -\family typewriter -nonzero -\family default -, -\family typewriter -copyswap -\family default -, -\family typewriter -copyswapn -\family default -, -\family typewriter -getitem -\family default -, and -\family typewriter -setitem -\family default - functions can (and must) deal with mis-behaved arrays. - The other functions require behaved memory segments. -\end_layout - -\begin_deeper -\begin_layout Description -cast ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - from, -\family typewriter -void* -\family default - to, -\family typewriter -npy_intp -\family default - n, -\family typewriter -void* -\family default - fromarr, -\family typewriter -void* -\family default - toarr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - An array of function pointers to cast from the current type to all of the - other builtin types. - Each function casts a contiguous, aligned, and notswapped buffer pointed - at by -\emph on -from -\emph default - to a contiguous, aligned, and notswapped buffer pointed at by -\emph on -to -\emph default - The number of items to cast is given by -\emph on -n -\emph default -, and the arguments -\emph on -fromarr -\emph default - and -\emph on -toarr -\emph default - are interpreted as PyArrayObjects for flexible arrays to get itemsize informati -on. -\end_layout - -\begin_layout Description -getitem ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that returns a standard Python object from a single - element of the array object -\emph on -arr -\emph default - pointed to by -\emph on -data -\emph default -. - This function must be able to deal with -\begin_inset Quotes eld -\end_inset - -misbehaved -\begin_inset Quotes erd -\end_inset - - (misaligned and/or swapped) arrays correctly. - -\end_layout - -\begin_layout Description -setitem ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - item, -\family typewriter -void* -\family default - data, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that sets the Python object -\emph on -item -\emph default - into the array, -\emph on -arr -\emph default -, at the position pointed to by -\emph on -data -\emph default -. - This function deals with -\begin_inset Quotes eld -\end_inset - -misbehaved -\begin_inset Quotes erd -\end_inset - - arrays. - If successful, a zero is returned, otherwise, a negative one is returned - (and a Python error set). - -\end_layout - -\begin_layout Description -copyswapn ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - dest, -\family typewriter -npy_intp -\family default - dstride, -\family typewriter -void* -\family default - src, -\family typewriter -npy_intp -\family default - sstride, -\family typewriter -npy_intp -\family default - n, -\family typewriter -int -\family default - swap, void *arr) -\end_layout - -\begin_layout Description -copyswap ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - dest, -\family typewriter -void* -\family default - src, -\family typewriter -int -\family default - swap, void *arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - These members are both pointers to functions to copy data from -\emph on -src -\emph default - to -\emph on -dest -\emph default - and -\emph on -swap -\emph default - if indicated. - The value of arr is only used for flexible ( -\family typewriter -NPY_STRING -\family default -, -\family typewriter -NPY_UNICODE -\family default -, and -\family typewriter -NPY_VOID -\family default -) arrays (and is obtained from -\family typewriter -arr->descr->elsize -\family default -). - The second function copies a single value, while the first loops over n - values with the provided strides. - These functions can deal with misbehaved -\emph on -src -\emph default - data. - If -\emph on -src -\emph default - is NULL then no copy is performed. - If -\emph on -swap -\emph default - is 0, then no byteswapping occurs. - It is assumed that -\emph on -dest -\emph default - and -\emph on -src -\emph default - do not overlap. - If they overlap, then use -\family typewriter -memmove -\family default -(...) first followed by -\family typewriter -copyswap(n) -\family default - with NULL valued -\family typewriter -src -\family default -. -\end_layout - -\begin_layout Description -compare ( -\family typewriter -int -\family default -) ( -\family typewriter -const void* -\family default - d1, -\family typewriter -const void* -\family default - d2, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that compares two elements of the array, -\family typewriter -arr -\family default -, pointed to by -\family typewriter -d1 -\family default - and -\family typewriter -d2 -\family default -. - This function requires behaved arrays. - The return value is 1 if * -\family typewriter -d1 -\family default - > * -\family typewriter -d2 -\family default -, 0 if * -\family typewriter -d1 -\family default - == * -\family typewriter -d2 -\family default -, and -1 if * -\family typewriter -d1 -\family default - < * -\family typewriter -d2 -\family default -. - The array object arr is used to retrieve itemsize and field information - for flexible arrays. -\end_layout - -\begin_layout Description -argmax ( -\family typewriter -int -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -npy_intp -\family default - n, -\family typewriter -npy_intp* -\family default - max_ind, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that retrieves the index of the largest of -\family typewriter -n -\family default - elements in -\family typewriter -arr -\family default - beginning at the element pointed to by -\family typewriter -data -\family default -. - This function requires that the memory segment be contiguous and behaved. - The return value is always 0. - The index of the largest element is returned in -\family typewriter -max_ind -\family default -. -\end_layout - -\begin_layout Description -dotfunc ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - ip1, -\family typewriter -npy_intp -\family default - is1, -\family typewriter -void* -\family default - ip2, -\family typewriter -npy_intp -\family default - is2, -\family typewriter -void* -\family default - op, -\family typewriter -npy_intp -\family default - n, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that multiplies two -\family typewriter -n -\family default --length sequences together, adds them, and places the result in element - pointed to by -\family typewriter -op -\family default - of -\family typewriter -arr -\family default -. - The start of the two sequences are pointed to by -\family typewriter -ip1 -\family default - and -\family typewriter -ip2 -\family default -. - To get to the next element in each sequence requires a jump of -\family typewriter -is1 -\family default - and -\family typewriter -is2 -\family default - -\emph on -bytes -\emph default -, respectively. - This function requires behaved (though not necessarily contiguous) memory. - -\end_layout - -\begin_layout Description -scanfunc ( -\family typewriter -int -\family default -) ( -\family typewriter -FILE* -\family default - fd, -\family typewriter -void* -\family default - ip , -\family typewriter -void* -\family default - sep , -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that scans (scanf style) one element of the correspondi -ng type from the file descriptor -\family typewriter -fd -\family default - into the array memory pointed to by -\family typewriter -ip -\family default -. - The array is assumed to be behaved. - If -\family typewriter -sep -\family default - is not NULL, then a separator string is also scanned from the file before - returning. - The last argument -\family typewriter -arr -\family default - is the array to be scanned into. - A 0 is returned if the scan is successful. - A negative number indicates something went wrong: -1 means the end of file - was reached before the separator string could be scanned, -4 means that - the end of file was reached before the element could be scanned, and -3 - means that the element could not be interpreted from the format string. - Requires a behaved array. -\end_layout - -\begin_layout Description -fromstr ( -\family typewriter -int -\family default -) ( -\family typewriter -char* -\family default - str, -\family typewriter -void* -\family default - ip, -\family typewriter -char** -\family default - endptr, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that converts the string pointed to by -\family typewriter -str -\family default - to one element of the corresponding type and places it in the memory location - pointed to by -\family typewriter -ip -\family default -. - After the conversion is completed, -\family typewriter -*endptr -\family default - points to the rest of the string. - The last argument -\family typewriter -arr -\family default - is the array into which ip points (needed for variable-size data-types). - Returns 0 on success or -1 on failure. - Requires a behaved array. -\end_layout - -\begin_layout Description -nonzero ( -\family typewriter -Bool -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that returns TRUE if the item of -\family typewriter -arr -\family default - pointed to by -\family typewriter -data -\family default - is nonzero. - This function can deal with misbehaved arrays. - -\end_layout - -\begin_layout Description -fill ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -npy_intp -\family default - length, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that fills a contiguous array of given length with - data. - The first two elements of the array must already be filled-in. - From these two values, a delta will be computed and the values from item - 3 to the end will be computed by repeatedly adding this computed delta. - The data buffer must be well-behaved. -\end_layout - -\begin_layout Description -fillwithscalar ( -\family typewriter -void -\family default -)( -\family typewriter -void* -\family default - buffer, -\family typewriter -npy_intp -\family default - length, -\family typewriter -void* -\family default - value, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to a function that fills a contiguous -\family typewriter -buffer -\family default - of the given -\family typewriter -length -\family default - with a single scalar -\family typewriter -value -\family default - whose address is given. - The final argument is the array which is needed to get the itemsize for - variable-length arrays. - -\end_layout - -\begin_layout Description -sort ( -\family typewriter -int -\family default -) ( -\family typewriter -void* -\family default - start, -\family typewriter -npy_intp -\family default - length, -\family typewriter -void* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - An array of function pointers to a particular sorting algorithms. - A particular sorting algorithm is obtained using a key (so far -\family typewriter -NPY_QUICKSORT -\family default -, -\family typewriter -NPY_HEAPSORT -\family default -, and -\family typewriter -NPY_MERGESORT -\family default - are defined). - These sorts are done in-place assuming contiguous and aligned data. - -\end_layout - -\begin_layout Description -argsort ( -\family typewriter -int -\family default -) ( -\family typewriter -void* -\family default - start, -\family typewriter -npy_intp* -\family default - result, -\family typewriter -npy_intp -\family default - length, void *arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - An array of function pointers to sorting algorithms for this data type. - The same sorting algorithms as for sort are available. - The indices producing the sort are returned in result (which must be initialize -d with indices 0 to length-1 inclusive). - -\end_layout - -\begin_layout Description -castdict -\end_layout - -\begin_layout Description -\InsetSpace ~ - Either -\family typewriter -NULL -\family default - or a dictionary containing low-level casting functions for user-defined - data-types. - Each function is wrapped in a -\family typewriter -PyCObject* -\family default - and keyed by the data-type number. - -\end_layout - -\begin_layout Description -scalarkind ( -\family typewriter -NPY_SCALARKIND -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A function to determine how scalars of this type should be interpreted. - The argument is -\family typewriter -NULL -\family default - or a 0-dimensional array containing the data (if that is needed to determine - the kind of scalar). - The return value must be of type -\family typewriter -NPY_SCALARKIND -\family default -. - -\end_layout - -\begin_layout Description -cancastscalarkindto -\end_layout - -\begin_layout Description -\InsetSpace ~ - Either -\family typewriter -NULL -\family default - or an array of -\family typewriter -NPY_NSCALARKINDS -\family default - pointers. - These pointers should each be either -\family typewriter -NULL -\family default - or a pointer to an array of integers (terminated by -\family typewriter -NPY_NOTYPE -\family default -) indicating data-types that a scalar of this data-type of the specified - kind can be cast to safely (this usually means without losing precision). -\end_layout - -\begin_layout Description -cancastto -\end_layout - -\begin_layout Description -\InsetSpace ~ - Either -\family typewriter -NULL -\family default - or an array of integers (terminated by -\family typewriter -NPY_NOTYPE -\family default -) indicated data-types that this data-type can be cast to safely (this usually - means without losing precision). -\end_layout - -\begin_layout Description -listpickle -\end_layout - -\begin_layout Description -\InsetSpace ~ - Unused. -\end_layout - -\end_deeper -\begin_layout Standard -The -\family typewriter -PyArray_Type -\family default - typeobject implements many of the features of Python objects including - the tp_as_number, tp_as_sequence, tp_as_mapping, and tp_as_buffer interfaces. - The rich comparison (tp_richcompare) is also used along with new-style - attribute lookup for methods (tp_methods) and properties (tp_getset). - The -\family typewriter -PyArray_Type -\family default - can also be sub-typed. - -\end_layout - -\begin_layout Tip -The tp_as_number methods use a generic approach to call whatever function - has been registered for handling the operation. - The function PyNumeric_SetOps(..) can be used to register functions to handle - particular mathematical operations (for all arrays). - When the umath module is imported, it sets the numeric operations for all - arrays to the corresponding ufuncs. - -\newline -The tp_str and tp_repr methods can also be altered using PyString_SetStringFunc -tion(...). -\end_layout - -\begin_layout Subsection -PyUFunc_Type -\end_layout - -\begin_layout Standard -The ufunc object is implemented by creation of the -\family typewriter -PyUFunc_Type -\family default - -\begin_inset LatexCommand index -name "PyUFunc\\_Type" - -\end_inset - -. - It is a very simple type that implements only basic getattribute behavior, - printing behavior, and has call behavior which allows these objects to - act like functions. - The basic idea behind the ufunc is to hold a reference to fast 1-dimensional - (vector) loops for each data type that supports the operation. - These one-dimensional loops all have the same signature and are the key - to creating a new ufunc. - They are called by the generic looping code as appropriate to implement - the N-dimensional function. - There are also some generic 1-d loops defined for floating and complexfloating - arrays that allow you to define a ufunc using a single scalar function - ( -\emph on -e.g. - -\emph default - atanh). - -\end_layout - -\begin_layout Standard -The core of the ufunc is the -\family typewriter -PyUFuncObject -\family default - which contains all the information needed to call the underlying C-code - loops that perform the actual work. - It has the following structure. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nin; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nout; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nargs; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - identity; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyUFuncGenericFunction * -\emph default -functions; -\end_layout - -\begin_layout LyX-Code - -\emph on -void ** -\emph default -data; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - ntypes; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - check_return; -\end_layout - -\begin_layout LyX-Code - -\emph on -char * -\emph default -name; -\end_layout - -\begin_layout LyX-Code - -\emph on -char * -\emph default -types; -\end_layout - -\begin_layout LyX-Code - -\emph on -char * -\emph default -doc; -\end_layout - -\begin_layout LyX-Code - -\emph on -void * -\emph default -ptr; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject * -\emph default -obj; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject * -\emph default -userloops; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyUFuncObject -\emph default -; -\end_layout - -\begin_layout Description -PyObject_HEAD required for all Python objects. -\end_layout - -\begin_layout Description -nin The number of input arguments. -\end_layout - -\begin_layout Description -nout The number of output arguments. -\end_layout - -\begin_layout Description -nargs The total number of arguments ( -\emph on -nin -\emph default -+ -\emph on -nout -\emph default -). - This must be less than -\family typewriter -NPY_MAXARGS -\family default -. -\end_layout - -\begin_layout Description -identity Either -\family typewriter -PyUFunc_One -\family default -, -\family typewriter -PyUFunc_Zero -\family default -, or -\family typewriter -PyUFunc_None -\family default - to indicate the identity for this operation. - It is only used for a reduce-like call on an empty array. -\end_layout - -\begin_layout Description -functions ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - extradata ) -\end_layout - -\begin_layout Description -\InsetSpace ~ - An array of function pointers --- one for each data type supported by the - ufunc. - This is the vector loop that is called to implement the underlying function - -\emph on -dims -\emph default -[0] times. - The first argument, -\emph on -args -\emph default -, is an array of -\emph on -nargs -\emph default - pointers to behaved memory. - Pointers to the data for the input arguments are first, followed by the - pointers to the data for the output arguments. - How many bytes must be skipped to get to the next element in the sequence - is specified by the corresponding entry in the -\emph on -steps -\emph default - array. - The last argument allows the loop to receive extra information. - This is commonly used so that a single, generic vector loop can be used - for multiple functions. - In this case, the actual scalar function to call is passed in as -\emph on -extradata -\emph default -. - The size of this function pointer array is ntypes. - -\end_layout - -\begin_layout Description -data Extra data to be passed to the 1-d vector loops or -\family typewriter -NULL -\family default - if no extra-data is needed. - This C-array must be the same size ( -\emph on -i.e. - -\emph default - ntypes) as the functions array. - -\family typewriter -NULL -\family default - is used if extra_data is not needed. - Several C-API calls for UFuncs are just 1-d vector loops that make use - of this extra data to receive a pointer to the actual function to call. - -\end_layout - -\begin_layout Description -ntypes The number of supported data types for the ufunc. - This number specifies how many different 1-d loops (of the builtin data - types) are available. - -\end_layout - -\begin_layout Description -check_return Obsolete and unused. - However, it is set by the corresponding entry in the main ufunc creation - routine: -\family typewriter -PyUFunc_FromFuncAndData -\family default -(...). -\end_layout - -\begin_layout Description -name A string name for the ufunc. - This is used dynamically to build the __doc__ attribute of ufuncs. -\end_layout - -\begin_layout Description -types An array of -\emph on -nargs -\series bold -\emph default - -\begin_inset Formula $\times$ -\end_inset - - -\series default -\emph on -ntypes -\emph default - 8-bit type_numbers which contains the type signature for the function for - each of the supported (builtin) data types. - For each of the -\emph on -ntypes -\emph default - functions, the corresponding set of type numbers in this array shows how - the -\emph on -args -\emph default - argument should be interpreted in the 1-d vector loop. - These type numbers do not have to be the same type and mixed-type ufuncs - are supported. - -\end_layout - -\begin_layout Description -doc Documentation for the ufunc. - Should not contain the function signature as this is generated dynamically - when __doc__ is retrieved. -\end_layout - -\begin_layout Description -ptr Any dynamically allocated memory. - Currently, this is used for dynamic ufuncs created from a python function - to store room for the types, data, and name members. -\end_layout - -\begin_layout Description -obj For ufuncs dynamically created from python functions, this member holds - a reference to the underlying Python function. -\end_layout - -\begin_layout Description -userloops A dictionary of user-defined 1-d vector loops (stored as CObject - ptrs) for user-defined types. - A loop may be registered by the user for any user-defined type. - It is retrieved by type number. - User defined type numbers are always larger than -\family typewriter -NPY_USERDEF -\family default -. - -\end_layout - -\begin_layout Subsection -PyArrayIter_Type -\end_layout - -\begin_layout Standard -This -\begin_inset LatexCommand index -name "PyArrayIter\\_Type" - -\end_inset - - is an iterator object that makes it easy to loop over an N-dimensional - array. - It is the object returned from the flat attribute of an ndarray. - It is also used extensively throughout the implementation internals to - loop over an N-dimensional array. - The tp_as_mapping interface is implemented so that the iterator object - can be indexed (using 1-d indexing), and a few methods are implemented - through the tp_methods table. - This object implements the next method and can be used anywhere an iterator - can be used in Python. -\end_layout - -\begin_layout Standard -The C-structure corresponding to an object of -\family typewriter -PyArrayIter_Type -\family default - is the -\family typewriter -PyArrayIterObject -\family default -. - The -\family typewriter -PyArrayIterObject -\family default - is used to keep track of a pointer into an N-dimensional array. - It contains associated information used to quickly march through the array. - The pointer can be adjusted in three basic ways: 1) advance to the -\begin_inset Quotes eld -\end_inset - -next -\begin_inset Quotes erd -\end_inset - - position in the array in a C-style contiguous fashion, 2) advance to an - arbitrary N-dimensional coordinate in the array, and 3) advance to an arbitrary - one-dimensional index into the array. - The members of the -\family typewriter -PyArrayIterObject -\family default - structure are used in these calculations. - Iterator objects keep their own dimension and strides information about - an array. - This can be adjusted as needed for -\begin_inset Quotes eld -\end_inset - -broadcasting, -\begin_inset Quotes erd -\end_inset - - or to loop over only specific dimensions. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nd_m1; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - index; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - size; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - coordinates -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - dims_m1 -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - strides -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - backstrides -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - factors -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArrayObject * -\emph default -ao; -\end_layout - -\begin_layout LyX-Code - -\emph on -char * -\emph default -dataptr; -\end_layout - -\begin_layout LyX-Code - -\emph on -Bool -\emph default - contiguous; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArrayIterObject -\emph default -; -\end_layout - -\begin_layout Description -nd_m1 -\begin_inset Formula $N-1$ -\end_inset - - where -\begin_inset Formula $N$ -\end_inset - - is the number of dimensions in the underlying array. -\end_layout - -\begin_layout Description -index The current 1-d index into the array. -\end_layout - -\begin_layout Description -size The total size of the underlying array. -\end_layout - -\begin_layout Description -coordinates An -\begin_inset Formula $N$ -\end_inset - --dimensional index into the array. -\end_layout - -\begin_layout Description -dims_m1 The size of the array minus 1 in each dimension. -\end_layout - -\begin_layout Description -strides The strides of the array. - How many bytes needed to jump to the next element in each dimension. - -\end_layout - -\begin_layout Description -backstrides How many bytes needed to jump from the end of a dimension back - to its beginning. - Note that -\emph on -backstrides -\emph default -[k]= -\emph on -strides -\emph default -[k]*d -\emph on -ims_m1 -\emph default -[k], but it is stored here as an optimization. -\end_layout - -\begin_layout Description -factors This array is used in computing an N-d index from a 1-d index. - It contains needed products of the dimensions. - -\end_layout - -\begin_layout Description -ao A pointer to the underlying ndarray this iterator was created to represent. -\end_layout - -\begin_layout Description -dataptr This member points to an element in the ndarray indicated by the - index. -\end_layout - -\begin_layout Description -contiguous This flag is true if the underlying array is -\family typewriter -NPY_C_CONTIGUOUS -\family default -. - It is used to simplify calculations when possible. - -\end_layout - -\begin_layout Standard -How to use an array iterator on a C-level is explained more fully in later - sections. - Typically, you do not need to concern yourself with the internal structure - of the iterator object, and merely interact with it through the use of - the macros -\family typewriter -PyArray_ITER_NEXT -\family default -(it), -\family typewriter -PyArray_ITER_GOTO -\family default -(it, dest), or -\family typewriter -PyArray_ITER_GOTO1D -\family default -(it, index). - All of these macros require the argument -\emph on -it -\emph default - to be a -\family typewriter -PyArrayIterObject* -\family default -. - -\end_layout - -\begin_layout Subsection -PyArrayMultiIter_Type -\end_layout - -\begin_layout Standard -This type provides an iterator that encapsulates the concept of broadcasting. - It allows -\begin_inset Formula $N$ -\end_inset - - arrays to be broadcast together so that the loop progresses in C-style - contiguous fashion over the broadcasted array. - The corresponding C-structure is the -\family typewriter -PyArrayMultiIterObject -\family default - whose memory layout must begin any object, -\emph on -obj -\emph default -, passed in to the -\family typewriter -PyArray_Broadcast -\family default -(obj) function. - Broadcasting is performed by adjusting array iterators so that each iterator - represents the broadcasted shape and size, but has its strides adjusted - so that the correct element from the array is used at each iteration. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - numiter; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - size; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - index; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nd; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - dimensions -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code - -\emph on -PyArrayIterObject * -\emph default -iters -\emph on -[NPY_MAXDIMS] -\emph default -; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArrayMultiIterObject -\emph default -; -\end_layout - -\begin_layout Description -PyObject_HEAD Needed at the start of every Python object (holds reference - count and type identification). -\end_layout - -\begin_layout Description -numiter The number of arrays that need to be broadcast to the same shape. -\end_layout - -\begin_layout Description -size The total broadcasted size. -\end_layout - -\begin_layout Description -index The current (1-d) index into the broadcasted result. -\end_layout - -\begin_layout Description -nd The number of dimensions in the broadcasted result. -\end_layout - -\begin_layout Description -dimensions The shape of the broadcasted result (only -\family typewriter -nd -\family default - slots are used). -\end_layout - -\begin_layout Description -iters An array of iterator objects that holds the iterators for the arrays - to be broadcast together. - On return, the iterators are adjusted for broadcasting. - -\end_layout - -\begin_layout Subsection -PyArrayFlags_Type -\end_layout - -\begin_layout Standard -When the flags attribute is retrieved from Python, a special builtin object - of this type is constructed. - This special type makes it easier to work with the different flags by accessing - them as attributes or by accessing them as if the object were a dictionary - with the flag names as entries. - -\end_layout - -\begin_layout Subsection -ScalarArrayTypes -\end_layout - -\begin_layout Standard -There is a Python type for each of the different built-in data types that - can be present in the array Most of these are simple wrappers around the - corresponding data type in C. - The C-names for these types are -\series bold -Py -\series default -<TYPE> -\series bold -ArrType_Type -\series default - where <TYPE> can be -\end_layout - -\begin_layout Quote - -\series bold -Bool -\series default -, -\series bold -Byte -\series default -, -\series bold -Short -\series default -, -\series bold -Int -\series default -, -\series bold -Long -\series default -, -\series bold -LongLong -\series default -, -\series bold -UByte -\series default -, -\series bold -UShort -\series default -, -\series bold -UInt -\series default -, -\series bold -ULong -\series default -, -\series bold -ULongLong -\series default -, -\series bold -Float -\series default -, -\series bold -Double -\series default -, -\series bold -LongDouble -\series default -, -\series bold -CFloat -\series default -, -\series bold -CDouble -\series default -, -\series bold -CLongDouble -\series default -, -\series bold -String -\series default -, -\series bold -Unicode -\series default -, -\series bold -Void -\series default -, and -\series bold -Object -\series default -. - -\end_layout - -\begin_layout Standard -These type names are part of the C-API and can therefore be created in extension - C-code. - There is also a -\family typewriter -PyIntpArrType_Type -\family default - and a -\family typewriter -PyUIntpArrType_Type -\family default - that are simple substitutes for one of the integer types that can hold - a pointer on the platform. - The structure of these scalar objects is not exposed to C-code. - The function -\family typewriter -PyArray_ScalarAsCtype -\family default -(..) can be used to extract the C-type value from the array scalar and the - function -\family typewriter -PyArray_Scalar -\family default -(...) can be used to construct an array scalar from a C-value. - -\end_layout - -\begin_layout Section -Other C-Structures -\end_layout - -\begin_layout Standard -A few new C-structures were found to be useful in the development of NumPy. - These C-structures are used in at least one C-API call and are therefore - documented here. - The main reason these structures were defined is to make it easy to use - the Python ParseTuple C-API to convert from Python objects to a useful - C-Object. - -\end_layout - -\begin_layout Subsection -PyArray_Dims -\end_layout - -\begin_layout Standard -This structure is very useful when shape and/or strides information is supposed - to be interpreted. - The structure is -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp * -\emph default -ptr; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - len; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArray_Dims -\emph default -; -\end_layout - -\begin_layout Standard -The members of this structure are -\end_layout - -\begin_layout Description -ptr A pointer to a list of ( -\family typewriter -npy_intp -\family default -) integers which usually represent array shape or array strides. - -\end_layout - -\begin_layout Description -len The length of the list of integers. - It is assumed safe to access -\emph on -ptr -\emph default -[0] to -\emph on -ptr -\emph default -[len-1]. - -\end_layout - -\begin_layout Subsection -PyArray_Chunk -\end_layout - -\begin_layout Standard -This is equivalent to the buffer object structure in Python up to the ptr - member. - On 32-bit platforms ( -\emph on -i.e. - -\emph default - if -\family typewriter -NPY_SIZEOF_INT -\family default -== -\family typewriter -NPY_SIZEOF_INTP -\family default -) or in Python 2.5, the len member also matches an equivalent member of the - buffer object. - It is useful to represent a generic single-segment chunk of memory. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD -\end_layout - -\begin_layout LyX-Code - -\emph on -PyObject * -\emph default -base; -\end_layout - -\begin_layout LyX-Code - -\emph on -void * -\emph default -ptr; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp -\emph default - len; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - flags; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArray_Chunk -\emph default -; -\end_layout - -\begin_layout Standard -The members are -\end_layout - -\begin_layout Description -PyObject_HEAD Necessary for all Python objects. - Included here so that the -\family typewriter -PyArray_Chunk -\family default - structure matches that of the buffer object (at least to the len member). - -\end_layout - -\begin_layout Description -base The Python object this chunk of memory comes from. - Needed so that memory can be accounted for properly. -\end_layout - -\begin_layout Description -ptr A pointer to the start of the single-segment chunk of memory. - -\end_layout - -\begin_layout Description -len The length of the segment in bytes. -\end_layout - -\begin_layout Description -flags Any data flags ( -\emph on -e.g. - -\emph default - -\family typewriter -NPY_WRITEABLE -\family default -) that should be used to interpret the memory. - -\end_layout - -\begin_layout Subsection -PyArrayInterface -\end_layout - -\begin_layout Standard -The -\family typewriter -PyArrayInterface -\family default - -\begin_inset LatexCommand index -name "PyArrayInterface" - -\end_inset - - structure is defined so that NumPy and other extension modules can use - the rapid array interface protocol. - The -\series bold -__array_struct__ -\series default - method of an object that supports the rapid array interface protocol should - return a -\family typewriter -PyCObject -\family default - that contains a pointer to a -\family typewriter -PyArrayInterface -\family default - structure with the relevant details of the array. - After the new array is created, the attribute should be -\family typewriter -DECREF -\family default -'d which will free the -\family typewriter -PyArrayInterface -\family default - structure. - Remember to -\family typewriter -INCREF -\family default - the object (whose -\series bold -__array_struct__ -\series default - attribute was retrieved) and point the base member of the new -\family typewriter -PyArrayObject -\family default - to this same object. - In this way the memory for the array will be managed correctly. - -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - two; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - nd; -\end_layout - -\begin_layout LyX-Code - -\emph on -char -\emph default - typekind; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - itemsize; -\end_layout - -\begin_layout LyX-Code - -\emph on -int -\emph default - flags; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp * -\emph default -shape; -\end_layout - -\begin_layout LyX-Code - -\emph on -npy_intp * -\emph default -strides; -\end_layout - -\begin_layout LyX-Code - -\emph on -void * -\emph default -data; -\end_layout - -\begin_layout LyX-Code - PyObject *descr; -\end_layout - -\begin_layout LyX-Code -} -\emph on -PyArrayInterface -\emph default -; -\end_layout - -\begin_layout Description -two the integer 2 as a sanity check. -\end_layout - -\begin_layout Description -nd the number of dimensions in the array. -\end_layout - -\begin_layout Description -typekind A character indicating what kind of array is present according - to the typestring convention with 't' -> bitfield, 'b' -> Boolean, 'i' - -> signed integer, 'u' -> unsigned integer, 'f' -> floating point, 'c' - -> complex floating point, 'O' -> object, 'S' -> string, 'U' -> unicode, - 'V' -> void. -\end_layout - -\begin_layout Description -itemsize the number of bytes each item in the array requires. -\end_layout - -\begin_layout Description -flags any of the bits -\family typewriter -NPY_C_CONTIGUOUS -\family default - (1), -\family typewriter -NPY_F_CONTIGUOUS -\family default - (2), -\family typewriter -NPY_ALIGNED -\family default - (0x100), -\family typewriter -NPY_NOTSWAPPED -\family default - (0x200), or -\family typewriter -NPY_WRITEABLE -\family default - (0x400) to indicate something about the data. - The -\family typewriter -NPY_ALIGNED -\family default -, -\family typewriter -NPY_C_CONTIGUOUS -\family default -, and -\family typewriter -NPY_F_CONTIGUOUS -\family default - flags can actually be determined from the other parameters. - The flag -\family typewriter -NPY_ARR_HAS_DESCR -\family default - (0x800) can also be set to indicate to objects consuming the version 3 - array interface that the descr member of the structure is present (it will - be ignored by objects consuming version 2 of the array interface). - -\end_layout - -\begin_layout Description -shape An array containing the size of the array in each dimension. -\end_layout - -\begin_layout Description -strides An array containing the number of bytes to jump to get to the next - element in each dimension. -\end_layout - -\begin_layout Description -data A pointer -\emph on -to -\emph default - the first element of the array. -\end_layout - -\begin_layout Description -descr A Python object describing the data-type in more detail (currently - an array_description list of tuples). - This can be -\family typewriter -NULL -\family default - if -\emph on -typekind -\emph default - and -\emph on -itemsize -\emph default - provide enough information. - -\end_layout - -\begin_layout Subsection -Internally used structures -\end_layout - -\begin_layout Standard -Internally, the code uses some additional Python objects primarily for memory - management. - These types are not accessible directly from Python, and are not exposed - to the C-API. - They are included here only for completeness and assistance in understanding - the code. - -\end_layout - -\begin_layout Subsubsection -PyUFuncLoopObject -\end_layout - -\begin_layout Standard -A loose wrapper for a C-structure that contains the information needed for - looping. - This is useful if you are trying to understand the ufunc looping code. - The -\family typewriter -PyUFuncLoopObject -\family default - is the associated C-structure. - It is defined in the -\family typewriter -ufuncobject.h -\family default - header. -\end_layout - -\begin_layout Subsubsection -PyUFuncReduceObject -\end_layout - -\begin_layout Standard -A loose wrapper for the C-structure that contains the information needed - for reduce-like methods of ufuncs. - This is useful if you are trying to understand the reduce, accumulate, - and reduce-at code. - The -\family typewriter -PyUFuncReduceObject -\family default - is the associated C-structure. - It is defined in the -\family typewriter -ufuncobject.h -\family default - header. -\end_layout - -\begin_layout Subsubsection -PyUFunc_Loop1d -\end_layout - -\begin_layout Standard -A simple linked-list of C-structures containing the information needed to - define a 1-d loop for a ufunc for every defined signature of a user-defined - data-type. - -\end_layout - -\begin_layout Subsubsection -PyArrayMapIter_Type -\end_layout - -\begin_layout Standard -Advanced indexing is handled with this Python type. - It is simply a loose wrapper around the C-structure containing the variables - needed for advanced array indexing. - The associated C-structure, -\family typewriter -PyArrayMapIterObject -\family default -, is useful if you are trying to understand the advanced-index mapping code. - It is defined in the -\family typewriter -arrayobject.h -\family default - header. - This type is not exposed to Python and could be replaced with a C-structure. - As a Python type it takes advantage of reference-counted memory management. -\end_layout - -\begin_layout Chapter -Complete API -\end_layout - -\begin_layout Quotation -The test of a first-rate intelligence is the ability to hold two opposed - ideas in the mind at the same time, and still retain the ability to function. -\end_layout - -\begin_layout Right Address ---- -\emph on -F. - Scott Fitzgerald -\end_layout - -\begin_layout Quotation -For a successful technology, reality must take precedence over public relations, - for Nature cannot be fooled. - -\end_layout - -\begin_layout Right Address ---- -\emph on -Richard P. - Feynman -\end_layout - -\begin_layout Section -Configuration defines -\end_layout - -\begin_layout Standard -When NumPy is built, a configuration file is constructed and placed as config.h - in the NumPy include directory. - This configuration file ensures that specific macros are defined and defines - other macros based on whether or not your system has certain features. - It is included by the arrayobject.h file. - -\end_layout - -\begin_layout Subsection -Guaranteed to be defined -\end_layout - -\begin_layout Standard -The -\series bold -SIZEOF_ -\series default -<CTYPE> constants are defined so that sizeof information is available to - the pre-processor. - -\end_layout - -\begin_layout Description -CHAR_BIT The number of bits of a char. - The char is the unit of all sizeof definitions -\end_layout - -\begin_layout Description -SIZEOF_SHORT sizeof(short) -\end_layout - -\begin_layout Description -SIZEOF_INT sizeof(int) -\end_layout - -\begin_layout Description -SIZEOF_LONG sizeof(long) -\end_layout - -\begin_layout Description -SIZEOF_LONG_LONG sizeof(longlong) where longlong is defined appropriately - on the platform (A macro defines -\series bold -SIZEOF_LONGLONG -\series default - as well.) -\end_layout - -\begin_layout Description -SIZEOF_PY_LONG_LONG -\end_layout - -\begin_layout Description -SIZEOF_FLOAT sizeof(float) -\end_layout - -\begin_layout Description -SIZEOF_DOUBLE sizeof(double) -\end_layout - -\begin_layout Description -SIZEOF_LONG_DOUBLE sizeof(longdouble) (A macro defines -\series bold -SIZEOF_LONGDOUBLE -\series default - as well.) -\end_layout - -\begin_layout Description -SIZEOF_PY_INTPTR_T Size of a pointer on this platform (sizeof(void *)) (A - macro defines SIZEOF_INTP as well.) -\end_layout - -\begin_layout Subsection -Possible defines -\end_layout - -\begin_layout Standard -These defines will cause the compilation to ignore compatibility code that - is placed in NumPy and use the system code instead. - If they are not defined, then the system does not have that capability. -\end_layout - -\begin_layout Description -HAVE_LONGDOUBLE_FUNCS System has C99 long double math functions. -\end_layout - -\begin_layout Description -HAVE_FLOAT_FUNCS System has C99 float math functions. -\end_layout - -\begin_layout Description -HAVE_INVERSE_HYPERBOLIC System has inverse hyperbolic functions: asinh, - acosh, and atanh. -\end_layout - -\begin_layout Description -HAVE_INVERSE_HYPERBOLIC_FLOAT System has C99 float extensions to inverse - hyperbolic functions: asinhf, acoshf, atanhf -\end_layout - -\begin_layout Description -HAVE_INVERSE_HYPERBOLIC_LONGDOUBLE System has C99 long double extensions - to inverse hyperbolic functions: asinhl, acoshl, atanhl. -\end_layout - -\begin_layout Description -HAVE_ISNAN System has an isnan function. -\end_layout - -\begin_layout Description -HAVE_ISINF System has an isinf function. - -\end_layout - -\begin_layout Description -HAVE_LOG1P System has the log1p function: -\begin_inset Formula $\log\left(x+1\right)$ -\end_inset - -. -\end_layout - -\begin_layout Description -HAVE_EXPM1 System has the expm1 function: -\begin_inset Formula $\exp\left(x\right)-1$ -\end_inset - -. -\end_layout - -\begin_layout Description -HAVE_RINT System has the rint function. - -\end_layout - -\begin_layout Section -Array Data Types -\end_layout - -\begin_layout Standard -The standard array can have 21 different data types (and has some support - for adding your own types). - These data types all have an enumerated type, an enumerated type-character, - and a corresponding array scalar Python type object (placed in a hierarchy). - There are also standard C typedefs to make it easier to manipulate elements - of the given data type. - For the numeric types, there are also bit-width equivalent C typedefs and - named typenumbers that make it easier to select the precision desired. - -\end_layout - -\begin_layout Warning -The names for the types in c code follows c naming conventions more closely. - The Python names for these types follow Python conventions. - Thus, NPY_FLOAT picks up a 32-bit float in C, but -\begin_inset Quotes eld -\end_inset - -float_ -\begin_inset Quotes erd -\end_inset - - in python corresponds to a 64-bit double. - The bit-width names can be used in both Python and C for clarity. -\end_layout - -\begin_layout Subsection -Enumerated Types -\end_layout - -\begin_layout Standard -There is a list of enumerated types defined providing the basic 21 data - types plus some useful generic names. - Whenever the code requires a type number, one of these enumerated types - is requested. - The types are all called -\series bold -NPY_ -\series default -<NAME> where <NAME> can be -\end_layout - -\begin_layout Quote - -\series bold -BOOL -\series default -, -\series bold -BYTE -\series default -, -\series bold -UBYTE -\series default -, -\series bold -SHORT -\series default -, -\series bold -USHORT -\series default -, -\series bold -INT -\series default -, -\series bold -UINT -\series default -, -\series bold -LONG -\series default -, -\series bold -ULONG -\series default -, -\series bold -LONGLONG -\series default -, -\series bold -ULONGLONG -\series default -, -\series bold -FLOAT -\series default -, -\series bold -DOUBLE -\series default -, -\series bold -LONGDOUBLE -\series default -, -\series bold -CFLOAT -\series default -, -\series bold -CDOUBLE -\series default -, -\series bold -CLONGDOUBLE -\series default -, -\series bold -OBJECT -\series default -, -\series bold -STRING -\series default -, -\series bold -UNICODE -\series default -, -\series bold -VOID -\end_layout - -\begin_layout Quote - -\series bold -NTYPES -\series default -, -\series bold -NOTYPE -\series default -, -\series bold -USERDEF -\series default -, -\series bold -DEFAULT_TYPE -\end_layout - -\begin_layout Standard -The various character codes indicating certain types are also part of an - enumerated list. - References to type characters (should they be needed at all) should always - use these enumerations. - The form of them is -\series bold -NPY_ -\series default -<NAME> -\series bold -LTR -\series default - where <NAME> can be -\end_layout - -\begin_layout Quote - -\series bold -BOOL -\series default -, -\series bold -BYTE -\series default -, -\series bold -UBYTE -\series default -, -\series bold -SHORT -\series default -, -\series bold -USHORT -\series default -, -\series bold -INT -\series default -, -\series bold -UINT -\series default -, -\series bold -LONG -\series default -, -\series bold -ULONG -\series default -, -\series bold -LONGLONG -\series default -, -\series bold -ULONGLONG -\series default -, -\series bold -FLOAT -\series default -, -\series bold -DOUBLE -\series default -, -\series bold -LONGDOUBLE -\series default -, -\series bold -CFLOAT -\series default -, -\series bold -CDOUBLE -\series default -, -\series bold -CLONGDOUBLE -\series default -, -\series bold -OBJECT -\series default -, -\series bold -STRING -\series default -, -\series bold -VOID -\series default - -\end_layout - -\begin_layout Quote - -\series bold -INTP -\series default -, -\series bold -UINTP -\end_layout - -\begin_layout Quote - -\series bold -GENBOOL -\series default -, -\series bold -SIGNED -\series default -, -\series bold -UNSIGNED -\series default -, -\series bold -FLOATING -\series default -, -\series bold -COMPLEX -\end_layout - -\begin_layout Standard -The latter group of <NAME>s corresponds to letters used in the array interface - typestring specification. - -\end_layout - -\begin_layout Subsection -Defines -\end_layout - -\begin_layout Subsubsection -Max and min values for integers -\end_layout - -\begin_layout Description -NPY_MAX_INT -\series medium -<bits> -\end_layout - -\begin_layout Description -NPY_MAX_UINT -\series medium -<bits> -\end_layout - -\begin_layout Description -NPY_MIN_INT -\series medium -<bits> -\series default - -\end_layout - -\begin_layout Description -\InsetSpace ~ - These are defined for <bits> = 8, 16, 32, 64, 128, and 256 and provide - the maximum (minimum) value of the corresponding (unsigned) integer type. - Note: the actual integer type may not be available on all platforms (i.e. - 128-bit and 256-bit integers are rare). - -\end_layout - -\begin_layout Description -NPY_MIN_ -\series medium -<type> -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is defined for <type> = -\series bold -BYTE -\series default -, -\series bold -SHORT -\series default -, -\series bold -INT -\series default -, -\series bold -LONG -\series default -, -\series bold -LONGLONG -\series default -, -\series bold -INTP -\end_layout - -\begin_layout Description -NPY_MAX_ -\series medium -<type> -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is defined for all defined for <type> = -\series bold -BYTE -\series default -, -\series bold -UBYTE -\series default -, -\series bold -SHORT -\series default -, -\series bold -USHORT -\series default -, -\series bold -INT -\series default -, -\series bold -UINT -\series default -, -\series bold -LONG -\series default -, -\series bold -ULONG -\series default -, -\series bold -LONGLONG -\series default -, -\series bold -ULONGLONG -\series default -, -\series bold -INTP -\series default -, -\series bold -UINTP -\end_layout - -\begin_layout Subsubsection -Number of bits in data types -\end_layout - -\begin_layout Standard -All -\series bold -NPY_SIZEOF_ -\series default -<CTYPE> constants have corresponding -\series bold -NPY_BITSOF_ -\series default -<CTYPE> constants defined. - The -\series bold -NPY_BITSOF_ -\series default -<CTYPE> constants provide the number of bits in the data type. - Specifically, the available <CTYPE>s are -\end_layout - -\begin_layout Quote - -\series bold -BOOL -\series default -, -\series bold -CHAR -\series default -, -\series bold -SHORT -\series default -, -\series bold -INT -\series default -, -\series bold -LONG -\series default -, -\series bold -LONGLONG -\series default -, -\series bold -FLOAT -\series default -, -\series bold -DOUBLE -\series default -, -\series bold -LONGDOUBLE -\end_layout - -\begin_layout Subsubsection -Bit-width references to enumerated typenums -\end_layout - -\begin_layout Standard -All of the numeric data types (integer, floating point, and complex) have - constants that are defined to be a specific enumerated type number. - Exactly which enumerated type a bit-width type refers to is platform dependent. - In particular, the constants available are -\series bold -PyArray_ -\series default -<NAME><BITS> where <NAME> is -\series bold -INT -\series default -, -\series bold -UINT -\series default -, -\series bold -FLOAT -\series default -, -\series bold -COMPLEX -\series default - and <BITS> can be 8, 16, 32, 64, 80, 96, 128, 160, 192, 256, and 512. - Obviously not all bit-widths are available on all platforms for all the - kinds of numeric types. - Commonly 8-, 16-, 32-, 64-bit integers; 32-, 64-bit floats; and 64-, 128-bit - complex types are available. - -\end_layout - -\begin_layout Subsubsection -Integer that can hold a pointer -\end_layout - -\begin_layout Standard -The constants -\series bold -NPY_INTP -\series default - and -\series bold -NPY_UINTP -\series default - refer to an enumerated integer type that is large enough to hold a pointer - on the platform. - Index arrays should always be converted to -\series bold -NPY_INTP -\series default -, because the dimension of the array is of type npy_intp. - -\end_layout - -\begin_layout Subsection -C-type names -\end_layout - -\begin_layout Standard -There are standard variable types for each of the numeric data types and - the bool data type. - Some of these are already available in the C-specification. - You can create variables in extension code with these types. - -\end_layout - -\begin_layout Subsubsection -Boolean -\end_layout - -\begin_layout Description -npy_bool unsigned char; The constants NPY_FALSE and NPY_TRUE are also defined. - -\end_layout - -\begin_layout Subsubsection -(Un)Signed Integer -\end_layout - -\begin_layout Standard -Unsigned versions of the integers can be defined by pre-pending a 'u' to - the front of the integer name. - -\end_layout - -\begin_layout Description -npy_(u)byte (unsigned) char -\end_layout - -\begin_layout Description -npy_(u)short (unsigned) short -\end_layout - -\begin_layout Description -npy_(u)int (unsigned) int -\end_layout - -\begin_layout Description -npy_(u)long (unsigned) long int -\end_layout - -\begin_layout Description -npy_(u)longlong (unsigned long long int) -\end_layout - -\begin_layout Description -npy_(u)intp (unsigned) Py_intptr_t (an integer that is the size of a pointer - on the platform). - -\end_layout - -\begin_layout Subsubsection -(Complex) Floating point -\end_layout - -\begin_layout Description -npy_(c)float float -\end_layout - -\begin_layout Description -npy_(c)double double -\end_layout - -\begin_layout Description -npy_(c)longdouble long double -\end_layout - -\begin_layout Standard -complex types are structures with -\series bold -.real -\series default - and -\series bold -.imag -\series default - members (in that order). -\end_layout - -\begin_layout Subsubsection -Bit-width names -\end_layout - -\begin_layout Standard -There are also typedefs for signed integers, unsigned integers, floating - point, and complex floating point types of specific bit-widths. - The available type names are -\end_layout - -\begin_layout Quote - -\series bold -npy_int -\series default -<bits>, -\series bold -npy_uint -\series default -<bits>, -\series bold -npy_float -\series default -<bits>, and -\series bold -npy_complex -\series default -<bits> -\end_layout - -\begin_layout Standard -where <bits> is the number of bits in the type and can be -\series bold -8 -\series default -, -\series bold -16 -\series default -, -\series bold -32 -\series default -, -\series bold -64 -\series default -, 128, and 256 for integer types; 16, -\series bold -32 -\series default -, -\series bold -64 -\series default -, 80, 96, 128, and 256 for floating-point types; and 32, -\series bold -64 -\series default -, -\series bold -128 -\series default -, 160, 192, and 512 for complex-valued types. - Which bit-widths are available is platform dependent. - The bolded bit-widths are usually available on all platforms. - -\end_layout - -\begin_layout Subsection -Printf Formatting -\end_layout - -\begin_layout Standard -For help in printing, the following strings are defined as the correct format - specifier in printf and related commands. -\end_layout - -\begin_layout Quote - -\series bold -NPY_LONGLONG_FMT -\series default -, -\series bold -NPY_ULONGLONG_FMT -\series default -, -\series bold -NPY_INTP_FMT -\series default -, -\series bold -NPY_UINTP_FMT -\series default -, -\series bold -NPY_LONGDOUBLE_FMT -\end_layout - -\begin_layout Section -Array API -\begin_inset LatexCommand index -name "ndarray!C-API|(" - -\end_inset - - -\begin_inset LatexCommand index -name "C-API!array|(" - -\end_inset - - -\end_layout - -\begin_layout Subsection -Array structure and data access -\end_layout - -\begin_layout Standard -These macros all access the PyArrayObject structure members. - The input argument, obj, can be any -\family typewriter -PyObject* -\family default - that is directly interpretable as a -\family typewriter -PyArrayObject* -\family default - (any instance of the -\series bold -PyArray_Type -\series default - and its sub-types). - -\end_layout - -\begin_layout Description -PyArray_DATA ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -PyArray_BYTES ( -\family typewriter -char* -\family default -) ( -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - These two macros are similar and obtain the pointer to the data-buffer - for the array. - The first macro can (and should be) assigned to a particular pointer where - the second is for generic processing. - If you have not guaranteed a contiguous and/or aligned array then be sure - you understand how to access the data in the array to avoid memory and/or - alignment problems. - -\end_layout - -\begin_layout Description -PyArray_DIMS ( -\family typewriter -npy_intp* -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -PyArray_STRIDES ( -\family typewriter -npy_intp* -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -PyArray_DIM ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -int -\family default - n) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the shape in the -\emph on -n -\emph default - -\begin_inset Formula $^{\textrm{th}}$ -\end_inset - - dimension. -\end_layout - -\begin_layout Description -PyArray_STRIDE ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -int -\family default - n) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the stride in the -\emph on -n -\emph default - -\begin_inset Formula $^{\textrm{th}}$ -\end_inset - - dimension. -\end_layout - -\begin_layout Description -PyArray_BASE ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -PyArray_DESCR ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -PyArray_FLAGS ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -PyArray_ITEMSIZE ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the itemsize for the elements of this array. -\end_layout - -\begin_layout Description -PyArray_TYPE ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the (builtin) typenumber for the elements of this array. - -\end_layout - -\begin_layout Description -PyArray_GETITEM ( -\family typewriter -PyObject -\family default - *) ( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -void* -\family default - itemptr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Get a Python object from the ndarray, -\emph on -arr -\emph default -, at the location pointed to by itemptr. - Return -\family typewriter -NULL -\family default - on failure. - -\end_layout - -\begin_layout Description -PyArray_SETITEM ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -void* -\family default - itemptr, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert obj and place it in the ndarray, -\emph on -arr -\emph default -, at the place pointed to by itemptr. - Return -1 if an error occurs or 0 on success. - -\end_layout - -\begin_layout Description -PyArray_SIZE ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns the total size (in number of elements) of the array. -\end_layout - -\begin_layout Description -PyArray_Size ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns 0 if -\emph on -obj -\emph default - is not a sub-class of bigndarray. - Otherwise, returns the total number of elements in the array. - Safer version of -\family typewriter -PyArray_SIZE -\family default -( -\emph on -obj -\emph default -). -\end_layout - -\begin_layout Description -PyArray_NBYTES ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns the total number of bytes consumed by the array. - -\end_layout - -\begin_layout Subsubsection -Data access -\end_layout - -\begin_layout Standard -These functions and macros provide easy access to elements of the ndarray - from C. - These work for all arrays. - You may need to take care when accessing the data in the array, however, - if it is not in machine byte-order, misaligned, or not writeable. - In other words, be sure to respect the state of the flags unless you know - what you are doing, or have previously guaranteed an array that is writeable, - aligned, and in machine byte-order using PyArray_FromAny. - If you wish to handle all types of arrays, the copyswap function for each - type is useful for handling misbehaved arrays. - Some platforms (e.g. - Solaris) do not like misaligned data and will crash if you de-reference - a misaligned pointer. - Other platforms (e.g. - x86 Linux) will just work more slowly with misaligned data. - -\end_layout - -\begin_layout Description -PyArray_GetPtr ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - aobj, -\family typewriter -npy_intp* -\family default - ind) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a pointer to the data of the ndarray, -\emph on -aobj -\emph default -, at the N-dimensional index given by the c-array, -\emph on -ind -\emph default -, (which must be at least -\emph on -aobj -\emph default -->nd in size). - You may want to typecast the returned pointer to the data type of the ndarray. -\end_layout - -\begin_layout Description -PyArray_GETPTR1 ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -<npy_intp> -\family default - i) -\end_layout - -\begin_layout Description -PyArray_GETPTR2 ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -<npy_intp> -\family default - i, -\family typewriter -<npy_intp> -\family default - j) -\end_layout - -\begin_layout Description -PyArray_GETPTR3 ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -<npy_intp> -\family default - i, -\family typewriter -<npy_intp> -\family default - j, -\family typewriter -<npy_intp> -\family default - k) -\end_layout - -\begin_layout Description -PyArray_GETPTR4 ( -\family typewriter -void* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -<npy_intp> -\family default - i, -\family typewriter -<npy_intp> -\family default - j, -\family typewriter -<npy_intp> -\family default - k, -\family typewriter -<npy_intp> -\family default - l) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Quick, inline access to the element at the given coordinates in the ndarray, - -\emph on -obj -\emph default -, which must have respectively 1, 2, 3, or 4 dimensions (this is not checked). - The corresponding -\emph on -i -\emph default -, -\emph on -j -\emph default -, -\emph on -k -\emph default -, and -\emph on -l -\emph default - coordinates can be any integer but will be interpreted as -\family typewriter -npy_intp -\family default -. - You may want to typecast the returned pointer to the data type of the ndarray. - -\end_layout - -\begin_layout Subsection -Creating arrays -\end_layout - -\begin_layout Subsubsection -From scratch -\end_layout - -\begin_layout Description -PyArray_NewFromDescr ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyTypeObject* -\family default - subtype, -\family typewriter -PyArray_Descr* -\family default - descr, -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -npy_intp* -\family default - strides, -\family typewriter -void* -\family default - data, -\family typewriter -int -\family default - flags, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is the main array creation function. - Most new arrays are created with this flexible function. - The returned object is an object of Python-type -\emph on -subtype -\emph default -, which must be a subtype of -\family typewriter -PyArray_Type -\family default -. - The array has -\emph on -nd -\emph default - dimensions, described by -\emph on -dims -\emph default -. - The data-type descriptor of the new array is -\emph on -descr -\emph default -. - If -\emph on -subtype -\emph default - is not -\family typewriter -&PyArray_Type -\family default - ( -\emph on -e.g. - -\emph default - a Python subclass of the ndarray), then -\emph on -obj -\emph default - is the object to pass to the -\series bold -__array_finalize__ -\series default - method of the subclass. - If -\emph on -data -\emph default - is -\family typewriter -NULL -\family default -, then new memory will be allocated and -\emph on -flags -\emph default - can be non-zero to indicate a Fortran-style contiguous array. - If -\emph on -data -\emph default - is not -\family typewriter -NULL -\family default -, then it is assumed to point to the memory to be used for the array and - the -\emph on -flags -\emph default - argument is used as the new flags for the array (except the state of -\family typewriter -NPY_OWNDATA -\family default - and -\family typewriter -UPDATEIFCOPY -\family default - flags of the new array will be reset). - In addition, if -\emph on -data -\emph default - is non-NULL, then -\emph on -strides -\emph default - can also be provided. - If -\emph on -strides -\emph default - is -\family typewriter -NULL -\family default -, then the array strides are computed as C-style contiguous (default) or - Fortran-style contiguous ( -\emph on -flags -\emph default - is nonzero for -\emph on -data -\emph default -= -\family typewriter -NULL -\family default - or -\emph on -flags -\emph default - & -\family typewriter -NPY_F_CONTIGUOUS -\family default - is nonzero non-NULL -\emph on -data -\emph default -). - Any provided -\emph on -dims -\emph default - and -\emph on -strides -\emph default - are copied into newly allocated dimension and strides arrays for the new - array object. -\end_layout - -\begin_layout Description -PyArray_New ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyTypeObject* -\family default - subtype, -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - type_num, -\family typewriter -npy_intp* -\family default - strides, -\family typewriter -void* -\family default - data, -\family typewriter -int -\family default - itemsize, -\family typewriter -int -\family default - flags, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is similar to -\family typewriter -PyArray -\family default -\series bold -_ -\family typewriter -\series default -DescrNew -\family default -(...) except you specify the data-type descriptor with -\emph on -type_num -\emph default - and -\emph on -itemsize -\emph default -, where -\emph on -type_num -\emph default - corresponds to a builtin (or user-defined) type. - If the type always has the same number of bytes, then itemsize is ignored. - Otherwise, itemsize specifies the particular size of this array. - -\end_layout - -\begin_layout Warning -If data is passed to -\family typewriter -PyArray_NewFromDescr -\family default - or -\family typewriter -PyArray_New -\family default -, this memory must not be deallocated until the new array is deleted. - If this data came from another Python object, this can be accomplished - using -\family typewriter -Py_INCREF -\family default - on that object and setting the base member of the new array to point to - that object. - If strides are passed in they must be consistent with the dimensions, the - itemsize, and the data of the array. -\end_layout - -\begin_layout Description -PyArray_SimpleNew ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create a new unitialized array of type, -\emph on -typenum -\emph default -, whose size in each of -\emph on -nd -\emph default - dimensions is given by the integer array, -\emph on -dims -\emph default -. - This function cannot be used to create a flexible-type array (no itemsize - given). -\end_layout - -\begin_layout Description -PyArray_SimpleNewFromData ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - typenum, -\family typewriter -void* -\family default - data) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create an array wrapper around -\emph on -data -\emph default - pointed to by the given pointer. - The array flags will have a default that the data area is well-behaved - and C-style contiguous. - The shape of the array is given by the -\emph on -dims -\emph default - c-array of length -\emph on -nd -\emph default -. - The data-type of the array is indicated by -\emph on -typenum -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_SimpleNewFromDescr ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -PyArray_Descr* -\family default - descr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create a new array with the provided data-type descriptor, -\emph on -descr -\emph default -, of the shape deteremined by -\emph on -nd -\emph default - and -\emph on -dims -\emph default -. -\end_layout - -\begin_layout Description -PyArray_FILLWBYTE ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - val) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Fill the array pointed to by -\emph on -obj -\emph default ----which must be a (subclass of) bigndarray---with the contents of -\emph on -val -\emph default - (evaluated as a byte). -\end_layout - -\begin_layout Description -PyArray_Zeros ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a new -\emph on -nd -\emph default --dimensional array with shape given by -\emph on -dims -\emph default - and data type given by -\emph on -dtype -\emph default -. - If -\emph on -fortran -\emph default - is non-zero, then a Fortran-order array is created, otherwise a C-order - array is created. - Fill the memory with zeros (or the 0 object if -\emph on -dtype -\emph default - corresponds to -\family typewriter -NPY_OBJECT -\family default -). - -\end_layout - -\begin_layout Description -PyArray_ZEROS ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - type_num, -\family typewriter -int -\family default - fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Macro form of -\family typewriter -PyArray_Zeros -\family default - which takes a type-number instead of a data-type object. -\end_layout - -\begin_layout Description -PyArray_Empty ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a new -\emph on -nd -\emph default --dimensional array with shape given by -\emph on -dims -\emph default - and data type given by -\emph on -dtype -\emph default -. - If -\emph on -fortran -\emph default - is non-zero, then a Fortran-order array is created, otherwise a C-order - array is created. - The array is uninitialized unless the data type corresponds to -\family typewriter -NPY_OBJECT -\family default - in which case the array is filled with -\family typewriter -Py_None -\family default -. - -\end_layout - -\begin_layout Description -PyArray_EMPTY ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Macro form of -\family typewriter -PyArray_Empty -\family default - which takes a type-number, -\emph on -typenum -\emph default -, instead of a data-type object. -\end_layout - -\begin_layout Description -PyArray_Arange ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -double -\family default - start, -\family typewriter -double -\family default - stop, -\family typewriter -double -\family default - step, -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a new 1-dimensional array of data-type, -\emph on -typenum -\emph default -, that ranges from -\emph on -start -\emph default - to -\emph on -stop -\emph default - (exclusive) in increments of -\emph on -step -\emph default -. - Equivalent to -\series bold -arange -\series default -( -\emph on -start -\emph default -, -\emph on -stop -\emph default -, -\emph on -step -\emph default -, dtype). -\end_layout - -\begin_layout Description -PyArray_ArangeObj ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - start, -\family typewriter -PyObject* -\family default - stop, -\family typewriter -PyObject* -\family default - step, -\family typewriter -PyArray_Descr* -\family default - descr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a new 1-dimensional array of data-type determined by -\family typewriter -descr -\family default -, that ranges from -\family typewriter -start -\family default - to -\family typewriter -stop -\family default - (exclusive) in increments of -\family typewriter -step -\family default -. - Equivalent to arange( -\family typewriter -start -\family default -, -\family typewriter -stop -\family default -, -\family typewriter -step -\family default -, -\family typewriter -typenum -\family default -). - -\end_layout - -\begin_layout Subsubsection -From other objects -\end_layout - -\begin_layout Description -PyArray_FromAny ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - min_depth, -\family typewriter -int -\family default - max_depth, -\family typewriter -int -\family default - requirements, -\family typewriter -PyObject* -\family default - context) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is the main function used to obtain an array from any nested sequence, - or object that exposes the array interface, -\family typewriter -op -\family default -. - The parameters allow specification of the required -\emph on -type -\emph default -, the minimum ( -\emph on -min_depth -\emph default -) and maximum ( -\emph on -max_depth -\emph default -) number of dimensions acceptable, and other -\emph on -requirements -\emph default - for the array. - The -\emph on -dtype -\emph default - argument needs to be a -\family typewriter -PyArray_Descr -\family default - structure indicating the desired data-type (including required byteorder). - The -\emph on -dtype -\emph default - argument may be NULL, indicating that any data-type (and byteorder) is - acceptable. - If you want to use -\family typewriter -NULL -\family default - for the -\emph on -dtype -\emph default - and ensure the array is notswapped then use -\family typewriter -PyArray_CheckFromAny -\family default -. - A value of 0 for either of the depth parameters causes the parameter to - be ignored. - Any of the following array flags can be added ( -\emph on -e.g. - -\emph default - using |) to get the -\emph on -requirements -\emph default - argument. - If your code can handle general ( -\emph on -e.g. - -\emph default - strided, byte-swapped, or unaligned arrays) then -\emph on -requirements -\emph default - may be 0. - Also, if -\emph on -op -\emph default - is not already an array (or does not expose the array interface), then - a new array will be created (and filled from -\emph on -op -\emph default - using the sequence protocol). - The new array will have -\family typewriter -NPY_DEFAULT -\family default - as its flags member. - The -\emph on -context -\emph default - argument is passed to the -\series bold -__array__ -\series default - method of -\emph on -op -\emph default - and is only used if the array is constructed that way. - -\end_layout - -\begin_deeper -\begin_layout Description -NPY_C_CONTIGUOUS Make sure the returned array is C-style contiguous -\end_layout - -\begin_layout Description -NPY_F_CONTIGUOUS Make sure the returned array is Fortran-style contiguous. - -\end_layout - -\begin_layout Description -NPY_ALIGNED Make sure the returned array is aligned on proper boundaries - for its data type. - An aligned array has the data pointer and every strides factor as a multiple - of the alignment factor for the data-type-descriptor. -\end_layout - -\begin_layout Description -NPY_WRITEABLE Make sure the returned array can be written to. - -\end_layout - -\begin_layout Description -NPY_ENSURECOPY Make sure a copy is made of -\emph on -op -\emph default -. - If this flag is not present, data is not copied if it can be avoided. - -\end_layout - -\begin_layout Description -NPY_ENSUREARRAY Make sure the result is a base-class ndarray or bigndarray. - By default, if -\emph on -op -\emph default - is an instance of a subclass of the bigndarray, an instance of that same - subclass is returned. - If this flag is set, an ndarray object will be returned instead. -\end_layout - -\begin_layout Description -NPY_FORCECAST Force a cast to the output type even if it cannot be done - safely. - Without this flag, a data cast will occur only if it can be done safely, - otherwise an error is reaised. - -\end_layout - -\begin_layout Description -NPY_UPDATEIFCOPY If -\emph on -op -\emph default - is already an array, but does not satisfy the requirements, then a copy - is made (which will satisfy the requirements). - If this flag is present and a copy (of an object that is already an array) - must be made, then the corresponding -\family typewriter -NPY_UPDATEIFCOPY -\family default - flag is set in the returned copy and -\emph on -op -\emph default - is made to be read-only. - When the returned copy is deleted (presumably after your calculations are - complete), its contents will be copied back into -\emph on -op -\emph default - and the -\emph on -op -\emph default - array will be made writeable again. - If -\emph on -op -\emph default - is not writeable to begin with, then an error is raised. - If -\emph on -op -\emph default - is not already an array, then this flag has no effect. -\end_layout - -\begin_layout Description -NPY_BEHAVED -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -NPY_WRITEABLE -\end_layout - -\begin_layout Description -NPY_CARRAY -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_BEHAVED -\end_layout - -\begin_layout Description -NPY_CARRAY_RO -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_FARRAY -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_BEHAVED -\end_layout - -\begin_layout Description -NPY_FARRAY_RO -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_DEFAULT -\family typewriter -NPY_CARRAY -\end_layout - -\begin_layout Description -NPY_IN_ARRAY -\family typewriter -NPY_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_IN_FARRAY -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_INOUT_ARRAY -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_INOUT_FARRAY -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_OUT_ARRAY -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -NPY_UPDATEIFCOPY -\end_layout - -\begin_layout Description -NPY_OUT_FARRAY -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -UPDATEIFCOPY -\end_layout - -\end_deeper -\begin_layout Description -PyArray_CheckFromAny ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - min_depth, -\family typewriter -int -\family default - max_depth, -\family typewriter -int -\family default - requirements, -\family typewriter -PyObject* -\family default - context) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Nearly identical to -\family typewriter -PyArray_FromAny -\family default -(...) except -\emph on -requirements -\emph default - can contain -\family typewriter -NPY_NOTSWAPPED -\family default - (over-riding the specification in -\emph on -dtype -\emph default -) and -\family typewriter -NPY_ELEMENTSTRIDES -\family default - which indicates that the array should be aligned in the sense that the - strides are multiples of the element size. - -\end_layout - -\begin_layout Description -NPY_NOTSWAPPED Make sure the returned array has a data-type descriptor that - is in machine byte-order, over-riding any specification in the -\emph on -dtype -\emph default - argument. - Normally, the byte-order requirement is determined by the -\emph on -dtype -\emph default - argument. - If this flag is set and the dtype argument does not indicate a machine - byte-order descriptor (or is NULL and the object is already an array with - a data-type descriptor that is not in machine byte-order), then a new data-type - descriptor is created and used with its byte-order field set to native. -\end_layout - -\begin_layout Description -NPY_BEHAVED_NS -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_NOTSWAPPED -\end_layout - -\begin_layout Description -NPY_ELEMENTSTRIDES Make sure the returned array has strides that are multiples - of the element size. - -\end_layout - -\begin_layout Description -PyArray_FromArray ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - newtype, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Special case of -\family typewriter -PyArray_FromAny -\family default - for when -\emph on -op -\emph default - is already an array but it needs to be of a specific -\emph on -newtype -\emph default - (including byte-order) or has certain -\emph on -requirements -\emph default -. -\end_layout - -\begin_layout Description -PyArray_FromStructInterface ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns an ndarray object from a Python object that exposes the -\series bold -__array_struct__ -\series default - method and follows the array interface protocol. - If the object does not contain this method then a borrowed reference to - -\family typewriter -Py_NotImplemented -\family default - is returned. -\end_layout - -\begin_layout Description -PyArray_FromInterface ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns an ndarray object from a Python object that exposes the -\series bold -__array_shape__ -\series default - and -\series bold -__array_typestr__ -\series default - methods following the array interface protocol. - If the object does not contain one of these method then a borrowed reference - to -\family typewriter -Py_NotImplemented -\family default - is returned. -\end_layout - -\begin_layout Description -PyArray_FromArrayAttr ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -PyObject* -\family default - context) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an ndarray object from a Python object that exposes the -\series bold -__array__ -\series default - method. - The -\series bold -__array__ -\series default - method can take 0, 1, or 2 arguments ([dtype, context]) where -\emph on -context -\emph default - is used to pass information about where the -\series bold -__array__ -\series default - method is being called from (currently only used in ufuncs). - -\end_layout - -\begin_layout Description -PyArray_ContiguousFromAny ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - min_depth, -\family typewriter -int -\family default - max_depth) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function returns a (C-style) contiguous and behaved function array - from any nested sequence or array interface exporting object, -\emph on -op -\emph default -, of (non-flexible) type given by the enumerated -\emph on -typenum -\emph default -, of minimum depth -\emph on -min_depth -\emph default -, and of maximum depth -\emph on -max_depth -\emph default -. - Equivalent to a call to -\family typewriter -PyArray_FromAny -\family default - with requirements set to -\family typewriter -NPY_DEFAULT -\family default - and the type_num member of the type argument set to -\emph on -typenum -\emph default -. -\end_layout - -\begin_layout Description -PyArray_FromObject (PyObject *) (PyObject * op, int typenum, int min_depth, - int max_depth) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an aligned and in native-byteorder array from any nested sequence - or array-interface exporting object, op, of a type given by the enumerated - typenum. - The minimum number of dimensions the array can have is given by min_depth - while the maximum is max_depth. - This is equivalent to a call to PyArray_FromAny with requirements set to - BEHAVED. - -\end_layout - -\begin_layout Description -PyArray_EnsureArray ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function -\series bold -steals a reference -\series default - to -\family typewriter -op -\family default - and makes sure that -\family typewriter -op -\family default - is a base-class ndarray. - It special cases array scalars, but otherwise calls -\series bold -PyArray_FromAny -\series default -( -\family typewriter -op -\family default -, NULL, 0, 0, NPY_ENSUREARRAY). -\end_layout - -\begin_layout Description -PyArray_FromString ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -char* -\family default - string, -\family typewriter -npy_intp -\family default - slen, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -npy_intp -\family default - num, -\family typewriter -char* -\family default - sep) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a one-dimensional ndarray of a single type from a binary or (ASCII) - text -\family typewriter -string -\family default - of length -\family typewriter -slen -\family default -. - The data-type of the array to-be-created is given by -\family typewriter -dtype -\family default -. - If num is -1, then -\series bold -copy -\series default - the entire string and return an appropriately sized array, otherwise, -\family typewriter -num -\family default - is the number of items to -\series bold -copy -\series default - from the string. - If -\family typewriter -sep -\family default - is NULL (or -\begin_inset Quotes eld -\end_inset - - -\begin_inset Quotes erd -\end_inset - -), then interpret the string as bytes of binary data, otherwise convert - the sub-strings separated by -\family typewriter -sep -\family default - to items of data-type -\family typewriter -dtype -\family default -. - Some data-types may not be readable in text mode and an error will be raised - if that occurs. - All errors return NULL. - -\end_layout - -\begin_layout Description -PyArray_FromFile ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -FILE* -\family default - fp, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -npy_intp -\family default - num, -\family typewriter -char* -\family default - sep) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a one-dimensional ndarray of a single type from a binary or text - file. - The open file pointer is -\family typewriter -fp -\family default -, the data-type of the array to be created is given by -\family typewriter -dtype -\family default -. - This must match the data in the file. - If -\family typewriter -num -\family default - is -1, then read until the end of the file and return an appropriately - sized array, otherwise, -\family typewriter -num -\family default - is the number of items to read. - If -\family typewriter -sep -\family default - is NULL (or -\begin_inset Quotes eld -\end_inset - - -\begin_inset Quotes erd -\end_inset - -), then read from the file in binary mode, otherwise read from the file - in text mode with -\family typewriter -sep -\family default - providing the item separator. - Some array types cannot be read in text mode in which case an error is - raised. -\end_layout - -\begin_layout Description -PyArray_FromBuffer ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - buf, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -npy_intp -\family default - count, -\family typewriter -npy_intp -\family default - offset) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Construct a one-dimensional ndarray of a single type from an object, -\family typewriter -buf -\family default -, that exports the (single-segment) buffer protocol (or has an attribute - __buffer__ that returns an object that exports the buffer protocol). - A writeable buffer will be tried first followed by a read-only buffer. - The NPY_WRITEABLE flag of the returned array will reflect which one was - successful. - The data is assumed to start at -\family typewriter -offset -\family default - bytes from the start of the memory location for the object. - The type of the data in the buffer will be interpreted depending on the - data-type descriptor, -\family typewriter -dtype. - -\family default - If -\family typewriter -count -\family default - is negative then it will be determined from the size of the buffer and - the requested itemsize, otherwise, -\family typewriter -count -\family default - represents how many elements should be converted from the buffer. - -\end_layout - -\begin_layout Description -PyArray_CopyInto ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - dest, -\family typewriter -PyArrayObject* -\family default - src) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Copy from the source array, -\family typewriter -src -\family default -, into the destination array, -\family typewriter -dest -\family default -, performing a data-type conversion if necessary. - If an error occurs return -1 (otherwise 0). - The shape of -\family typewriter -src -\family default - must be broadcastable to the shape of -\family typewriter -dest -\family default -. - The data areas of dest and src must not overlap. - -\end_layout - -\begin_layout Description -PyArray_MoveInto ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - dest, -\family typewriter -PyArrayObject* -\family default - src) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Move data from the source array, -\family typewriter -src -\family default -, into the destination array, -\family typewriter -dest -\family default -, performing a data-type conversion if necessary. - If an error occurs return -1 (otherwise 0). - The shape of -\family typewriter -src -\family default - must be broadcastable to the shape of -\family typewriter -dest -\family default -. - The data areas of dest and src may overlap. - -\end_layout - -\begin_layout Description -PyArray_GETCONTIGUOUS ( -\family typewriter -PyArrayObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - If -\family typewriter -op -\family default - is already (C-style) contiguous and well-behaved then just return a reference, - otherwise return a (contiguous and well-behaved) copy of the array. - The parameter op must be a (sub-class of an) ndarray and no checking for - that is done. -\end_layout - -\begin_layout Description -PyArray_FROM_O ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert -\family typewriter -obj -\family default - to an ndarray. - The argument can be any nested sequence or object that exports the array - interface. - This is a macro form of -\family typewriter -PyArray_FromAny -\family default - using -\family typewriter -NULL -\family default -, 0, 0, 0 for the other arguments. - Your code must be able to handle any data-type descriptor and any combination - of data-flags to use this macro. - -\end_layout - -\begin_layout Description -PyArray_FROM_OF ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Similar to -\family typewriter -PyArray_FROM_O -\family default - except it can take an argument of -\emph on -requirements -\emph default - indicating properties the resulting array must have. - Available requirements that can be enforced are -\family typewriter -NPY_CONTIGUOUS -\family default -, -\family typewriter -NPY_F_CONTIGUOUS -\family default -, -\family typewriter -NPY_ALIGNED -\family default -, -\family typewriter -NPY_WRITEABLE -\family default -, -\family typewriter -NPY_NOTSWAPPED -\family default -, -\family typewriter -NPY_ENSURECOPY -\family default -, -\family typewriter -NPY_UPDATEIFCOPY -\family default -, -\family typewriter -NPY_FORCECAST -\family default -, and -\family typewriter -NPY_ENSUREARRAY -\family default -. - Standard combinations of flags can also be used: -\end_layout - -\begin_layout Description -PyArray_FROM_OT ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Similar to -\family typewriter -PyArray_FROM_O -\family default - except it can take an argument of -\emph on -typenum -\emph default - specifying the type-number the returned array. -\end_layout - -\begin_layout Description -PyArray_FROM_OTF ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Combination of -\family typewriter -PyArray_FROM_OF -\family default - and -\family typewriter -PyArray_FROM_OT -\family default - allowing both a -\emph on -typenum -\emph default - and a -\emph on -flags -\emph default - argument to be provided.. -\end_layout - -\begin_layout Description -PyArray_FROMANY ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - min, -\family typewriter -int -\family default - max, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Similar to -\family typewriter -PyArray_FromAny -\family default - except the data-type is specified using a typenumber. - -\family typewriter -PyArray_DescrFromType -\family default -( -\emph on -typenum -\emph default -) is passed directly to -\family typewriter -PyArray_FromAny -\family default -. - This macro also adds -\family typewriter -NPY_DEFAULT -\family default - to requirements if -\family typewriter -NPY_ENSURECOPY -\family default - is passed in as requirements. - -\end_layout - -\begin_layout Description -PyArray_CheckAxis ( -\family typewriter -PyObject* -\family default -)( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int* -\family default - axis, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Encapsulate the functionality of functions and methods that take the axis= - keyword and work properly with None as the axis argument. - The input array is -\family typewriter -obj -\family default -, while -\family typewriter -*axis -\family default - is a converted integer (so that >=MAXDIMS is the None value), and -\family typewriter -requirements -\family default - gives the needed properties of -\family typewriter -obj -\family default -. - The output is a converted version of the input so that requirements are - met and if needed a flattening has occurred. - On output negative values of -\family typewriter -*axis -\family default - are converted and the new value is checked to ensure consistency with the - shape of -\family typewriter -obj -\family default -. -\end_layout - -\begin_layout Subsection -Dealing with types -\end_layout - -\begin_layout Subsubsection -General check of Python Type -\end_layout - -\begin_layout Description -PyArray_Check (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is a Python object whose type is a sub-type of -\family typewriter -PyArray_Type -\family default -. - -\end_layout - -\begin_layout Description -PyArray_CheckExact (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is a Python object with type -\family typewriter -PyArray_Type -\family default -. -\end_layout - -\begin_layout Description -PyArray_HasArrayInterface (op, out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - If -\family typewriter -op -\family default - implements any part of the array interface, then -\family typewriter -out -\family default - will contain a new reference to the newly created ndarray using the interface - or -\family typewriter -out -\family default - will contain -\family typewriter -NULL -\family default - if an error during conversion occurs. - Otherwise, out will contain a borrowed reference to -\family typewriter -Py_NotImplemented -\family default - and no error condition is set. - -\end_layout - -\begin_layout Description -PyArray_HasArrayInterfaceType (op, type, context, out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - If -\family typewriter -op -\family default - implements any part of the array interface, then -\family typewriter -out -\family default - will contain a new reference to the newly created ndarray using the interface - or -\family typewriter -out -\family default - will contain -\family typewriter -NULL -\family default - if an error during conversion occurs. - Otherwise, out will contain a borrowed reference to Py_NotImplemented and - no error condition is set. - This version allows setting of the type and context in the part of the - array interface that looks for the -\series bold -__array__ -\series default - attribute. - -\end_layout - -\begin_layout Description -PyArray_IsZeroDim (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is an instance of (a subclass of) -\family typewriter -PyArray_Type -\family default - and has 0 dimensions. -\end_layout - -\begin_layout Description -PyArray_IsScalar (op, cls) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is an instance of -\family typewriter -Py<cls>ArrType_Type -\family default -. -\end_layout - -\begin_layout Description -PyArray_CheckScalar (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is either an array scalar (an instance of a sub-type of -\family typewriter -PyGenericArr_Type -\family default -), or an instance of (a sub-class of) -\family typewriter -PyArray_Type -\family default - whose dimensionality is 0. -\end_layout - -\begin_layout Description -PyArray_IsPythonScalar (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is a builtin Python -\begin_inset Quotes eld -\end_inset - -scalar -\begin_inset Quotes erd -\end_inset - - object (int, float, complex, str, unicode, long, bool). -\end_layout - -\begin_layout Description -PyArray_IsAnyScalar (op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is either a Python scalar or an array scalar (an instance of a sub-type - of -\family typewriter -PyGenericArr_Type -\family default -). - -\end_layout - -\begin_layout Subsubsection -Data-type checking -\end_layout - -\begin_layout Standard -For the typenum macros, the argument is an integer representing an enumerated - array data type. - For the array type checking macros the argument must be a -\family typewriter -PyObject* -\family default - that can be directly interpreted as a -\family typewriter -PyArrayObject* -\family default -. - -\end_layout - -\begin_layout Description -PyTypeNum_ISUNSIGNED (num) -\end_layout - -\begin_layout Description -PyDataType_ISUNSIGNED (descr) -\end_layout - -\begin_layout Description -PyArray_ISUNSIGNED (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents an unsigned integer. -\end_layout - -\begin_layout Description -PyTypeNum_ISSIGNED (num) -\end_layout - -\begin_layout Description -PyDataType_ISSIGNED (descr) -\end_layout - -\begin_layout Description -PyArray_ISSIGNED (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents a signed integer. -\end_layout - -\begin_layout Description -PyTypeNum_ISINTEGER (num) -\end_layout - -\begin_layout Description -PyDataType_ISINTEGER (descr) -\end_layout - -\begin_layout Description -PyArray_ISINTEGER (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents any integer. -\end_layout - -\begin_layout Description -PyTypeNum_ISFLOAT (num) -\end_layout - -\begin_layout Description -PyDataType_ISFLOAT (descr) -\end_layout - -\begin_layout Description -PyArray_ISFLOAT (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents any floating point number. -\end_layout - -\begin_layout Description -PyTypeNum_ISCOMPLEX (num) -\end_layout - -\begin_layout Description -PyDataType_ISCOMPLEX (descr) -\end_layout - -\begin_layout Description -PyArray_ISCOMPLEX (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents any complex floating point number. -\end_layout - -\begin_layout Description -PyTypeNum_ISNUMBER (num) -\end_layout - -\begin_layout Description -PyDataType_ISNUMBER (descr) -\end_layout - -\begin_layout Description -PyArray_ISNUMBER (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents any integer, floating point, or complex floating point - number. -\end_layout - -\begin_layout Description -PyTypeNum_ISSTRING (num) -\end_layout - -\begin_layout Description -PyDataType_ISSTRING (descr) -\end_layout - -\begin_layout Description -PyArray_ISSTRING (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents a string data type. -\end_layout - -\begin_layout Description -PyTypeNum_ISPYTHON (num) -\end_layout - -\begin_layout Description -PyDataType_ISPYTHON (descr) -\end_layout - -\begin_layout Description -PyArray_ISPYTHON (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents an enumerated type corresponding to one of the standard - Python scalar (bool, int, float, or complex). - -\end_layout - -\begin_layout Description -PyTypeNum_ISFLEXIBLE (num) -\end_layout - -\begin_layout Description -PyDataType_ISFLEXIBLE (descr) -\end_layout - -\begin_layout Description -PyArray_ISFLEXIBLE (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents one of the flexible array types ( -\family typewriter -NPY_STRING -\family default -, -\family typewriter -NPY_UNICODE -\family default -, or -\family typewriter -NPY_VOID -\family default -). -\end_layout - -\begin_layout Description -PyTypeNum_ISUSERDEF (num) -\end_layout - -\begin_layout Description -PyDataType_ISUSERDEF (descr) -\end_layout - -\begin_layout Description -PyArray_ISUSERDEF (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents a user-defined type. -\end_layout - -\begin_layout Description -PyTypeNum_ISEXTENDED (num) -\end_layout - -\begin_layout Description -PyDataType_ISEXTENDED (descr) -\end_layout - -\begin_layout Description -PyArray_ISEXTENDED (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type is either flexible or user-defined. -\end_layout - -\begin_layout Description -PyTypeNum_ISOBJECT (num) -\end_layout - -\begin_layout Description -PyDataType_ISOBJECT (descr) -\end_layout - -\begin_layout Description -PyArray_ISOBJECT (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents object data type. -\end_layout - -\begin_layout Description -PyTypeNum_ISBOOL (num) -\end_layout - -\begin_layout Description -PyDataType_ISBOOL (descr) -\end_layout - -\begin_layout Description -PyArray_ISBOOL (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type represents Boolean data type. -\end_layout - -\begin_layout Description -PyDataType_HASFIELDS (descr) -\end_layout - -\begin_layout Description -PyArray_HASFIELDS (obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type has fields associated with it. -\end_layout - -\begin_layout Description -PyArray_ISNOTSWAPPED (m) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of the ndarray -\emph on -m -\emph default - is in machine byte-order according to the array's data-type descriptor. -\end_layout - -\begin_layout Description -PyArray_ISBYTESWAPPED (m) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of the ndarray -\emph on -m -\emph default - is -\series bold -not -\series default - in machine byte-order according to the array's data-type descriptor. - -\end_layout - -\begin_layout Description -PyArray_EquivTypes ( -\family typewriter -Bool -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - type1, -\family typewriter -PyArray_Descr* -\family default - type2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return -\family typewriter -NPY_TRUE -\family default - if -\emph on -type1 -\emph default - and -\emph on -type2 -\emph default - actually represent equivalent types for this platform (the fortran member - of each type is ignored). - For example, on 32-bit platforms, -\family typewriter -NPY_LONG -\family default - and -\family typewriter -NPY_INT -\family default - are equivalent. - Otherwise return -\family typewriter -NPY_FALSE -\family default -. -\end_layout - -\begin_layout Description -PyArray_EquivArrTypes ( -\family typewriter -Bool -\family default -) ( -\family typewriter -PyArrayObject* -\family default - a1, -\family typewriter -PyArrayObject -\family default -* a2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return -\family typewriter -NPY_TRUE -\family default - if -\emph on -a1 -\emph default - and -\emph on -a2 -\emph default - are arrays with equivalent types for this platform. - -\end_layout - -\begin_layout Description -PyArray_EquivTypenums ( -\family typewriter -Bool -\family default -) ( -\family typewriter -int -\family default - typenum1, -\family typewriter -int -\family default - typenum2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Special case of -\family typewriter -PyArray_EquivTypes -\family default -(...) that does not accept flexible data types but may be easier to call. - -\end_layout - -\begin_layout Description -PyArray_EquivByteorders (int) (<byteorder> b1, <byteorder> b2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - True if byteorder characters ( -\family typewriter -NPY_LITTLE -\family default -, -\family typewriter -NPY_BIG -\family default -, -\family typewriter -NPY_NATIVE -\family default -, -\family typewriter -NPY_IGNORE -\family default -) are either equal or equivalent as to their specification of a native byte - order. - Thus, on a little-endian machine -\family typewriter -NPY_LITTLE -\family default - and -\family typewriter -NPY_NATIVE -\family default - are equivalent where they are not equivalent on a big-endian machine. - -\end_layout - -\begin_layout Subsubsection -Converting data types -\end_layout - -\begin_layout Description -PyArray_Cast ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr, -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Mainly for backwards compatibility to the Numeric C-API and for simple - casts to non-flexible types. - Return a new array object with the elements of -\emph on -arr -\emph default - cast to the data-type -\emph on -typenum -\emph default - which must be one of the enumerated types and not a flexible type. -\end_layout - -\begin_layout Description -PyArray_CastToType ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr, -\family typewriter -PyArray_Descr* -\family default - type, -\family typewriter -int -\family default - fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a new array of the -\emph on -type -\emph default - specified, casting the elements of -\emph on -arr -\emph default - as appropriate. - The fortran argument specifies the ordering of the output array. - -\end_layout - -\begin_layout Description -PyArray_CastTo ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - out, -\family typewriter -PyArrayObject* -\family default - in) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Cast the elements of the array -\emph on -in -\emph default - into the array -\emph on -out -\emph default -. - The output array should be writeable, have an integer-multiple of the number - of elements in the input array (more than one copy can be placed in out), - and have a data type that is one of the builtin types. - Returns 0 on success and -1 if an error occurs. -\end_layout - -\begin_layout Description -PyArray_GetCastFunc ( -\family typewriter -PyArray_VectorUnaryFunc* -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - from, -\family typewriter -int -\family default - totype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the low-level casting function to cast from the given descriptor - to the builtin type number. - If no casting function exists return -\family typewriter -NULL -\family default - and set an error. - Using this function instead of direct access to -\emph on -from -\emph default -->f->cast will allow support of any user-defined casting functions added - to a descriptors casting dictionary. - -\end_layout - -\begin_layout Description -PyArray_CanCastSafely ( -\family typewriter -int -\family default -) ( -\family typewriter -int -\family default - fromtype, -\family typewriter -int -\family default - totype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns non-zero if an array of data type -\emph on -fromtype -\emph default - can be cast to an array of data type -\emph on -totype -\emph default - without losing information. - An exception is that 64-bit integers are allowed to be cast to 64-bit floating - point values even though this can lose precision on large integers so as - not to proliferate the use of long doubles without explict requests. - Flexible array types are not checked according to their lengths with this - function. - -\end_layout - -\begin_layout Description -PyArray_CanCastTo ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - fromtype, -\family typewriter -PyArray_Descr* -\family default - totype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns non-zero if an array of data type -\emph on -fromtype -\emph default - (which can include flexible types) can be cast safely to an array of data - type -\emph on -totype -\emph default - (which can include flexible types). - This is basically a wrapper around -\family typewriter -PyArray_CanCastSafely -\family default - with additional support for size checking if -\emph on -fromtype -\emph default - and -\emph on -totype -\emph default - are -\family typewriter -NPY_STRING -\family default - or -\family typewriter -NPY_UNICODE -\family default -. -\end_layout - -\begin_layout Description -PyArray_ObjectType ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -int -\family default - mintype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function is useful for determining a common type that two or more - arrays can be converted to. - It only works for non-flexible array types as no itemsize information is - passed. - The -\emph on -mintype -\emph default - argument represents the minimum type acceptable, and -\emph on -op -\emph default - represents the object that will be converted to an array. - The return value is the enumerated typenumber that represents the data-type - that -\emph on -op -\emph default - should have. -\end_layout - -\begin_layout Description -PyArray_ArrayType ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - mintype, -\family typewriter -PyArray_Descr* -\family default - outtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function works similarly to -\family typewriter -PyArray_ObjectType -\family default -(...) except it handles flexible arrays. - The -\emph on -mintype -\emph default - argument can have an itemsize member and the -\emph on -outtype -\emph default - argument will have an itemsize member at least as big but perhaps bigger - depending on the object -\emph on -op -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_ConvertToCommonType ( -\family typewriter -PyArrayObject** -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -int* -\family default - n) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert a sequence of Python objects contained in -\emph on -op -\emph default - to an array of ndarrays each having the same data type. - The type is selected based on the typenumber (larger type number is chosen - over a smaller one) ignoring objects that are only scalars. - The length of the sequence is returned in -\emph on -n -\emph default -, and an -\emph on -n -\emph default --length array of -\family typewriter -PyArrayObject -\family default - pointers is the return value (or -\family typewriter -NULL -\family default - if an error occurs). - The returned array must be freed by the caller of this routine (using -\family typewriter -PyDataMem_FREE -\family default -) and all the array objects in it -\family typewriter -DECREF -\family default -'d or a memory-leak will occur. - The example template-code below shows a typically usage. -\end_layout - -\begin_layout LyX-Code -mps = PyArray_ConvertToCommonType(obj, &n); -\end_layout - -\begin_layout LyX-Code -if (mps==NULL) return NULL; -\end_layout - -\begin_layout LyX-Code -<code> -\end_layout - -\begin_layout LyX-Code -<before return> -\end_layout - -\begin_layout LyX-Code -for (i=0; i<n; i++) Py_DECREF(mps[i]); -\end_layout - -\begin_layout LyX-Code -PyDataMem_FREE(mps); -\end_layout - -\begin_layout LyX-Code -<return> -\end_layout - -\begin_layout Description -PyArray_Zero ( -\family typewriter -char* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to newly created memory of size -\emph on -arr -\emph default -->itemsize that holds the representation of 0 for that type. - The returned pointer, -\emph on -ret -\emph default -, -\series bold -must be freed -\series default - using -\family typewriter -\emph on -PyDataMem_FREE -\family default -\emph default -(ret) when it is not needed anymore. -\end_layout - -\begin_layout Description -PyArray_One ( -\family typewriter -char* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to newly created memory of size -\emph on -arr -\emph default -->itemsize that holds the representation of 1 for that type. - The returned pointer, -\emph on -ret -\emph default -, -\series bold -must be freed -\series default - using -\family typewriter -PyDataMem_FREE -\family default -(ret) when it is not needed anymore. -\end_layout - -\begin_layout Description -PyArray_ValidType ( -\family typewriter -int -\family default -) ( -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns -\family typewriter -NPY_TRUE -\family default - if -\family typewriter -\emph on -typenum -\family default -\emph default - represents a valid type-number (builtin or user-defined or character code). - Otherwise, this function returns -\family typewriter -NPY_FALSE -\family default -. -\end_layout - -\begin_layout Subsubsection -New data types -\end_layout - -\begin_layout Description -PyArray_InitArrFuncs ( -\family typewriter -void -\family default -) ( -\family typewriter -PyArray_ArrFuncs* -\family default - f) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Initialize all function pointers and members to -\family typewriter -NULL -\family default -. -\end_layout - -\begin_layout Description -PyArray_RegisterDataType ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Register a data-type as a new user-defined data type for arrays. - The type must have most of its entries filled in. - This is not always checked and errors can produce segfaults. - In particular, the typeobj member of the -\family typewriter -dtype -\family default - structure must be filled with a Python type that has a fixed-size element-size - that corresponds to the elsize member of -\emph on -dtype -\emph default -. - Also the -\family typewriter -f -\family default - member must have the required functions: nonzero, copyswap, copyswapn, - getitem, setitem, and cast (some of the cast functions may be -\family typewriter -NULL -\family default - if no support is desired). - To avoid confusion, you should choose a unique character typecode but this - is not enforced and not relied on internally. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - A user-defined type number is returned that uniquely identifies the type. - A pointer to the new structure can then be obtained from -\family typewriter -PyArray_DescrFromType -\family default - using the returned type number. - A -1 is returned if an error occurs. - If this -\family typewriter -\emph on -dtype -\family default -\emph default - has already been registered (checked only by the address of the pointer), - then return the previously-assigned type-number. - -\end_layout - -\begin_layout Description -PyArray_RegisterCastFunc ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - descr, -\family typewriter -int -\family default - totype, -\family typewriter -PyArray_VectorUnaryFunc* -\family default - castfunc) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Register a low-level casting function, -\emph on -castfunc -\emph default -, to convert from the data-type, -\emph on -descr -\emph default -, to the given data-type number, -\emph on -totype -\emph default -. - Any old casting function is over-written. - A -\family typewriter -0 -\family default - is returned on success or a -\family typewriter --1 -\family default - on failure. - -\end_layout - -\begin_layout Description -PyArray_RegisterCanCast ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - descr, -\family typewriter -int -\family default - totype, -\family typewriter -NPY_SCALARKIND -\family default - scalar) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Register the data-type number, -\emph on -totype -\emph default -, as castable from data-type object, -\emph on -descr -\emph default -, of the given -\emph on -scalar -\emph default - kind. - Use -\emph on -scalar -\emph default - = -\family typewriter -NPY_NOSCALAR -\family default - to register that an array of data-type -\emph on -descr -\emph default - can be cast safely to a data-type whose type_number is -\emph on -totype -\emph default -. - -\end_layout - -\begin_layout Subsubsection -Special functions for NPY_OBJECT -\end_layout - -\begin_layout Description -PyArray_INCREF ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Used for an array, -\emph on -op -\emph default -, that contains any Python objects. - It increments the reference count of every object in the array according - to the data-type of -\emph on -op -\emph default -. - A -1 is returned if an error occurs, otherwise 0 is returned. -\end_layout - -\begin_layout Description -PyArray_Item_INCREF ( -\family typewriter -void -\family default -) ( -\family typewriter -char* -\family default - ptr, -\family typewriter -PyArray_Descr* -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A function to INCREF all the objects at the location -\emph on -ptr -\emph default - according to the data-type -\emph on -dtype -\emph default -. - If -\emph on -ptr -\emph default - is the start of a record with an object at any offset, then this will (recursiv -ely) increment the reference count of all object-like items in the record. -\end_layout - -\begin_layout Description -PyArray_XDECREF ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Used for an array, -\emph on -op -\emph default -, that contains any Python objects. - It decrements the reference count of every object in the array according - to the data-type of -\emph on -op -\emph default -. - Normal return value is 0. - A -1 is returned if an error occurs. -\end_layout - -\begin_layout Description -PyArray_Item_XDECREF ( -\family typewriter -void -\family default -) ( -\family typewriter -char* -\family default - ptr, -\family typewriter -PyArray_Descr* -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A function to XDECREF all the object-like items at the loacation -\emph on -ptr -\emph default - as recorded in the data-type, -\emph on -dtype -\emph default -. - This works recursively so that if -\family typewriter -dtype -\family default - itself has fields with data-types that contain object-like items, all the - object-like fields will be XDECREF -\family typewriter -'d -\family default -. - -\end_layout - -\begin_layout Description -PyArray_FillObjectArray ( -\family typewriter -void -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Fill a newly created array with a single value obj at all locations in - the structure with object data-types. - No checking is performed but -\emph on -arr -\emph default - must be of data-type -\family typewriter -NPY_OBJECT -\family default - and be single-segment and uninitialized (no previous objects in position). - Use -\family typewriter -PyArray_DECREF -\family default -( -\emph on -arr -\emph default -) if you need to decrement all the items in the object array prior to calling - this function. - -\end_layout - -\begin_layout Subsection -Array flags -\end_layout - -\begin_layout Subsubsection -Basic Array Flags -\end_layout - -\begin_layout Standard -An ndarray can have a data segment that is not a simple contiguous chunk - of well-behaved memory you can manipulate. - It may not be aligned with word boundaries (very important on some platforms). - It might have its data in a different byte-order than the machine recognizes. - It might not be writeable. - It might be in Fortan-contiguous order. - The array flags are used to indicate what can be said about data associated - with an array. -\end_layout - -\begin_layout Description -NPY_C_CONTIGUOUS The data area is in C-style contiguous order (last index - varies the fastest). -\end_layout - -\begin_layout Description -NPY_F_CONTIGUOUS The data area is in Fortran-style contiguous order (first - index varies the fastest). -\end_layout - -\begin_layout Description -NPY_OWNDATA The data area is owned by this array. -\end_layout - -\begin_layout Description -NPY_ALIGNED The data area is aligned appropriately (for all strides). -\end_layout - -\begin_layout Description -NPY_WRITEABLE The data area can be written to. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - Notice that the above 3 flags are are defined so that a new, well-behaved - array has these flags defined as true. - -\end_layout - -\begin_layout Description -NPY_UPDATEIFCOPY The data area represents a (well-behaved) copy whose informatio -n should be transferred back to the original when this array is deleted. -\end_layout - -\begin_layout Subsubsection -Combinations of array flags -\end_layout - -\begin_layout Description -NPY_BEHAVED -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -NPY_WRITEABLE -\end_layout - -\begin_layout Description -NPY_CARRAY -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_BEHAVED -\end_layout - -\begin_layout Description -NPY_CARRAY_RO -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_FARRAY -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_BEHAVED -\end_layout - -\begin_layout Description -NPY_FARRAY_RO -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Description -NPY_DEFAULT -\family typewriter -NPY_CARRAY -\end_layout - -\begin_layout Description -NPY_UPDATE_ALL -\family typewriter -NPY_C_CONTIGUOUS -\family default - | -\family typewriter -NPY_F_CONTIGUOUS -\family default - | -\family typewriter -NPY_ALIGNED -\end_layout - -\begin_layout Subsubsection -Flag-like constants -\end_layout - -\begin_layout Standard -These constants are used in PyArray_FromAny (and its macro forms) to specify - desired properties of the new array. -\end_layout - -\begin_layout Description -NPY_FORCECAST Cast to the desired type, even if it can't be done without - losing information. -\end_layout - -\begin_layout Description -NPY_ENSURECOPY Make sure the resulting array is a copy of the original. -\end_layout - -\begin_layout Description -NPY_ENSUREARRAY Make sure the resulting object is an actual ndarray (or - bigndarray), and not a sub-class. -\end_layout - -\begin_layout Description -NPY_NOTSWAPPED Only used in -\family typewriter -PyArray_CheckFromAny -\family default - to over-ride the byteorder of the data-type object passed in. - -\end_layout - -\begin_layout Description -NPY_BEHAVED_NS -\family typewriter -NPY_ALIGNED -\family default - | -\family typewriter -NPY_WRITEABLE -\family default - | -\family typewriter -NPY_NOTSWAPPED -\end_layout - -\begin_layout Subsubsection -Flag checking -\end_layout - -\begin_layout Standard -For all of these macros -\emph on -arr -\emph default - must be an instance of a (subclass of) -\family typewriter -PyArray_Type -\family default -, but no checking is done. -\end_layout - -\begin_layout Description -PyArray_CHKFLAGS (arr, flags) -\end_layout - -\begin_layout Description -\InsetSpace ~ - The first parameter, arr, must be an ndarray or subclass. - The parameter, -\emph on -flags -\emph default -, should be an integer consisting of bitwise combinations of the possible - flags an array can have: -\family typewriter -NPY_C_CONTIGUOUS -\family default -, -\family typewriter -NPY_F_CONTIGUOUS -\family default -, -\family typewriter -NPY_OWNDATA -\family default -, -\family typewriter -NPY_ALIGNED -\family default -, -\family typewriter -NPY_WRITEABLE -\family default -, -\family typewriter -NPY_UPDATEIFCOPY -\family default -. -\end_layout - -\begin_layout Description -PyArray_ISCONTIGUOUS (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -arr -\emph default - is C-style contiguous. -\end_layout - -\begin_layout Description -PyArray_ISFORTRAN (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -arr -\emph default - is Fortran-style contiguous. -\end_layout - -\begin_layout Description -PyArray_ISWRITEABLE (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - can be written to -\end_layout - -\begin_layout Description -PyArray_ISALIGNED (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is properly aligned on the machine. -\end_layout - -\begin_layout Description -PyArray_ISBEHAVED (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evalutes true if the data area of -\emph on -arr -\emph default - is aligned and writeable and in machine byte-order according to its descriptor. -\end_layout - -\begin_layout Description -PyArray_ISBEHAVED_RO (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is aligned and in machine byte-order. -\end_layout - -\begin_layout Description -PyArray_ISCARRAY (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is C-style contiguous, and -\family typewriter -PyArray_ISBEHAVED -\family default -( -\emph on -arr -\emph default -) is true. -\end_layout - -\begin_layout Description -PyArray_ISFARRAY (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is Fortran-style contiguous and -\family typewriter -PyArray_ISBEHAVED -\family default -( -\emph on -arr -\emph default -) is true. -\end_layout - -\begin_layout Description -PyArray_ISCARRAY_RO (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is C-style contiguous, aligned, and in machine byte-order. - -\end_layout - -\begin_layout Description -PyArray_ISFARRAY_RO (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - is Fortran-style contiguous, aligned, and in machine byte-order -\series bold -. - -\end_layout - -\begin_layout Description -PyArray_ISONESEGMENT (arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if the data area of -\emph on -arr -\emph default - consists of a single (C-style or Fortran-style) contiguous segment. -\end_layout - -\begin_layout Description -PyArray_UpdateFlags ( -\family typewriter -void -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr, -\family typewriter -int -\family default - flagmask) -\end_layout - -\begin_layout Description -\InsetSpace ~ - The -\family typewriter -NPY_C_CONTIGUOUS -\family default -, -\family typewriter -NPY_ALIGNED -\family default -, and -\family typewriter -NPY_F_CONTIGUOUS -\family default - array flags can be -\begin_inset Quotes eld -\end_inset - -calculated -\begin_inset Quotes erd -\end_inset - - from the array object itself. - This routine updates one or more of these flags of -\emph on -arr -\emph default - as specified in -\emph on -flagmask -\emph default - by performing the required calculation. - -\end_layout - -\begin_layout Warning -It is important to keep the flags updated (using PyArray_UpdateFlags can - help) whenever a manipulation with an array is performed that might cause - them to change. - Later calculations in NumPy that rely on the state of these flags do not - repeat the calculation to update them. - -\end_layout - -\begin_layout Subsection -Array method alternative API -\end_layout - -\begin_layout Subsubsection -Conversion -\end_layout - -\begin_layout Description -PyArray_GetField ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - offset) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -getfield -\series default -( -\emph on -dtype -\emph default -, -\emph on -offset -\emph default -). - Return a new array of the given -\emph on -dtype -\emph default - using the data in the current array at a specified -\emph on -offset -\emph default - in bytes. - The -\emph on -offset -\emph default - plus the itemsize of the new array type must be less than -\emph on -self -\emph default -->descr->elsize or an error is raised. - The same shape and strides as the original array are used. - Therefore, this function has the effect of returning a field from a record - array. - But, it can also be used to select specific bytes or groups of bytes from - any array type. - -\end_layout - -\begin_layout Description -PyArray_SetField ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -int -\family default - offset, -\family typewriter -PyObject* -\family default - val) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -setfield -\series default -( -\emph on -val -\emph default -, -\emph on -dtype -\emph default -, -\emph on -offset -\emph default -). - Set the field starting at -\emph on -offset -\emph default - in bytes and of the given -\emph on -dtype -\emph default - to -\emph on -val -\emph default -. - The -\emph on -offset -\emph default - plus -\emph on -dtype -\emph default -->elsize must be less than -\emph on -self -\emph default -->descr->elsize or an error is raised. - Otherwise, the -\emph on -val -\emph default - argument is converted to an array and copied into the field pointed to. - If necessary, the elements of -\emph on -val -\emph default - are repeated to fill the destination array, But, the number of elements - in the destination must be an integer multiple of the number of elements - in -\emph on -val -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_Byteswap ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -Bool -\family default - inplace) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -byteswap -\series default -( -\emph on -inplace -\emph default -). - Return an array whose data area is byteswapped. - If -\emph on -inplace -\emph default - is non-zero, then do the byteswap inplace and return a reference to self. - Otherwise, create a byteswapped copy and leave self unchanged. -\end_layout - -\begin_layout Description -PyArray_NewCopy ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - old, -\family typewriter -NPY_ORDER -\family default - order) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -copy -\series default -( -\emph on -fortran -\emph default -). - Make a copy of the -\emph on -old -\emph default - array. - The returned array is always aligned and writeable with data interpreted - the same as the old array. - If -\emph on -order -\emph default - is -\family typewriter -NPY_CORDER -\family default -, then a C-style contiguous array is returned. - If -\emph on -order -\emph default - is -\family typewriter -NPY_FORTRANORDER -\family default -, then a Fortran-style contiguous array is returned. - If -\emph on -order is -\emph default - -\family typewriter -NPY_ANYORDER -\family default -, then the array returned is Fortran-style contiguous only if the old one - is; otherwise, it is C-style contiguous. - -\end_layout - -\begin_layout Description -PyArray_ToList ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -tolist -\series default -(). - Return a nested Python list from -\emph on -self -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_ToString (PyObject*) (PyArrayObject* self, NPY_ORDER order) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -tobytes -\series default -( -\emph on -order -\emph default -). - Return the bytes of this array in a Python string. - -\end_layout - -\begin_layout Description -PyArray_ToFile ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -FILE* -\family default - fp, -\family typewriter -char* -\family default - sep, -\family typewriter -char* -\family default - format) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Write the contents of -\emph on -self -\emph default - to the file pointer -\emph on -fp -\emph default - in C-style contiguous fashion. - Write the data as binary bytes if -\family typewriter -\emph on -sep -\family default -\emph default - is the string -\begin_inset Quotes eld -\end_inset - - -\begin_inset Quotes erd -\end_inset - - or -\family typewriter -NULL -\family default -. - Otherwise, write the contents of -\emph on -self -\emph default - as text using the -\family typewriter -\emph on -sep -\family default -\emph default - string as the item separator. - Each item will be printed to the file. - If the -\emph on -format -\emph default - string is not -\family typewriter -NULL -\family default - or -\begin_inset Quotes eld -\end_inset - - -\begin_inset Quotes erd -\end_inset - -, then it is a Python print statement format string showing how the items - are to be written. -\end_layout - -\begin_layout Description -PyArray_Dump ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - self, -\family typewriter -PyObject* -\family default - file, -\family typewriter -int -\family default - protocol) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Pickle the object in -\emph on -self -\emph default - to the given -\emph on -file -\emph default - (either a string or a Python file object). - If -\emph on -file -\emph default - is a Python string it is considered to be the name of a file which is then - opened in binary mode. - The given -\emph on -protocol -\emph default - is used (if -\emph on -protocol -\emph default - is negative, or the highest available is used). - This is a simple wrapper around cPickle.dump( -\emph on -self -\emph default -, -\emph on -file -\emph default -, -\emph on -protocol -\emph default -). -\end_layout - -\begin_layout Description -PyArray_Dumps ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - self, -\family typewriter -int -\family default - protocol) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Pickle the object in -\emph on -self -\emph default - to a Python string and return it. - Use the Pickle -\emph on -protocol -\emph default - provided (or the highest available if -\emph on -protocol -\emph default - is negative). - -\end_layout - -\begin_layout Description -PyArray_FillWithScalar ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Fill the array, -\emph on -arr -\emph default -, with the given scalar object, -\emph on -obj -\emph default -. - The object is first converted to the data type of -\emph on -arr -\emph default -, and then copied into every location. - A -1 is returned if an error occurs, otherwise 0 is returned. -\end_layout - -\begin_layout Description -PyArray_View ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Descr* -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -view -\series default -( -\emph on -dtype -\emph default -). - Return a new view of the array -\emph on -self -\emph default - as possibly a different data-type, -\emph on -dtype -\emph default -. - If -\emph on -dtype -\emph default - is -\family typewriter -NULL -\family default -, then the returned array will have the same data type as -\emph on -self -\emph default -. - The new data-type must be consistent with the size of -\emph on -self -\emph default -. - Either the itemsizes must be identical, or -\emph on -self -\emph default - must be single-segment and the total number of bytes must be the same. - In the latter case the dimensions of the returned array will be altered - in the last (or first for Fortran-style contiguous arrays) dimension. - The data area of the returned array and self is exactly the same. -\end_layout - -\begin_layout Subsubsection -Shape Manipulation -\end_layout - -\begin_layout Description -PyArray_Newshape ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Dims* -\family default - newshape) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Result will be a new array (pointing to the same memory location as -\emph on -self -\emph default - if possible), but having a shape given by -\emph on -newshape -\emph default -. - If the new shape is not compatible with the strides of -\emph on -self -\emph default -, then a copy of the array with the new specified shape will be returned. - -\end_layout - -\begin_layout Description -PyArray_Reshape ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - shape) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\family typewriter -\emph on -self -\family default -\emph default -. -\series bold -reshape -\series default -( -\family typewriter -\emph on -shape -\family default -\emph default -) where -\emph on -shape -\emph default - is a sequence. - Converts -\emph on -shape -\emph default - to a -\family typewriter -PyArray_Dims -\family default - structure and calls -\family typewriter -PyArray_Newshape -\family default - internally. - -\end_layout - -\begin_layout Description -PyArray_Squeeze ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -squeeze -\series default -(). - Return a new view of -\emph on -self -\emph default - with all of the dimensions of length 1 removed from the shape. - -\end_layout - -\begin_layout Warning -matrix objects are always 2-dimensional. - Therefore, -\family typewriter -PyArray_Squeeze -\family default - has no effect on arrays of matrix sub-class. - -\end_layout - -\begin_layout Description -PyArray_SwapAxes ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - a1, -\family typewriter -int -\family default - a2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -swapaxes -\series default -( -\emph on -a1 -\emph default -, -\emph on -a2 -\emph default -). - The returned array is a new view of the data in -\emph on -self -\emph default - with the given axes, -\emph on -a1 -\emph default - and -\emph on -a2 -\emph default -, swapped. -\end_layout - -\begin_layout Description -PyArray_Resize ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Dims* -\family default - newshape, -\family typewriter -int -\family default - refcheck, NPY_ORDER fortran) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -resize -\series default -( -\emph on -newshape -\emph default -, refcheck -\family typewriter -= -\family default -\emph on -refcheck -\emph default -, order= -\shape italic -fortran -\shape default -). - This function only works on single-segment arrays. - It changes the shape of -\emph on -self -\emph default - inplace and will reallocate the memory for -\emph on -self -\emph default - if -\emph on -newshape -\emph default - has a different total number of elements then the old shape. - If reallocation is necessary, then -\emph on -self -\emph default - must own its data, have -\emph on -self -\emph default -- -\family typewriter ->base==NULL -\family default -, have -\emph on -self -\emph default -- -\family typewriter ->weakrefs==NULL -\family default -, and (unless refcheck is 0) not be referenced by any other array. - A reference to the new array is returned. - The -\shape italic -fortran -\shape default - argument can be NPY_ANYORDER, NPY_CORDER, or NPY_FORTRANORDER. - This argument is used if the number of dimension is (or is being resized - to be) greater than 2. - It currently has no effect. - Eventually it could be used to determine how the resize operation should - view the data when constructing a differently-dimensioned array. - -\end_layout - -\begin_layout Description -PyArray_Transpose ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyArray_Dims* -\family default - permute) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -transpose -\series default -( -\emph on -permute -\emph default -). - Permute the axes of the ndarray object -\emph on -self -\emph default - according to the data structure -\emph on -permute -\emph default - and return the result. - If -\emph on -permute -\emph default - is -\family typewriter -NULL -\family default -, then the resulting array has its axes reversed. - For example if -\emph on -self -\emph default - has shape -\begin_inset Formula $10\times20\times30$ -\end_inset - -, and -\emph on -permute -\family typewriter -\emph default -.ptr -\family default - is (0,2,1) the shape of the result is -\begin_inset Formula $10\times30\times20.$ -\end_inset - - If -\emph on -permute -\emph default - is -\family typewriter -NULL -\family default -, the shape of the result is -\begin_inset Formula $30\times20\times10.$ -\end_inset - - -\end_layout - -\begin_layout Description -PyArray_Flatten ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -NPY_ORDER -\family default - order) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -flatten -\series default -( -\emph on -order -\emph default -). - Return a 1-d copy of the array. - If -\emph on -order -\emph default - is -\family typewriter -NPY_FORTRANORDER -\family default - the elements are scanned out in Fortran order (first-dimension varies the - fastest). - If -\emph on -order -\emph default - is -\family typewriter -NPY_CORDER -\family default -, the elements of -\family typewriter -self -\family default - are scanned in C-order (last dimension varies the fastest). - If -\emph on -order -\emph default - -\family typewriter -NPY_ANYORDER -\family default -, then the result of -\family typewriter -PyArray_ISFORTRAN -\family default -( -\emph on -self -\emph default -) is used to determine which order to flatten. -\end_layout - -\begin_layout Description -PyArray_Ravel ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -NPY_ORDER -\family default - order) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -.ravel( -\emph on -order -\emph default -). - Same basic functionality as -\family typewriter -PyArray_Flatten -\family default -( -\emph on -self -\emph default -, -\emph on -order -\emph default -) except if -\emph on -order -\emph default - is 0 and -\emph on -self -\emph default - is C-style contiguous, the shape is altered but no copy is performed. -\end_layout - -\begin_layout Subsubsection -Item selection and manipulation -\end_layout - -\begin_layout Description -PyArray_TakeFrom ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - indices, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - ret, -\family typewriter -NPY_CLIPMODE -\family default - clipmode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -take -\series default -( -\emph on -indices -\emph default -, -\emph on -axis -\emph default -, -\emph on -ret -\emph default -, -\emph on -clipmode -\emph default -) except -\emph on -axis -\emph default -=None in Python is obtained by setting -\emph on -axis -\emph default -= -\family typewriter -NPY_MAXDIMS -\family default - in C. - Extract the items from self indicated by the integer-valued -\emph on -indices -\emph default - along the given -\emph on -axis. - -\emph default - The clipmode argument can be -\family typewriter -NPY_RAISE -\family default -, -\family typewriter -NPY_WRAP -\family default -, or -\family typewriter -NPY_CLIP -\family default - to indicate what to do with out-of-bound indices. - The -\emph on -ret -\emph default - argument can specify an output array rather than having one created internally. - -\end_layout - -\begin_layout Description -PyArray_PutTo ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - values, -\family typewriter -PyObject* -\family default - indices, -\family typewriter -NPY_CLIPMODE -\family default - clipmode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -.put( -\emph on -values -\emph default -, -\emph on -indices -\emph default -, -\emph on -clipmode -\emph default -). - Put -\emph on -values -\emph default - into -\emph on -self -\emph default - at the corresponding (flattened) -\emph on -indices -\emph default -. - If -\emph on -values -\emph default - is too small it will be repeated as necessary. - -\end_layout - -\begin_layout Description -PyArray_PutMask ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - values, -\family typewriter -PyObject* -\family default - mask) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Place the -\emph on -values -\emph default - in -\emph on -self -\emph default - wherever corresponding positions (using a flattened context) in -\emph on -mask -\emph default - are true. - The -\emph on -mask -\emph default - and -\emph on -self -\emph default - arrays must have the same total number of elements. - If -\emph on -values -\emph default - is too small, it will be repeated as necessary. -\end_layout - -\begin_layout Description -PyArray_Repeat ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - op, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -repeat -\series default -( -\emph on -op -\emph default -, -\emph on -axis -\emph default -). - Copy the elements of -\emph on -self -\emph default -, -\emph on -op -\emph default - times along the given -\emph on -axis -\emph default -. - Either -\emph on -op -\emph default - is a scalar integer or a sequence of length -\emph on -self -\emph default -->dimensions[ -\emph on -axis -\emph default -] indicating how many times to repeat each item along the axis. -\end_layout - -\begin_layout Description -PyArray_Choose ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArrayObject* -\family default - ret, -\family typewriter -NPY_CLIPMODE -\family default - clipmode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -choose -\series default -( -\emph on -op -\emph default -, -\emph on -ret -\emph default -, -\emph on -clipmode -\emph default -). - Create a new array by selecting elements from the sequence of arrays in - -\emph on -op -\emph default - based on the integer values in -\emph on -self -\emph default -. - The arrays must all be broadcastable to the same shape and the entries - in -\emph on -self -\emph default - should be between 0 and len( -\emph on -op -\emph default -). - The output is placed in -\emph on -ret -\emph default - unless it is -\family typewriter -NULL -\family default - in which case a new output is created. - The -\emph on -clipmode -\emph default - argument determines behavior for when entries in -\emph on -self -\emph default - are not between 0 and len( -\emph on -op -\emph default -). -\end_layout - -\begin_deeper -\begin_layout Description -NPY_RAISE raise a ValueError; -\end_layout - -\begin_layout Description -NPY_WRAP wrap values <0 by adding len( -\emph on -op -\emph default -) and values >=len( -\emph on -op -\emph default -) by subtracting len( -\emph on -op -\emph default -) until they are in range; -\end_layout - -\begin_layout Description -NPY_CLIP all values are clipped to the region [0, len( -\emph on -op -\emph default -) ). -\end_layout - -\end_deeper -\begin_layout Description -PyArray_Sort ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -sort -\series default -( -\emph on -axis -\emph default -). - Return an array with the items of -\emph on -self -\emph default - sorted along -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Description -PyArray_ArgSort ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -argsort -\series default -( -\emph on -axis -\emph default -). - Return an array of indices such that selection of these indices along the - given -\family typewriter -axis -\family default - would return a sorted version of -\emph on -self -\emph default -. - If -\emph on -self -\emph default -->descr is a data-type with fields defined, then self->descr->names is used - to determine the sort order. - A comparison where the first field is equal will use the second field and - so on. - To alter the sort order of a record array, create a new data-type with - a different order of names and construct a view of the array with that - new data-type. - -\end_layout - -\begin_layout Description -PyArray_LexSort ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - sort_keys, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Given a sequence of arrays ( -\emph on -sort_keys -\emph default -) of the same shape, return an array of indices (similar to -\family typewriter -PyArray_ArgSort -\family default -(...)) that would sort the arrays lexicographically. - A lexicographic sort specifies that when two keys are found to be equal, - the order is based on comparison of subsequent keys. - A merge sort (which leaves equal entries unmoved) is required to be defined - for the types. - The sort is accomplished by sorting the indices first using the first -\emph on -sort_key -\emph default - and then using the second -\emph on -sort_key -\emph default - and so forth. - This is equivalent to the lexsort( -\emph on -sort_keys -\emph default -, -\emph on -axis -\emph default -) Python command. - Because of the way the merge-sort works, be sure to understand the order - the -\emph on -sort_keys -\emph default - must be in (reversed from the order you would use when comparing two elements). -\end_layout - -\begin_layout Description -\InsetSpace ~ - If these arrays are all collected in a record array, then -\family typewriter -PyArray_Sort -\family default -(...) can also be used to sort the array directly. - -\end_layout - -\begin_layout Description -PyArray_SearchSorted ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - values) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -searchsorted -\series default -( -\emph on -values -\emph default -). - Assuming -\emph on -self -\emph default - is a 1-d array in ascending order representing bin boundaries then the - output is an array the same shape as -\emph on -values -\emph default - of bin numbers, giving the bin into which each item in -\emph on -values -\emph default - would be placed. - No checking is done on whether or not self is in ascending order. -\end_layout - -\begin_layout Description -PyArray_Diagonal ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - offset, -\family typewriter -int -\family default - axis1, -\family typewriter -int -\family default - axis2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -diagonal -\series default -( -\emph on -offset -\emph default -, -\emph on -axis1 -\emph default -, -\emph on -axis2 -\emph default -). - Return the -\emph on -offset -\emph default - diagonals of the 2-d arrays defined by -\emph on -axis1 -\emph default - and -\emph on -axis2 -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_Nonzero ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -nonzero -\series default -(). - Returns a tuple of index arrays that select elements of -\emph on -self -\emph default - that are nonzero. - If (nd= -\family typewriter -PyArray_NDIM -\family default -( -\family typewriter -self -\family default -))==1, then a single index array is returned. - The index arrays have data type -\family typewriter -NPY_INTP -\family default -. - If a tuple is returned (nd -\begin_inset Formula $\neq$ -\end_inset - -1), then its length is nd. - -\end_layout - -\begin_layout Description -PyArray_Compress ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - condition, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -compress -\series default -( -\emph on -condition -\emph default -, -\emph on -axis -\emph default -). - Return the elements along -\emph on -axis -\emph default - corresponding to elements of -\emph on -condition -\emph default - that are true. - -\end_layout - -\begin_layout Subsubsection -Calculation -\end_layout - -\begin_layout Tip -Pass in NPY_MAXDIMS for axis in order to achieve the same effect that is - obtained by passing in axis = None in Python (treating the array as a 1-d - array). - -\end_layout - -\begin_layout Description -PyArray_ArgMax ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -argmax -\series default -( -\emph on -axis -\emph default -). - Return the index of the largest element of -\emph on -self -\emph default - along -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Description -PyArray_ArgMin ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -argmin -\series default -( -\emph on -axis -\emph default -). - Return the index of the smallest element of -\emph on -self -\emph default - along -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Max ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -max -\series default -( -\emph on -axis -\emph default -). - Return the largest element of -\emph on -self -\emph default - along the given -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Min ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -min -\series default -( -\emph on -axis -\emph default -). - Return the smallest element of -\emph on -self -\emph default - along the given -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Ptp ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -ptp -\series default -( -\emph on -axis -\emph default -). - Return the difference between the largest element of -\emph on -self -\emph default - along -\emph on -axis -\emph default - and the smallest element of -\emph on -self -\emph default - along -\emph on -axis -\emph default -. -\end_layout - -\begin_layout Note -The rtype argument specifies the data-type the reduction should take place - over. - This is important if the data-type of the array is not -\begin_inset Quotes eld -\end_inset - -large -\begin_inset Quotes erd -\end_inset - - enough to handle the output. - By default, all integer data-types are made at least as large as NPY_LONG - for the -\begin_inset Quotes eld -\end_inset - -add -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - -multiply -\begin_inset Quotes erd -\end_inset - - ufuncs (which form the basis for mean, sum, cumsum, prod, and cumprod functions -). -\end_layout - -\begin_layout Description -PyArray_Mean ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -mean -\series default -( -\emph on -axis -\emph default -, -\emph on -rtype -\emph default -). - Returns the mean of the elements along the given -\emph on -axis -\emph default -, using the enumerated type -\emph on -rtype -\emph default - as the data type to sum in. - Default sum behavior is obtained using -\family typewriter -NPY_NOTYPE -\family default - for -\emph on -rtype -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Trace ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - offset, -\family typewriter -int -\family default - axis1, -\family typewriter -int -\family default - axis2, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -trace -\series default -( -\emph on -offset -\emph default -, -\emph on -axis1 -\emph default -, -\emph on -axis2 -\emph default -, -\emph on -rtype -\emph default -). - Return the sum (using -\emph on -rtype -\emph default - as the data type of summation) over the -\emph on -offset -\emph default - diagonal elements of the 2-d arrays defined by -\emph on -axis1 -\emph default - and -\emph on -axis2 -\emph default - variables. - A positive offset chooses diagonals above the main diagonal. - A negative offset selects diagonals below the main diagonal. - -\end_layout - -\begin_layout Description -PyArray_Clip ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -PyObject* -\family default - min, -\family typewriter -PyObject* -\family default - max) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -clip -\series default -( -\emph on -min -\emph default -, -\emph on -max -\emph default -). - Clip an array, -\emph on -self -\emph default -, so that values larger than -\emph on -max -\emph default - are fixed to -\emph on -max -\emph default - and values less than -\emph on -min -\emph default - are fixed to -\emph on -min -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Conjugate ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -conjugate -\series default -() and -\emph on -self -\emph default -. -\series bold -conj -\series default -() Return the complex conjugate of -\emph on -self -\emph default -. - If -\emph on -self -\emph default - is not of complex data type, then return -\emph on -self -\emph default - with an reference. -\end_layout - -\begin_layout Description -PyArray_Round ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - decimals, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -round -\series default -( -\emph on -decimals -\emph default -, -\emph on -out -\emph default -). - Returns the array with elements rounded to the nearest decimal place. - The decimal place is defined as the -\begin_inset Formula $10^{-\textrm{decimals}}$ -\end_inset - - digit so that negative -\emph on -decimals -\emph default - cause rounding to the nearest 10's, 100's, etc. - If out is -\family typewriter -NULL -\family default -, then the output array is created, otherwise the output is placed in -\family typewriter -\emph on -out -\family default -\emph default - which must be the correct size and type. - -\end_layout - -\begin_layout Description -PyArray_Std ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -std -\series default -( -\emph on -axis -\emph default -, -\emph on -rtype -\emph default -). - Return the standard deviation using data along -\emph on -axis -\emph default - converted to data type -\emph on -rtype -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_Sum ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -sum -\series default -( -\family typewriter -\emph on -axis -\family default -\emph default -, -\family typewriter -\emph on -rtype -\family default -\emph default -). - Return 1-d vector sums of elements in -\emph on -self -\emph default - along -\emph on -axis -\emph default -. - Perform the sum after converting data to data type -\emph on -rtype -\emph default -. -\end_layout - -\begin_layout Description -PyArray_CumSum ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -cumsum -\series default -( -\family typewriter -\emph on -axis -\family default -\emph default -, -\family typewriter -\emph on -rtype -\family default -\emph default -). - Return cumulative 1-d sums of elements in -\emph on -self -\emph default - along -\emph on -axis -\emph default -. - Perform the sum after converting data to data type -\emph on -rtype -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Prod ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -prod -\series default -( -\emph on -axis -\emph default -, -\emph on -rtype -\emph default -). - Return 1-d products of elements in -\emph on -self -\emph default - along -\emph on -axis -\emph default -. - Perform the product after converting data to data type -\emph on -rtype -\emph default -. -\end_layout - -\begin_layout Description -PyArray_CumProd ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -int -\family default - rtype, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -cumprod -\series default -( -\emph on -axis -\emph default -, -\emph on -rtype -\emph default -). - Return 1-d cumulative products of elements in -\family typewriter -self -\family default - along -\family typewriter -axis -\family default -. - Perform the product after converting data to data type -\family typewriter -rtype -\family default -. -\end_layout - -\begin_layout Description -PyArray_All ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -all -\series default -( -\emph on -axis -\emph default -). - Return an array with True elements for every 1-d sub-array of -\family typewriter -self -\family default - defined by -\family typewriter -axis -\family default - in which all the elements are True. - -\end_layout - -\begin_layout Description -PyArray_Any ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - self, -\family typewriter -int -\family default - axis, -\family typewriter -PyArrayObject* -\family default - out) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Equivalent to -\emph on -self -\emph default -. -\series bold -any -\series default -( -\emph on -axis -\emph default -). - Return an array with True elements for every 1-d sub-array of -\emph on -self -\emph default - defined by -\emph on -axis -\emph default - in which any of the elements are True. - -\end_layout - -\begin_layout Subsection -Functions -\end_layout - -\begin_layout Subsubsection -Array Functions -\end_layout - -\begin_layout Description -PyArray_AsCArray ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject** -\family default - op, -\family typewriter -void* -\family default - ptr, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - nd, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - itemsize) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Sometimes it is useful to access a multidimensional array as a C-style - multi-dimensional array so that algorithms can be implemented using C's - a[i][j][k] syntax. - This routine returns a pointer, -\emph on -ptr -\emph default -, that simulates this kind of C-style array, for 1-, 2-, and 3-d ndarrays. - -\end_layout - -\begin_deeper -\begin_layout Description -op The address to any Python object. - This Python object will be replaced with an equivalent well-behaved, C-style - contiguous, ndarray of the given data type specifice by the last two arguments. - Be sure that stealing a reference in this way to the input object is justified. - -\end_layout - -\begin_layout Description -ptr The address to a (ctype* for 1-d, ctype** for 2-d or ctype*** for 3-d) - variable where ctype is the equivalent C-type for the data type. - On return, -\emph on -ptr -\emph default - will be addressable as a 1-d, 2-d, or 3-d array. - -\end_layout - -\begin_layout Description -dims An output array that contains the shape of the array object. - This array gives boundaries on any looping that will take place. - -\end_layout - -\begin_layout Description -nd The dimensionality of the array (1, 2, or 3). - -\end_layout - -\begin_layout Description -typenum The expected data type of the array. - -\end_layout - -\begin_layout Description -itemsize This argument is only needed when -\emph on -typenum -\emph default - represents a flexible array. - Otherwise it should be 0. - -\end_layout - -\end_deeper -\begin_layout Note -The simulation of a C-style array is not complete for 2-d and 3-d arrays. - For example, the simulated arrays of pointers cannot be passed to subroutines - expecting specific, statically-defined 2-d and 3-d arrays. - To pass to functions requiring those kind of inputs, you must statically - define the required array and copy data. - -\end_layout - -\begin_layout Description -PyArray_Free ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -void* -\family default - ptr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Must be called with the same objects and memory locations returned from - -\family typewriter -PyArray_AsCArray -\family default -(...). - This function cleans up memory that otherwise would get leaked. -\end_layout - -\begin_layout Description -PyArray_Concatenate ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Join the sequence of objects in -\emph on -obj -\emph default - together along -\emph on -axis -\emph default - into a single array. - If the dimensions or types are not compatible an error is raised. -\end_layout - -\begin_layout Description -PyArray_InnerProduct ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj1, -\family typewriter -PyObject* -\family default - obj2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Compute a product-sum over the last dimensions of -\emph on -obj1 -\emph default - and -\emph on -obj2 -\emph default -. - Neither array is conjugated. - -\end_layout - -\begin_layout Description -PyArray_MatrixProduct ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj1, -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Compute a product-sum over the last dimension of -\emph on -obj1 -\emph default - and the second-to-last dimension of -\emph on -obj2 -\emph default -. - For 2-d arrays this is a matrix-product. - Neither array is conjugated. - -\end_layout - -\begin_layout Description -PyArray_CopyAndTranspose ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject -\family default -* op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A specialized copy and transpose function that works only for 2-d arrays. - The returned array is a transposed copy of -\emph on -op -\emph default -. -\end_layout - -\begin_layout Description -PyArray_Correlate ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - op1, -\family typewriter -PyObject* -\family default - op2, -\family typewriter -int -\family default - mode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Compute the 1-d correlation of the 1-d arrays -\emph on -op1 -\emph default - and -\emph on -op2 -\emph default -. - The correlation is computed at each output point by multiplying -\emph on -op1 -\emph default - by a shifted version of -\emph on -op2 -\emph default - and summing the result. - As a result of the shift, needed values outside of the defined range of - -\emph on -op1 -\emph default - and -\emph on -op2 -\emph default - are interpreted as zero. - The mode determines how many shifts to return: 0 - return only shifts that - did not need to assume zero-values; 1 - return an object that is the same - size as -\emph on -op1 -\emph default -, 2 - return all possible shifts (any overlap at all is accepted). - -\end_layout - -\begin_layout Description -PyArray_Where ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - condition, -\family typewriter -PyObject* -\family default - x, -\family typewriter -PyObject* -\family default - y) -\end_layout - -\begin_layout Description -\InsetSpace ~ - If both -\family typewriter -x -\family default - and -\family typewriter -y -\family default - are -\family typewriter -NULL -\family default -, then return -\family typewriter -PyArray_Nonzero -\family default -( -\family typewriter -\emph on -condition -\family default -\emph default -). - Otherwise, both -\emph on -x -\emph default - and -\emph on -y -\emph default - must be given and the object returned is shaped like -\emph on -condition -\emph default - and has elements of -\emph on -x -\emph default - and -\emph on -y -\emph default - where -\emph on -condition -\emph default - is respectively True or False. - -\end_layout - -\begin_layout Subsubsection -Other functions -\end_layout - -\begin_layout Description -PyArray_CheckStrides ( -\family typewriter -Bool -\family default -) ( -\family typewriter -int -\family default - elsize, -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp -\family default - numbytes, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -npy_intp* -\family default - newstrides) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Determine if -\emph on -newstrides -\emph default - is a strides array consistent with the memory of an -\emph on -nd -\emph default --dimensional array with shape -\family typewriter -dims -\family default - and element-size, -\emph on -elsize -\emph default -. - The -\emph on -newstrides -\emph default - array is checked to see if jumping by the provided number of bytes in each - direction will ever mean jumping more than -\emph on -numbytes -\emph default - which is the assumed size of the available memory segment. - If -\emph on -numbytes -\emph default - is 0, then an equivalent -\emph on -numbytes -\emph default - is computed assuming -\emph on -nd -\emph default -, -\emph on -dims -\emph default -, and -\emph on -elsize -\emph default - refer to a single-segment array. - Return -\family typewriter -NPY_TRUE -\family default - if -\emph on -newstrides -\emph default - is acceptable, otherwise return -\family typewriter -NPY_FALSE -\family default -. -\end_layout - -\begin_layout Description -PyArray_MultiplyList ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -npy_intp* -\family default - seq, -\family typewriter -int -\family default - n) -\end_layout - -\begin_layout Description -PyArray_MultiplyIntList ( -\family typewriter -int -\family default -) ( -\family typewriter -int* -\family default - seq, -\family typewriter -int -\family default - n) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Both of these routines multiply an -\emph on -n -\emph default --length array, -\emph on -seq -\emph default -, of integers and return the result. - No overflow checking is performed. -\end_layout - -\begin_layout Description -PyArray_CompareLists ( -\family typewriter -int -\family default -) ( -\family typewriter -npy_intp* -\family default - l1, -\family typewriter -npy_intp* -\family default - l2, -\family typewriter -int -\family default - n) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Given two -\emph on -n -\emph default --length arrays of integers, -\emph on -l1 -\emph default -, and -\emph on -l2 -\emph default -, return 1 if the lists are identical; otherwise, return 0. - -\end_layout - -\begin_layout Subsection -Array Iterators -\end_layout - -\begin_layout Standard -An array iterator is a simple way to access the elements of an N-dimensional - array quickly and efficiently. - Section -\begin_inset LatexCommand ref -reference "sec:array_iterator" - -\end_inset - - provides more description and examples of this useful approach to looping - over an array. - -\end_layout - -\begin_layout Description -PyArray_IterNew ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an array iterator object from the array, -\emph on -arr -\emph default -. - This is equivalent to -\emph on -arr -\emph default -. -\series bold -flat -\series default -. - The array iterator object makes it easy to loop over an N-dimensional non-conti -guous array in C-style contiguous fashion. - -\end_layout - -\begin_layout Description -PyArray_IterAllButAxis ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -int -\family default - *axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an array iterator that will iterate over all axes but the one provided - in -\emph on -*axis -\emph default -. - The returned iterator cannot be used with -\family typewriter -PyArray_ITER_GOTO1D -\family default -. - This iterator could be used to write something similar to what ufuncs do - wherein the loop over the largest axis is done by a separate sub-routine. - If -\emph on -*axis -\emph default - is negative then -\emph on -*axis -\emph default - will be set to the axis having the smallest stride and that axis will be - used. - -\end_layout - -\begin_layout Description -PyArray_BroadcastToShape ( -\family typewriter -PyObject* -\family default -)( -\family typewriter -PyObject* -\family default - arr, -\family typewriter -npy_intp -\family default - *dimensions, -\family typewriter -int -\family default - nd) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an array iterator that is broadcast to iterate as an array of the - shape provided by -\emph on -dimensions -\emph default - and -\emph on -nd -\emph default -. - -\end_layout - -\begin_layout Description -PyArrayIter_Check ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates true if -\emph on -op -\emph default - is an array iterator (or instance of a subclass of the array iterator type). - -\end_layout - -\begin_layout Description -PyArray_ITER_RESET ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - iterator) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Reset an -\emph on -iterator -\emph default - to the beginning of the array. -\end_layout - -\begin_layout Description -PyArray_ITER_NEXT ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - iterator) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Incremement the index and the dataptr members of the -\emph on -iterator -\emph default - to point to the next element of the array. - If the array is not (C-style) contiguous, also increment the N-dimensional - coordinates array. -\end_layout - -\begin_layout Description -PyArray_ITER_DATA ( -\family typewriter -void* -\family default -)( -\family typewriter -PyObject* -\family default - iterator) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A pointer to the current element of the array. - -\end_layout - -\begin_layout Description -PyArray_ITER_GOTO ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - iterator, -\family typewriter -npy_intp* -\family default - destination) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Set the -\emph on -iterator -\emph default - index, dataptr, and coordinates members to the location in the array indicated - by the N-dimensional c-array, -\emph on -destination -\emph default -, which must have size at least -\emph on -iterator -\emph default -->nd_m1+1. -\end_layout - -\begin_layout Description -PyArray_ITER_GOTO1D ( -\family typewriter -PyObject* -\family default - iterator, -\family typewriter -npy_intp -\family default - index) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Set the -\emph on -iterator -\emph default - index and dataptr to the location in the array indicated by the integer - -\emph on -index -\emph default - which points to an element in the C-styled flattened array. - -\end_layout - -\begin_layout Description -PyArray_ITER_NOTDONE ( -\family typewriter -int -\family default -)( -\family typewriter -PyObject* -\family default - iterator) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates TRUE as long as the iterator has not looped through all of the - elements, otherwise it evaluates FALSE. - -\end_layout - -\begin_layout Subsection -Broadcasting (multi-iterators) -\end_layout - -\begin_layout Description -PyArray_MultiIterNew ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - num, ...) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A simplified interface to broadcasting. - This function takes the number of arrays to broadcast and then -\emph on -num -\emph default - extra ( -\family typewriter -PyObject* -\family default -) arguments. - These arguments are converted to arrays and iterators are created. - -\family typewriter -PyArray_Broadcast -\family default - is then called on the resulting multi-iterator object. - The resulting, broadcasted mult-iterator object is then returned. - A broadcasted operation can then be performed using a single loop and using - -\family typewriter -PyArray_MultiIter_NEXT -\family default -(..) -\end_layout - -\begin_layout Description -PyArray_MultiIter_RESET ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - multi) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Reset all the iterators to the beginning in a multi-iterator object, -\emph on -multi -\emph default -. -\end_layout - -\begin_layout Description -PyArray_MultiIter_NEXT ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - multi) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Advance each iterator in a multi-iterator object, -\emph on -multi -\emph default -, to its next (broadcasted) element. -\end_layout - -\begin_layout Description -PyArray_MultiIter_DATA ( -\family typewriter -void* -\family default -)( -\family typewriter -PyObject* -\family default - multi, -\family typewriter -int -\family default - i) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the data-pointer of the -\emph on -i -\emph default - -\begin_inset Formula $^{\textrm{th}}$ -\end_inset - - iterator in a multi-iterator object. - -\end_layout - -\begin_layout Description -PyArray_MultiIter_NEXTi ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - multi, -\family typewriter -int -\family default - i) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Advance the pointer of only the -\emph on -i -\emph default - -\begin_inset Formula $^{\textrm{th}}$ -\end_inset - - iterator. -\end_layout - -\begin_layout Description -PyArray_MultiIter_GOTO ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - multi, -\family typewriter -npy_intp* -\family default - destination) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Advance each iterator in a multi-iterator object, -\emph on -multi -\emph default -, to the given -\begin_inset Formula $N$ -\end_inset - --dimensional -\emph on -destination -\emph default - where -\begin_inset Formula $N$ -\end_inset - - is the number of dimensions in the broadcasted array. - -\end_layout - -\begin_layout Description -PyArray_MultiIter_GOTO1D ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - multi, -\family typewriter -npy_intp -\family default - index) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Advance each iterator in a multi-iterator object, -\emph on -multi -\emph default -, to the corresponding location of the -\emph on -index -\emph default - into the flattened broadcasted array. - -\end_layout - -\begin_layout Description -PyArray_MultiIter_NOTDONE ( -\family typewriter -int -\family default -)( -\family typewriter -PyObject* -\family default - multi) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates TRUE as long as the multi-iterator has not looped through all - of the elements (of the broadcasted result), otherwise it evaluates FALSE. - -\end_layout - -\begin_layout Description -PyArray_Broadcast ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayMultiIterObject* -\family default - mit) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function encapsulates the broadcasting rules. - The -\emph on -mit -\emph default - container should already contain iterators for all the arrays that need - to be broadcast. - On return, these iterators will be adjusted so that iteration over each - simultaneously will accomplish the broadcasting. - A negative number is returned if an error occurs. - -\end_layout - -\begin_layout Description -PyArray_RemoveSmallest ( -\family typewriter -int -\family default -) ( -\family typewriter -PyArrayMultiIterObject* -\family default - mit) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function takes a multi-iterator object that has been previously -\begin_inset Quotes eld -\end_inset - -broadcasted, -\begin_inset Quotes erd -\end_inset - - finds the dimension with the smallest -\begin_inset Quotes eld -\end_inset - -sum of strides -\begin_inset Quotes erd -\end_inset - - in the broadcasted result and adapts all the iterators so as not to iterate - over that dimension (by effectively making them of length-1 in that dimension). - The corresponding dimension is returned unless -\emph on -mit -\emph default -->nd is 0, then -1 is returned. - This function is useful for constructing ufunc-like routines that broadcast - their inputs correctly and then call a strided 1-d version of the routine - as the inner-loop. - This 1-d version is usually optimized for speed and for this reason the - loop should be performed over the axis that won't require large stride - jumps. - -\end_layout - -\begin_layout Subsection -Array Scalars -\end_layout - -\begin_layout Description -PyArray_Return ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyArrayObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function checks to see if -\emph on -arr -\emph default - is a 0-dimensional array and, if so, returns the appropriate array scalar. - It should be used whenever 0-dimensional arrays could be returned to Python. -\end_layout - -\begin_layout Description -PyArray_Scalar ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -PyArray_Descr* -\family default - dtype, -\family typewriter -PyObject* -\family default - itemsize) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an array scalar object of the given enumerated -\emph on -typenum -\emph default - and -\emph on -itemsize -\emph default - by -\series bold -copying -\series default - from memory pointed to by -\emph on -data -\emph default -. - If -\emph on -swap -\emph default - is nonzero then this function will byteswap the data if appropriate to - the data-type because array scalars are always in correct machine-byte - order. -\end_layout - -\begin_layout Description -PyArray_ToScalar ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -void* -\family default - data, -\family typewriter -PyArrayObject* -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an array scalar object of the type and itemsize indicated by the - array object -\emph on -arr -\emph default - copied from the memory pointed to by -\emph on -data -\emph default - and swapping if the data in -\emph on -arr -\emph default - is not in machine byte-order. -\end_layout - -\begin_layout Description -PyArray_FromScalar ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - scalar, -\family typewriter -PyArray_Descr* -\family default - outcode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a 0-dimensional array of type determined by -\emph on -outcode -\emph default - from -\emph on -scalar -\emph default - which should be an array-scalar object. - If -\emph on -outcode -\emph default - is NULL, then the type is determined from -\family typewriter -\emph on -scalar -\family default -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_ScalarAsCtype ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - scalar, -\family typewriter -void* -\family default - ctypeptr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return in -\emph on -ctypeptr -\emph default - a pointer to the actual value in an array scalar. - There is no error checking so -\emph on -scalar -\emph default - must be an array-scalar object, and ctypeptr must have enough space to - hold the correct type. - For flexible-sized types, a pointer to the data is copied into the memory - of -\emph on -ctypeptr -\emph default -, for all other types, the actual data is copied into the address pointed - to by -\emph on -ctypeptr -\emph default -. - -\end_layout - -\begin_layout Description -PyArray_CastScalarToCtype ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - scalar, -\family typewriter -void* -\family default - ctypeptr, -\family typewriter -PyArray_Descr* -\family default - outcode) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the data (cast to the data type indicated by -\emph on -outcode -\emph default -) from the array-scalar, -\emph on -scalar -\emph default -, into the memory pointed to by -\emph on -ctypeptr -\emph default - (which must be large enough to handle the incoming memory). - -\end_layout - -\begin_layout Description -PyArray_TypeObjectFromType ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - type) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns a scalar type-object from a type-number, -\emph on -type -\emph default -. - Equivalent to -\family typewriter -PyArray_DescrFromType -\family default -( -\emph on -type -\emph default -)->typeobj except for reference counting and error-checking. - Returns a new reference to the typeobject on success or -\family typewriter -NULL -\family default - on failure. -\end_layout - -\begin_layout Description -PyArray_ScalarKind ( -\family typewriter -NPY_SCALARKIND -\family default -) ( -\family typewriter -int -\family default - typenum, -\family typewriter -PyArrayObject** -\family default - arr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the kind of scalar represented by -\emph on -typenum -\emph default - and the array in -\emph on -*arr -\emph default - (if -\emph on -arr -\emph default - is not -\family typewriter -NULL -\family default -). - The array is assumed to be rank-0 and only used if -\emph on -typenum -\emph default - represents a signed integer. - If -\emph on -arr -\emph default - is not -\family typewriter -NULL -\family default - and the first element is negative then -\family typewriter -NPY_INTNEG_SCALAR -\family default - is returned, otherwise -\family typewriter -NPY_INTPOS_SCALAR -\family default - is returned. - The possible return values are -\family typewriter -NPY_ -\family default -<kind> -\family typewriter -_SCALAR -\family default - where <kind> can be -\series bold -INTPOS -\series default -, -\series bold -INTNEG -\series default -, -\series bold -FLOAT -\series default -, -\series bold -COMPLEX -\series default -, -\series bold -BOOL -\series default -, or -\series bold -OBJECT -\series default -. - -\family typewriter -NPY_NOSCALAR -\family default - is also an enumerated value -\family typewriter -NPY_SCALARKIND -\family default - variables can take on. - -\end_layout - -\begin_layout Description -PyArray_CanCoerceScalar ( -\family typewriter -int -\family default -) ( -\family typewriter -char -\family default - thistype, -\family typewriter -char -\family default - neededtype, -\family typewriter -NPY_SCALARKIND -\family default - scalar) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Implements the rules for scalar coercion. - Scalars are only silently coerced from thistype to neededtype if this function - returns nonzero. - If scalar is -\family typewriter -NPY_NOSCALAR -\family default -, then this function is equivalent to -\family typewriter -PyArray_CanCastSafely -\family default -. - The rule is that scalars of the same KIND can be coerced into arrays of - the same KIND. - This rule means that high-precision scalars will never cause low-precision - arrays of the same KIND to be upcast. - -\end_layout - -\begin_layout Subsection -Data-type descriptors -\end_layout - -\begin_layout Warning -Data-type objects must be reference counted so be aware of the action on - the data-type reference of different C-API calls. - The standard rule is that when a data-type object is returned it is a new - reference. - Functions that take -\family typewriter -PyArray_Descr* -\family default - objects and return arrays steal references to the data-type their inputs - unless otherwise noted. - Therefore, you must own a reference to any data-type object used as input - to such a function. - -\end_layout - -\begin_layout Description -PyArray_DescrCheck ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates as true if -\emph on -obj -\emph default - is a data-type object ( -\family typewriter -PyArray_Descr* -\family default -). -\end_layout - -\begin_layout Description -PyArray_DescrNew ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a new data-type object copied from -\emph on -obj -\emph default - (the fields reference is just updated so that the new object points to - the same fields dictionary if any). - -\end_layout - -\begin_layout Description -PyArray_DescrNewFromType ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create a new data-type object from the built-in (or user-registered) data-type - indicated by -\emph on -typenum -\emph default -. - All builtin types should not have any of their fields changed. - This creates a new copy of the -\family typewriter -PyArray_Descr -\family default - structure so that you can fill it in as appropriate. - This function is especially needed for flexible data-types which need to - have a new elsize member in order to be meaningful in array construction. - -\end_layout - -\begin_layout Description -PyArray_DescrNewByteorder ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -PyArray_Descr* -\family default - obj, -\family typewriter -char -\family default - newendian) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create a new data-type object with the byteorder set according to -\emph on -newendian -\emph default -. - All referenced data-type objects (in subdescr and fields members of the - data-type object) are also changed (recursively). - If a byteorder of -\family typewriter -NPY_IGNORE -\family default - is encountered it is left alone. - If newendian is -\family typewriter -NPY_SWAP -\family default -, then all byte-orders are swapped. - Other valid newendian values are -\family typewriter -NPY_NATIVE -\family default -, -\family typewriter -NPY_LITTLE -\family default -, and -\family typewriter -NPY_BIG -\family default - which all cause the returned data-typed descriptor (and all it's referenced - data-type descriptors) to have the corresponding byte-order. -\end_layout - -\begin_layout Description -PyArray_DescrFromObject ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -PyArray_Descr* -\family default - mintype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Determine an appropriate data-type object from the object -\emph on -op -\emph default - (which should be a -\begin_inset Quotes eld -\end_inset - -nested -\begin_inset Quotes erd -\end_inset - - sequence object) and the minimum data-type descriptor mintype (which can - be -\family typewriter -NULL -\family default -). - Similar in behavior to array( -\emph on -op -\emph default -).dtype. - Don't confuse this function with -\family typewriter -PyArray_DescrConverter -\family default -. - This function essentially looks at all the objects in the (nested) sequence - and determines the data-type from the elements it finds. - -\end_layout - -\begin_layout Description -PyArray_DescrFromScalar ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -PyObject* -\family default - scalar) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a data-type object from an array-scalar object. - No checking is done to be sure that -\emph on -scalar -\emph default - is an array scalar. - If no suitable data-type can be determined, then a data-type of NPY_OBJECT - is returned by default. - -\end_layout - -\begin_layout Description -PyArray_DescrFromType ( -\family typewriter -PyArray_Descr* -\family default -) ( -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns a data-type object corresponding to -\emph on -typenum -\emph default -. - The -\emph on -typenum -\emph default - can be one of the enumerated types, a character code for one of the enumerated - types, or a user-defined type. - -\end_layout - -\begin_layout Description -PyArray_DescrConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Descr** -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any compatible Python object, -\emph on -obj -\emph default -, to a data-type object in -\emph on -dtype -\emph default -. - A large number of Python objects can be converted to data-type objects. - See Chapter -\begin_inset LatexCommand ref -reference "cha:Data-descriptor-objects" - -\end_inset - - for a complete description. - This version of the converter converts None objects to a -\family typewriter -NPY_DEFAULT_TYPE -\family default - data-type object. - This function can be used with the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - character code in PyArg_ParseTuple processing. - -\end_layout - -\begin_layout Description -PyArray_DescrConverter2 ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Descr** -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any compatible Python object, -\emph on -obj -\emph default -, to a data-type object in -\emph on -dtype -\emph default -. - This version of the converter converts None objects so that the returned - data-type is -\family typewriter -NULL -\family default -. - This function can also be used with the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - character in PyArg_ParseTuple processing. -\end_layout - -\begin_layout Description -Pyarray_DescrAlignConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Descr** -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Like -\family typewriter -PyArray_DescrConverter -\family default - except it aligns C-struct-like objects on word-boundaries as the compiler - would. -\end_layout - -\begin_layout Description -Pyarray_DescrAlignConverter2 ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Descr** -\family default - dtype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Like -\family typewriter -PyArray_DescrConverter2 -\family default - except it aligns C-struct-like objects on word-boundaries as the compiler - would. -\end_layout - -\begin_layout Description -PyArray_FieldNames ( -\family typewriter -PyObject* -\family default -)( -\family typewriter -PyObject* -\family default - dict) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Take the fields dictionary, -\family typewriter -\emph on -dict -\family default -\emph default -, such as the one attached to a data-type object and construct an ordered-list - of field names such as is stored in the names field of the -\family typewriter -PyArray_Descr -\family default - object. - -\end_layout - -\begin_layout Subsection -Conversion Utilities -\end_layout - -\begin_layout Subsubsection -For use with -\family typewriter -PyArg_ParseTuple -\end_layout - -\begin_layout Standard -All of these functions can be used in -\family typewriter -PyArg_ParseTuple -\family default -(...) with the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - format specifier to automatically convert any Python object to the required - C-object. - All of these functions return -\family typewriter -NPY_SUCCEED -\family default - if successful and -\family typewriter -NPY_FAIL -\family default - if not. - The first argument to all of these function is a Python object. - The second argument is the -\series bold -address -\series default - of the C-type to convert the Python object to. - -\end_layout - -\begin_layout Warning -Be sure to understand what steps you should take to manage the memory when - using these conversion functions. - These functions can require freeing memory, and/or altering the reference - counts of specific objects based on your use. -\end_layout - -\begin_layout Description -PyArray_Converter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyObject** -\family default - address) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any Python object to a -\family typewriter -PyArrayObject -\family default -. - If -\family typewriter -PyArray_Check -\family default -( -\family typewriter -\emph on -obj -\family default -\emph default -) is TRUE then its reference count is incremented and a reference placed - in -\emph on -address -\emph default -. - If -\emph on -obj -\emph default - is not an array, then convert it to an array using -\family typewriter -PyArray_FromAny -\family default -. - No matter what is returned, you must DECREF the object returned by this - routine in -\emph on -address -\emph default - when you are done with it. - -\end_layout - -\begin_layout Description -PyArray_OutputConverter ( -\family typewriter -int -\family default -)( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArrayObject** -\family default - address) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is a default converter for output arrays given to functions. - If -\emph on -obj -\emph default - is -\family typewriter -Py_None -\family default - or -\family typewriter -NULL -\family default -, then -\emph on -*address -\emph default - will be -\family typewriter -NULL -\family default - but the call will succeed. - If -\family typewriter -PyArray_Check -\family default -( -\emph on -obj -\emph default -) is TRUE then it is returned in -\emph on -*address -\emph default - without incrementing its reference count. - -\end_layout - -\begin_layout Description -PyArray_IntpConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Dims* -\family default - seq) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any Python sequence, -\emph on -obj -\emph default -, smaller than -\family typewriter -NPY_MAXDIMS -\family default - to a C-array of -\family typewriter -npy_intp -\family default -. - The Python object could also be a single number. - The -\emph on -seq -\emph default - variable is a pointer to a structure with members ptr and len. - On successful return, -\emph on -seq -\emph default -->ptr contains a pointer to memory that must be freed to avoid a memory - leak. - The restriction on memory size allows this converter to be conveniently - used for sequences intended to be interpreted as array shapes. - -\end_layout - -\begin_layout Description -PyArray_BufferConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -PyArray_Chunk* -\family default - buf) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any Python object, -\emph on -obj -\emph default -, with a (single-segment) buffer interface to a variable with members that - detail the object's use of its chunk of memory. - The -\emph on -buf -\emph default - variable is a pointer to a structure with base, ptr, len, and flags members. - The -\family typewriter -PyArray_Chunk -\family default - structure is binary compatibile with the Python's buffer object (through - its len member on 32-bit platforms and its ptr member on 64-bit platforms - or in Python 2.5). - On return, the base member is set to -\emph on -obj -\emph default - (or its base if -\emph on -obj -\emph default - is already a buffer object pointing to another object). - If you need to hold on to the memory be sure to INCREF the base member. - The chunk of memory is pointed to by -\emph on -buf -\emph default -->ptr member and has length -\emph on -buf -\emph default -->len. - The flags member of -\emph on -buf -\emph default - is -\family typewriter -NPY_BEHAVED_RO -\family default - with the -\family typewriter -NPY_WRITEABLE -\family default - flag set if -\emph on -obj -\emph default - has a writeable buffer interface. - -\end_layout - -\begin_layout Description -PyArray_AxisConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject -\family default -* obj, -\family typewriter -int* -\family default - axis) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert a Python object, -\emph on -obj -\emph default -, representing an axis argument to the proper value for passing to the functions - that take an integer axis. - Specifically, if -\emph on -obj -\emph default - is None, -\emph on -axis -\emph default - is set to -\family typewriter -NPY_MAXDIMS -\family default - which is interpreted correctly by the C-API functions that take axis arguments. -\end_layout - -\begin_layout Description -PyArray_BoolConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -Bool* -\family default - value) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any Python object, -\emph on -obj -\emph default -, to -\family typewriter -NPY_TRUE -\family default - or -\family typewriter -NPY_FALSE -\family default -, and place the result in -\emph on -value -\emph default -. -\end_layout - -\begin_layout Description -PyArray_ByteorderConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -char* -\family default - endian) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert Python strings into the corresponding byte-order character: '>', - '<', 's', '=', or '|'. - -\end_layout - -\begin_layout Description -PyArray_SortkindConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -NPY_SORTKIND* -\family default - sort) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert Python strings into one of -\family typewriter -NPY_QUICKSORT -\family default - (starts with 'q' or 'Q') , -\family typewriter -NPY_HEAPSORT -\family default - (starts with 'h' or 'H'), or -\family typewriter -NPY_MERGESORT -\family default - (starts with 'm' or 'M'). - -\end_layout - -\begin_layout Description -PyArray_SearchsideConverter ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -NPY_SEARCHSIDE* -\family default - side) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert Python strings into one of -\family typewriter -NPY_SEARCHLEFT -\family default - (starts with 'l' or 'L'), or -\family typewriter -NPY_SEARCHRIGHT -\family default - (starts with 'r' or 'R'). - -\end_layout - -\begin_layout Subsubsection -Other conversions -\end_layout - -\begin_layout Description -PyArray_PyIntAsInt ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert all kinds of Python objects (including arrays and array scalars) - to a standard integer. - On error, -1 is returned and an exception set. - You may find useful the macro: -\end_layout - -\begin_layout LyX-Code -#define error_converting(x) (((x) == -1) && PyErr_Occurred() -\end_layout - -\begin_layout Description -PyArray_PyIntAsIntp ( -\family typewriter -npy_intp -\family default -) ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert all kinds of Python objects (including arrays and array scalars) - to a (platform-pointer-sized) integer. - On error, -1 is returned and an exception set. - -\end_layout - -\begin_layout Description -PyArray_IntpFromSequence ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - seq, -\family typewriter -npy_intp* -\family default - vals, -\family typewriter -int -\family default - maxvals) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert any Python sequence (or single Python number) passed in as -\emph on -seq -\emph default - to (up to) -\emph on -maxvals -\emph default - pointer-sized integers and place them in the -\emph on -vals -\emph default - array. - The sequence can be smaller then -\emph on -maxvals -\emph default - as the number of converted objects is returned. - -\end_layout - -\begin_layout Description -PyArray_TypestrConvert ( -\family typewriter -int -\family default -) ( -\family typewriter -int -\family default - itemsize, -\family typewriter -int -\family default - gentype) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Convert typestring characters (with -\emph on -itemsize -\emph default -) to basic enumerated data types. - The typestring character corresponding to signed and unsigned integers, - floating point numbers, and complex-floating point numbers are recognized - and converted. - Other values of gentype are returned. - This function can be used to convert, for example, the string 'f4' to -\family typewriter -NPY_FLOAT32 -\family default -. - -\end_layout - -\begin_layout Subsection -Miscellaneous -\end_layout - -\begin_layout Subsubsection -Importing the API -\end_layout - -\begin_layout Standard -In order to make use of the C-API from another extension module, the -\family typewriter -import_array -\family default -() command must be used. - If the extension module is self-contained in a single .c file, then that - is all that needs to be done. - If, however, the extension module involves multiple files where the C-API - is needed then some additional steps must be taken. -\end_layout - -\begin_layout Description -import_array (void) (void) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function must be called in the initialization section of a module - that will make use of the C-API. - It imports the module where the function-pointer table is stored and points - the correct variable to it. - -\end_layout - -\begin_layout Description -PY_ARRAY_UNIQUE_SYMBOL -\end_layout - -\begin_layout Description -NO_IMPORT_ARRAY -\end_layout - -\begin_layout Description -\InsetSpace ~ - Using these #defines you can use the C-API in multiple files for a single - extension module. - In each file you must define -\family typewriter -PY_ARRAY_UNIQUE_SYMBOL -\family default - to some name that will hold the C-API ( -\emph on -e.g. - -\emph default - myextension_ARRAY_API). - This must be done -\series bold -before -\series default - including the numpy/arrayobject.h file. - In the module intialization routine you call -\family typewriter -import_array -\family default -(). - In addition, in the files that do not have the module initialization sub_routin -e define -\family typewriter -NO_IMPORT_ARRAY -\family default - prior to including numpy/arrayobject.h. -\end_layout - -\begin_layout Description -\InsetSpace ~ - Suppose I have two files coolmodule.c and coolhelper.c which need to be compiled - and linked into a single extension module. - Suppose coolmodule.c contains the required initcool module initialization - function (with the import_array() function called). - Then, coolmodule.c would have at the top: -\end_layout - -\begin_layout LyX-Code -#define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API -\end_layout - -\begin_layout LyX-Code -#include numpy/arrayobject.h -\end_layout - -\begin_layout Description -\InsetSpace ~ - On the other hand, coolhelper.c would contain at the top: -\end_layout - -\begin_layout LyX-Code -#define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API -\end_layout - -\begin_layout LyX-Code -#define NO_IMPORT_ARRAY -\end_layout - -\begin_layout LyX-Code -#include numpy/arrayobject.h -\end_layout - -\begin_layout Description -PyArray_GetNDArrayCVersion ( -\family typewriter -unsigned -\family default - -\family typewriter -int -\family default -) ( -\family typewriter -void -\family default -) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This just returns the value -\family typewriter -NPY_VERSION -\family default -. - Because it is in the C-API, however, comparing the output of this function - from the value defined in the current header gives a way to test if the - C-API has changed thus requiring a re-compilation of extension modules - that use the C-API. - -\end_layout - -\begin_layout Subsubsection -Internal Flexibility -\end_layout - -\begin_layout Description -PyArray_SetNumericOps ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - dict) -\end_layout - -\begin_layout Description -\InsetSpace ~ - NumPy stores an internal table of Python callable objects that are used - to implement arithmetic operations for arrays as well as certain array - calculation methods. - This function allows the user to replace any or all of these Python objects - with their own versions. - The keys of the dictionary, -\emph on -dict -\emph default -, are the named functions to replace and the paired value is the Python - callable object to use. - Care should be taken that the function used to replace an internal array - operation does not itself call back to that internal array operation (unless - you have designed the function to handle that), or an unchecked infinite - recursion can result (possibly causing program crash). - The key names that represent operations that can be replaced are: -\end_layout - -\begin_layout Quote - -\series bold -add -\series default -, -\series bold -subtract -\series default -, -\series bold -multiply -\series default -, -\series bold -divide -\series default -, -\series bold -remainder -\series default -, -\series bold -power -\series default -, -\series bold -square, reciprocal, ones_like, sqrt -\series default -, -\series bold -negative -\series default -, -\series bold -absolute -\series default -, -\series bold -invert -\series default -, -\series bold -left_shift -\series default -, -\series bold -right_shift -\series default -, -\series bold -bitwise_and -\series default -, -\series bold -bitwise_xor -\series default -, -\series bold -bitwise_or -\series default -, -\series bold -less -\series default -, -\series bold -less_equal -\series default -, -\series bold -equal -\series default -, -\series bold -not_equal -\series default -, -\series bold -greater -\series default -, -\series bold -greater_equal -\series default -, -\series bold -floor_divide -\series default -, -\series bold -true_divide -\series default -, -\series bold -logical_or -\series default -, -\series bold -logical_and -\series default -, -\series bold -floor -\series default -, -\series bold -ceil -\series default -, -\series bold -maximum -\series default -, -\series bold -minimum -\series default -, -\series bold -rint -\series default -. -\end_layout - -\begin_layout Description -\InsetSpace ~ - These functions are included here because they are used at least once in - the array object's methods. - The function returns -1 (without setting a Python Error) if one of the - objects being assigned is not callable. -\end_layout - -\begin_layout Description -PyArray_GetNumericOps ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -void -\family default -) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return a Python dictionary containing the callable Python objects stored - in the the internal arithmetic operation table. - The keys of this dictionary are given in the explanation for -\family typewriter -PyArray_SetNumericOps -\family default -. -\end_layout - -\begin_layout Description -PyArray_SetStringFunction ( -\family typewriter -void -\family default -) ( -\family typewriter -PyObject* -\family default - op, -\family typewriter -int -\family default - repr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function allows you to alter the tp_str and tp_repr methods of the - array object to any Python function. - Thus you can alter what happens for all arrays when str(arr) or repr(arr) - is called from Python. - The function to be called is passed in as -\emph on -op -\emph default -. - If -\emph on -repr -\emph default - is non-zero, then this function will be called in response to repr(arr), - otherwise the function will be called in response to str(arr). - No check on whether or not -\emph on -op -\emph default - is callable is performed. - The callable passed in to -\emph on -op -\emph default - should expect an array argument and should return a string to be printed. -\end_layout - -\begin_layout Subsubsection -Memory management -\end_layout - -\begin_layout Description -PyDataMem_NEW ( -\family typewriter -char* -\family default -) ( -\family typewriter -size_t -\family default - nbytes) -\end_layout - -\begin_layout Description -PyDataMem_FREE ( -\family typewriter -char* -\family default - ptr) -\end_layout - -\begin_layout Description -PyDataMem_RENEW ( -\family typewriter -char* -\family default -) ( -\family typewriter -void * -\family default - ptr, -\family typewriter -size_t -\family default - newbytes) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Macros to allocate, free, and reallocate memory. - These macros are used internally to create arrays. -\end_layout - -\begin_layout Description -PyDimMem_NEW ( -\family typewriter -npy_intp* -\family default -) (nd) -\end_layout - -\begin_layout Description -PyDimMem_FREE ( -\family typewriter -npy_intp* -\family default - ptr) -\end_layout - -\begin_layout Description -PyDimMem_RENEW ( -\family typewriter -npy_intp* -\family default -) ( -\family typewriter -npy_intp* -\family default - ptr, -\family typewriter -npy_intp -\family default - newnd) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Macros to allocate, free, and reallocate dimension and strides memory. -\end_layout - -\begin_layout Description -PyArray_malloc (nbytes) -\end_layout - -\begin_layout Description -PyArray_free (ptr) -\end_layout - -\begin_layout Description -PyArray_realloc (ptr, nbytes) -\end_layout - -\begin_layout Description -\InsetSpace ~ - These macros use different memory allocators, depending on the constant - -\family typewriter -NPY_USE_PYMEM -\family default -. - The system malloc is used when NPY_USE_PYMEM is 0, if NPY_USE_PYMEM is - 1, then the Python memory allocator is used. - -\end_layout - -\begin_layout Subsubsection -Threading support -\end_layout - -\begin_layout Standard -These macros are only meaningful if -\family typewriter -NPY_ALLOW_THREADS -\family default - evaluates True during compilation of the extension module. - Otherwise, these macros are equivalent to whitespace. - Python uses a single Global Interpreter Lock (GIL) for each Python process - so that only a single thread may excecute at a time (even on multi-cpu - machines). - When calling out to a compiled function that may take time to compute (and - does not have side-effects for other threads like updated global variables), - the GIL should be released so that other Python threads can run while the - time-consuming calculations are performed. - This can be accomplished using two groups of macros. - Typically, if one macro in a group is used in a code block, all of them - must be used in the same code block. - Currently, -\family typewriter -NPY_ALLOW_THREADS -\family default - is defined to the python-defined -\family typewriter -WITH_THREADS -\family default - constant unless the environment variable -\family typewriter -NPY_NOSMP -\family default - is set in which case -\family typewriter -NPY_ALLOW_THREADS -\family default - is defined to be 0. - -\end_layout - -\begin_layout Description -Group\InsetSpace ~ -1 This group is used to call code that may take some time but does - not use any Python C-API calls. - Thus, the GIL should be released during its calculation. -\end_layout - -\begin_deeper -\begin_layout Description -NPY_BEGIN_ALLOW_THREADS Equivalent to -\family typewriter -Py_BEGIN_ALLOW_THREADS -\family default - except it uses -\family typewriter -NPY_ALLOW_THREADS -\family default - to determine if the macro if replaced with white-space or not. - -\end_layout - -\begin_layout Description -NPY_END_ALLOW_THREADS Equivalent to -\family typewriter -Py_END_ALLOW_THREADS -\family default - except it uses -\family typewriter -NPY_ALLOW_THREADS -\family default - to determine if the macro if replaced with white-space or not. - -\end_layout - -\begin_layout Description -NPY_BEGIN_THREADS_DEF Place in the variable declaration area. - This macro sets up the variable needed for storing the Python state. -\end_layout - -\begin_layout Description -NPY_BEGIN_THREADS Place right before code that does not need the Python - interpreter (no Python C-API calls). - This macro saves the Python state and releases the GIL. -\end_layout - -\begin_layout Description -NPY_END_THREADS Place right after code that does not need the Python interpreter. - This macro acquires the GIL and restores the Python state from the saved - variable. -\end_layout - -\begin_layout Description -NPY_BEGIN_THREADS_DESCR ( -\family typewriter -PyArray_Descr* -\family default - dtype) Useful to release the GIL only if -\emph on -dtype -\emph default - does not contain arbitrary Python objects which may need the Python interpreter - during execution of the loop. - Equivalent to -\end_layout - -\begin_layout Description -NPY_END_THREADS_DESCR ( -\family typewriter -PyArray_Descr* -\family default - dtype) Useful to regain the GIL in situations where it was released using - the BEGIN form of this macro. - -\end_layout - -\end_deeper -\begin_layout Description -Group\InsetSpace ~ -2 This group is used to re-acquire the Python GIL after it has been - released. - For example, suppose the GIL has been released (using the previous calls), - and then some path in the code (perhaps in a different subroutine) requires - use of the Python C-API, then these macros are useful to acquire the GIL. - These macros accomplish essentially a reverse of the previous three (acquire - the LOCK saving what state it had) and then re-release it with the saved - state. -\end_layout - -\begin_deeper -\begin_layout Description -NPY_ALLOW_C_API_DEF Place in the variable declaration area to set up the - necessary variable. - -\end_layout - -\begin_layout Description -NPY_ALLOW_C_API Place before code that needs to call the Python C-API (when - it is known that the GIL has already been released). - -\end_layout - -\begin_layout Description -NPY_DISABLE_C_API Place after code that needs to call the Python C-API (to - re-release the GIL). - -\end_layout - -\end_deeper -\begin_layout Tip -Never use semicolons after the threading support macros. -\end_layout - -\begin_layout Subsubsection -Priority -\end_layout - -\begin_layout Description -NPY_PRIOIRTY Default priority for arrays. -\end_layout - -\begin_layout Description -NPY_SUBTYPE_PRIORITY Default subtype priority. -\end_layout - -\begin_layout Description -NPY_SCALAR_PRIORITY Default scalar priority (very small) -\end_layout - -\begin_layout Description -PyArray_GetPriority ( -\family typewriter -double -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -double -\family default - def) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return the -\series bold -__array_priority__ -\series default - attribute (converted to a double) of -\emph on -obj -\emph default - or -\emph on -def -\emph default - if no attribute of that name exists. - Fast returns that avoid the attribute lookup are provided for objects of - type -\family typewriter -PyArray_Type -\family default -. - -\end_layout - -\begin_layout Subsubsection -Default buffers -\end_layout - -\begin_layout Description -NPY_BUFSIZE Default size of the user-settable internal buffers. -\end_layout - -\begin_layout Description -NPY_MIN_BUFSIZE Smallest size of user-settable internal buffers. -\end_layout - -\begin_layout Description -NPY_MAX_BUFSIZE Largest size allowed for the user-settable buffers. -\end_layout - -\begin_layout Subsubsection -Other constants -\end_layout - -\begin_layout Description -NPY_NUM_FLOATTYPE The number of floating-point types -\end_layout - -\begin_layout Description -NPY_MAXDIMS The maximum number of dimensions allowed in arrays. -\end_layout - -\begin_layout Description -NPY_VERSION The current version of the ndarray object (check to see if this - variable is defined to guarantee the numpy/arrayobject.h header is being - used). - -\end_layout - -\begin_layout Description -NPY_FALSE Defined as 0 for use with Bool. -\end_layout - -\begin_layout Description -NPY_TRUE Defined as 1 for use with Bool. -\end_layout - -\begin_layout Description -NPY_FAIL The return value of failed converter functions which are called - using the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - syntax in PyArg_ParseTuple-like functions. -\end_layout - -\begin_layout Description -NPY_SUCCEED The return value of successful converter functions which are - called using the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - syntax in PyArg_ParseTuple-like functions. -\end_layout - -\begin_layout Subsubsection -Miscellaneous Macros -\end_layout - -\begin_layout Description -PyArray_SAMESHAPE (a1, a2) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Evaluates as True if arrays -\emph on -a1 -\emph default - and -\emph on -a2 -\emph default - have the same shape. - -\end_layout - -\begin_layout Description -PyArray_MAX (a,b) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns the maximum of -\emph on -a -\emph default - and -\emph on -b -\emph default -. - If ( -\emph on -a -\emph default -) or ( -\emph on -b -\emph default -) are expressions they are evaluated twice. -\end_layout - -\begin_layout Description -PyArray_MIN (a,b) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns the minimum of -\emph on -a -\emph default - and -\emph on -b -\emph default -. - If ( -\emph on -a -\emph default -) or ( -\emph on -b -\emph default -) are expressions they are evaluated twice. -\end_layout - -\begin_layout Description -PyArray_CLT (a,b) -\end_layout - -\begin_layout Description -PyArray_CGT (a,b) -\end_layout - -\begin_layout Description -PyArray_CLE (a,b) -\end_layout - -\begin_layout Description -PyArray_CGE (a,b) -\end_layout - -\begin_layout Description -PyArray_CEQ (a,b) -\end_layout - -\begin_layout Description -PyArray_CNE (a,b) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Implements the complex comparisons between two complex numbers (structures - with a real and imag member) using NumPy's definition of the ordering which - is lexicographic: comparing the real parts first and then the complex parts - if the real parts are equal. - -\end_layout - -\begin_layout Description -PyArray_REFCOUNT ( -\family typewriter -PyObject* -\family default - op) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Returns the reference count of any Python object. - -\end_layout - -\begin_layout Description -PyArray_XDECREF_ERR (PyObject *obj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - DECREF's an array object which may have the -\family typewriter -NPY_UPDATEIFCOPY -\family default - flag set without causing the contents to be copied back into the original - array. - Resets the -\family typewriter -NPY_WRITEABLE -\family default - flag on the base object. - This is useful for recovering from an error condition when -\family typewriter -NPY_UPDATEIFCOPY -\family default - is used. - -\end_layout - -\begin_layout Subsubsection -Enumerated Types -\end_layout - -\begin_layout Description -NPY_SORTKIND A special variable-type which can take on the values -\series bold -NPY_ -\series default -<KIND> where <KIND> is -\end_layout - -\begin_layout Quote - -\series bold -QUICKSORT -\series default -, -\series bold -HEAPSORT -\series default -, -\series bold -MERGESORT -\end_layout - -\begin_layout Description -\InsetSpace ~ - -\series bold -NPY_NSORTS -\series default - is defined to be the number of sorts. -\end_layout - -\begin_layout Description -NPY_SCALARKIND A special variable type indicating the number of -\begin_inset Quotes eld -\end_inset - -kinds -\begin_inset Quotes erd -\end_inset - - of scalars distinguished in determining scalar-coercion rules. - This variable can take on the values NPY_<KIND> where <KIND> can be -\end_layout - -\begin_layout Quote - -\series bold -NOSCALAR -\series default -, -\series bold -BOOL_SCALAR -\series default -, -\series bold -INTPOS_SCALAR -\series default -, -\series bold -INTNEG_SCALAR -\series default -, -\series bold -FLOAT_SCALAR -\series default -, -\series bold -COMPLEX_SCALAR -\series default -, -\series bold -OBJECT_SCALAR -\end_layout - -\begin_layout Description -\InsetSpace ~ - -\series bold -NPY_NSCALARKINDS -\series default - is defined to be the number of scalar kinds (not including -\family typewriter -NPY_NOSCALAR -\family default -). - -\end_layout - -\begin_layout Description -NPY_ORDER A variable type indicating the order that an array should be interpret -ed in. - The value of a variable of this type can be -\series bold -NPY_ -\series default -<ORDER> where <ORDER> is -\end_layout - -\begin_layout Quote - -\series bold -ANYORDER -\series default -, -\series bold -CORDER -\series default -, -\series bold -FORTRANORDER -\end_layout - -\begin_layout Description -NPY_CLIPMODE A variable type indicating the kind of clipping that should - be applied in certain functions. - The value of a variable of this type can be -\series bold -NPY_ -\series default -<MODE> where <MODE> is -\end_layout - -\begin_layout Quote - -\series bold -CLIP -\series default -, -\series bold -WRAP -\series default -, -\series bold -RAISE -\begin_inset LatexCommand index -name "ndarray!C-API|)" - -\end_inset - - -\begin_inset LatexCommand index -name "C-API!array|)" - -\end_inset - - -\end_layout - -\begin_layout Section -UFunc API -\begin_inset LatexCommand index -name "ufunc!C-API|(" - -\end_inset - - -\begin_inset LatexCommand index -name "C-API!ufunc|(" - -\end_inset - - -\end_layout - -\begin_layout Subsection -Constants -\end_layout - -\begin_layout Description -UFUNC_ERR_<HANDLER> -\end_layout - -\begin_layout Description -\InsetSpace ~ - <HANDLER> can be -\series bold -IGNORE -\series default -, -\series bold -WARN -\series default -, -\series bold -RAISE -\series default -, or -\series bold -CALL -\end_layout - -\begin_layout Description -UFUNC_<THING>_<ERR> -\end_layout - -\begin_layout Description -\InsetSpace ~ - <THING> can be -\series bold -MASK -\series default -, -\series bold -SHIFT -\series default -, or -\series bold -FPE -\series default -, and <ERR> can be -\series bold -DIVIDEBYZERO -\series default -, -\series bold -OVERFLOW -\series default -, -\series bold -UNDERFLOW -\series default -, and -\series bold -INVALID -\series default -. -\end_layout - -\begin_layout Description -PyUFunc_<VALUE> <VALUE> can be -\series bold -One -\series default - (1), -\series bold -Zero -\series default - (0), or -\series bold -None -\series default - (-1) -\end_layout - -\begin_layout Subsection -Macros -\end_layout - -\begin_layout Description -NPY_LOOP_BEGIN_THREADS -\end_layout - -\begin_layout Description -\InsetSpace ~ - Used in universal function code to only release the Python GIL if loop->obj - is not true ( -\emph on -i.e. - -\emph default - this is not an OBJECT array loop). - Requires use of -\family typewriter -NPY_BEGIN_THREADS_DEF -\family default - in variable declaration area. -\end_layout - -\begin_layout Description -NPY_LOOP_END_THREADS -\end_layout - -\begin_layout Description -\InsetSpace ~ - Used in universal function code to re-acquire the Python GIL if it was - released (because loop->obj was not true). - -\end_layout - -\begin_layout Description -UFUNC_CHECK_ERROR (loop) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A macro used internally to check for errors and goto fail if found. - This macro requires a fail label in the current code block. - The -\emph on -loop -\emph default - variable must have at least members (obj, errormask, and errorobj). - If -\emph on -loop -\emph default -->obj is nonzero, then -\family typewriter -PyErr_Occurred -\family default -() is called (meaning the GIL must be held). - If -\emph on -loop -\emph default -->obj is zero, then if -\emph on -loop -\emph default -->errormask is nonzero, -\family typewriter -PyUFunc_checkfperr -\family default - is called with arguments -\emph on -loop -\emph default -->errormask and -\emph on -loop -\emph default -->errobj. - If the result of this check of the IEEE floating point registers is true - then the code redirects to the fail label which must be defined. -\end_layout - -\begin_layout Description -UFUNC_CHECK_STATUS ( -\emph on -ret -\emph default -) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A macro that expands to platform-dependent code. - The -\emph on -ret -\emph default - variable can can be any integer. - The -\family typewriter -UFUNC_FPE_ -\family default -<ERR> bits are set in -\emph on -ret -\emph default - according to the status of the corresponding error flags of the floating - point processor. - -\end_layout - -\begin_layout Subsection -Functions -\end_layout - -\begin_layout Description -PyUFunc_FromFuncAndData ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyUFuncGenericFunction* -\family default - func, -\family typewriter -void** -\family default - data, -\family typewriter -char* -\family default - types, -\family typewriter -int -\family default - ntypes, -\family typewriter -int -\family default - nin, -\family typewriter -int -\family default - nout, -\family typewriter -int -\family default - identity, -\family typewriter -char* -\family default - name, -\family typewriter -char* -\family default - doc, -\family typewriter -int -\family default - check_return) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Create a new broadcasting universal function from required variables. - Each ufunc builds around the notion of an element-by-element operation. - Each ufunc object contains pointers to 1-d loops implementing the basic - functionality for each supported type. - -\end_layout - -\begin_layout Description -nin The number of inputs to this operation. -\end_layout - -\begin_layout Description -nout The number of outputs -\end_layout - -\begin_layout Description -ntypes How many different data-type -\begin_inset Quotes eld -\end_inset - -signatures -\begin_inset Quotes erd -\end_inset - - the ufunc has implemented. - -\end_layout - -\begin_layout Description -func Must to an array of length -\emph on -ntypes -\emph default - containing -\family typewriter -PyUFuncGenericFunction -\family default - items. - These items are pointers to functions that acutally implement the underlying - (element-by-element) function -\begin_inset Formula $N$ -\end_inset - - times. - T -\end_layout - -\begin_layout Description -types Must be of length ( -\emph on -nin -\emph default -+ -\emph on -nout -\emph default -) -\emph on -*ntypes -\emph default -, and it contains the data-types (built-in only) that the corresponding - function in the -\emph on -func -\emph default - array can deal with. - -\end_layout - -\begin_layout Description -data Should be -\family typewriter -NULL -\family default - or a pointer to an array of size -\emph on -ntypes -\emph default -. - This array may contain arbitrary extra-data to be passed to the corresponding - 1-d loop function in the func array. - -\end_layout - -\begin_layout Description -name The name for the ufunc. - -\end_layout - -\begin_layout Description -doc Allows passing in a documentation string to be stored with the ufunc. - The documentation string should not contain the name of the function or - the calling signature as that will be dynamically determined from the object - and available when accessing the -\series bold -__doc__ -\series default - attribute of the ufunc. - -\end_layout - -\begin_layout Description -check_return Unused and present for backwards compatibility of the C-API. - A corresponding -\emph on -check_return -\emph default - integer does exist in the ufunc structure and it does get set with this - value when the ufunc object is created. - -\end_layout - -\begin_layout Description -PyUFunc_RegisterLoopForType ( -\family typewriter -int -\family default -) ( -\family typewriter -PyUFuncObject* -\family default - ufunc, -\family typewriter -int -\family default - usertype, -\family typewriter -PyUFuncGenericFunction -\family default - function, -\family typewriter -int* -\family default - arg_types, -\family typewriter -void* -\family default - data) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function allows the user to register a 1-d loop with an already-created - ufunc to be used whenever the ufunc is called with any of its input arguments - as the user-defined data-type. - This is needed in order to make ufuncs work with built-in data-types. - The data-type must have been previously registered with the numpy system. - The loop is passed in as -\emph on -function -\emph default -. - This loop can take arbitrary data which should be passed in as -\emph on -data -\emph default -. - The data-types the loop requires are passed in as -\emph on -arg_types -\emph default - which must be a pointer to memory at least as large as ufunc->nargs. -\end_layout - -\begin_layout Description -PyUFunc_ReplaceLoopBySignature ( -\family typewriter -int -\family default -) ( -\family typewriter -PyUFuncObject* -\family default - ufunc, -\family typewriter -PyUFuncGenericFunction -\family default - newfunc, -\family typewriter -int* -\family default - signature, -\family typewriter -PyUFuncGenericFunction* -\family default - oldfunc) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Replace a 1-d loop matching the given -\emph on -signature -\emph default - in the already-created -\emph on -ufunc -\emph default - with the new 1-d loop newfunc. - Return the old 1-d loop function in -\emph on -oldfunc -\emph default -. - Return 0 on success and -1 on failure. - This function works only with built-in types (use -\family typewriter -PyUFunc_RegisterLoopForType -\family default - for user-defined types). - A signature is an array of data-type numbers indicating the inputs followed - by the outputs assumed by the 1-d loop. - -\end_layout - -\begin_layout Description -PyUFunc_GenericFunction ( -\family typewriter -int -\family default -) ( -\family typewriter -PyUFuncObject* -\family default - self, -\family typewriter -PyObject* -\family default - args, -\family typewriter -PyArrayObject** -\family default - mps) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A generic ufunc call. - The ufunc is passed in as -\emph on -self -\emph default -, the arguments to the ufunc as -\emph on -args -\emph default -. - The -\emph on -mps -\emph default - argument is an array of -\family typewriter -PyArrayObject -\family default - pointers containing the converted input arguments as well as the ufunc - outputs on return. - The user is responsible for managing this array and receives a new reference - for each array in -\emph on -mps -\emph default -. - The total number of arrays in -\emph on -mps -\emph default - is given by -\emph on -self -\emph default -->nin + -\emph on -self -\emph default -->nout. -\end_layout - -\begin_layout Description -PyUFunc_checkfperr ( -\family typewriter -int -\family default -) ( -\family typewriter -int -\family default - errmask, -\family typewriter -PyObject* -\family default - errobj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - A simple interface to the IEEE error-flag checking support. - The -\emph on -errmask -\emph default - argument is a mask of -\family typewriter -UFUNC_MASK_<ERR> -\family default - bitmasks indicating which errors to check for (and how to check for them). - The -\emph on -errobj -\emph default - must be a Python tuple with two elements: a string containing the name - which will be used in any communication of error and either a callable - Python object (call-back function) or -\family typewriter -Py_None -\family default -. - The callable object will only be used if -\family typewriter -UFUNC_ERR_CALL -\family default - is set as the desired error checking method. - This routine manages the GIL and is safe to call even after releasing the - GIL. - If an error in the IEEE-compatibile hardware is determined a -1 is returned, - otherwise a 0 is returned. - -\end_layout - -\begin_layout Description -PyUFunc_clearfperr ( -\family typewriter -void -\family default -) () -\end_layout - -\begin_layout Description -\InsetSpace ~ - Clear the IEEE error flags. - -\end_layout - -\begin_layout Description -PyUFunc_GetPyValues ( -\family typewriter -void -\family default -) ( -\family typewriter -char* -\family default - name, -\family typewriter -int* -\family default - bufsize, -\family typewriter -int* -\family default - errmask, -\family typewriter -PyObject** -\family default - errobj) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Get the Python values used for ufunc processing from the thread-local storage - area unless the defaults have been set in which case the name lookup is - bypassed. - The name is placed as a string in the first element of -\emph on -*errobj -\emph default -. - The second element is the looked-up function to call on error callback. - The value of the looked-up buffer-size to use is passed into -\emph on -bufsize -\emph default -, and the value of the error mask is placed into -\emph on -errmask -\emph default -. - -\end_layout - -\begin_layout Subsection -Generic functions -\end_layout - -\begin_layout Standard -At the core of every ufunc is a collection of type-specific functions that - defines the basic functionality for each of the supported types. - These functions must evaluate the underlying function -\begin_inset Formula $N\geq1$ -\end_inset - - times. - Extra-data may be passed in that may be used during the calculation. - This feature allows some general functions to be used as these basic looping - functions. - The general function has all the code needed to point variables to the - right place and set up a function call. - The general function assumes that the actual function to call is passed - in as the extra data and calls it with the correct values. - All of these functions are suitable for placing directly in the array of - functions stored in the functions member of the PyUFuncObject structure. - -\end_layout - -\begin_layout Description -PyUFunc_f_f_As_d_d ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_d_d ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_f_f ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_g_g ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_F_F_As_D_D ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_F_F ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_D_D ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_G_G ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type specific, core 1-d functions for ufuncs where each calculation is - obtained by calling a function taking one input argument and returning - one output. - This function is passed in -\family typewriter -func -\family default -. - The letters correspond to dtypechar's of the supported data types ( -\family typewriter -f -\family default - - float, -\family typewriter -d -\family default - - double, -\family typewriter -g -\family default - - long double, -\family typewriter -F -\family default - - cfloat, -\family typewriter -D -\family default - - cdouble, -\family typewriter -G -\family default - - clongdouble). - The argument -\emph on -func -\emph default - must support the same signature. - The _As_X_X variants assume ndarray's of one data type but cast the values - to use an underlying function that takes a different data type. - Thus, -\family typewriter -PyUFunc_f_f_As_d_d -\family default - uses ndarrays of data type -\family typewriter -NPY_FLOAT -\family default - but calls out to a C-function that takes double and returns double. - -\end_layout - -\begin_layout Description -PyUFunc_ff_f_As_dd_d ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_ff_f ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_dd_d ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_gg_g ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_FF_F_As_DD_D ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_DD_D ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_FF_F ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_GG_G ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Type specific, core 1-d functions for ufuncs where each calculation is - obtained by calling a function taking two input arguments and returning - one output. - The underlying function to call is passed in as -\emph on -func -\emph default -. - The letters correspond to dtypechar's of the specific data type supported - by the general-purpose function. - The argument -\family typewriter -func -\family default - must support the corresponding signature. - The -\family typewriter -_As_XX_X -\family default - variants assume ndarrays of one data type but cast the values at each iteration - of the loop to use the underlying function that takes a different data - type. - -\end_layout - -\begin_layout Description -PyUFunc_O_O ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -PyUFunc_OO_O ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - One-input, one-output, and two-input, one-output core 1-d functions for - the -\family typewriter -NPY_OBJECT -\family default - data type. - These functions handle reference count issues and return early on error. - The actual function to call is -\emph on -func -\emph default - and it must accept calls with the signature ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default -) for -\family typewriter -PyUFunc_O_O -\family default - or ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject -\family default - *, -\family typewriter -PyObject -\family default - *) for -\family typewriter -PyUFunc_OO_O -\family default -. -\end_layout - -\begin_layout Description -PyUFunc_O_O_method ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This general purpose 1-d core function assumes that -\emph on -func -\emph default - is a string representing a method of the input object. - For each iteration of the loop, the Python obejct is extracted from the - array and its -\emph on -func -\emph default - method is called returning the result to the output array. - -\end_layout - -\begin_layout Description -PyUFunc_OO_O_method ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This general purpose 1-d core function assumes that -\emph on -func -\emph default - is a string representing a method of the input object that takes one argument. - The first argument in -\emph on -args -\emph default - is the method whose function is called, the second argument in -\emph on -args -\emph default - is the argument passed to the function. - The output of the function is stored in the third entry of -\emph on -args -\emph default -. - -\end_layout - -\begin_layout Description -PyUFunc_On_Om ( -\family typewriter -void -\family default -) ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - func) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This is the 1-d core function used by the dynamic ufuncs created by umath.frompy -func(function, nin, nout). - In this case -\emph on -func -\emph default - is a pointer to a -\family typewriter -PyUFunc_PyFuncData -\family default - structure which has definition { -\family typewriter -int -\family default - nin; -\family typewriter -int -\family default - nout; -\family typewriter -PyObject* -\family default - callable}. - At each iteration of the loop, the -\emph on -nin -\emph default - input objects are exctracted from their object arrays and placed into an - argument tuple, the Python -\emph on -callable -\emph default - is called with the input arguments, and the nout outputs are placed into - their object arrays. - -\end_layout - -\begin_layout Section -Importing the API -\end_layout - -\begin_layout Description -PY_UFUNC_UNIQUE_SYMBOL -\end_layout - -\begin_layout Description -NO_IMPORT_UFUNC -\end_layout - -\begin_layout Description -import_ufunc ( -\family typewriter -void -\family default -) ( -\family typewriter -void -\family default -) -\end_layout - -\begin_layout Description -\InsetSpace ~ - These are the constants and functions for accessing the ufunc C-API from - extension modules in precisely the same way as the array C-API can be accessed. - The -\family typewriter -import_ufunc -\family default -() function must always be called (in the initialization subroutine of the - extension module). - If your extension module is in one file then that is all that is required. - The other two constants are useful if your extension module makes use of - multiple files. - In that case, define -\family typewriter -PY_UFUNC_UNIQUE_SYMBOL -\family default - to something unique to your code and then in source files that do not contain - the module initialization function but still need access to the UFUNC API, - define -\family typewriter -PY_UFUNC_UNIQUE_SYMBOL -\family default - to the same name used previously and also define -\family typewriter -NO_IMPORT_UFUNC -\family default -. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - The C-API is actually an array of function pointers. - This array is created (and pointed to by a global variable) by import_ufunc. - The global variable is either statically defined or allowed to be seen - by other files depending on the state of -\family typewriter -Py_UFUNC_UNIQUE_SYMBOL -\family default - and -\family typewriter -NO_IMPORT_UFUNC -\family default -. - -\begin_inset LatexCommand index -name "ufunc!C-API|)" - -\end_inset - - -\begin_inset LatexCommand index -name "C-API!ufunc|)" - -\end_inset - - -\end_layout - -\begin_layout Chapter -How to extend NumPy -\end_layout - -\begin_layout Quotation -That which is static and repetitive is boring. - That which is dynamic and random is confusing. - In between lies art. -\end_layout - -\begin_layout Right Address ---- -\emph on -John A. - Locke -\end_layout - -\begin_layout Quotation -Science is a differential equation. - Religion is a boundary condition. -\end_layout - -\begin_layout Right Address ---- -\emph on -Alan Turing -\end_layout - -\begin_layout Section -Writing an extension module -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand label -name "sec:Writing-an-extension" - -\end_inset - - -\begin_inset LatexCommand index -name "extension module|(" - -\end_inset - -While the ndarray object is designed to allow rapid computation in Python, - it is also designed to be general-purpose and satisfy a wide-variety of - computational needs. - As a result, if absolute speed is essential, there is no replacement for - a well-crafted, compiled loop specific to your application and hardware. - This is one of the reasons that numpy includes f2py so that an easy-to-use - mechanisms for linking (simple) C/C++ and (arbitrary) Fortran code directly - into Python are available. - You are encouraged to use and improve this mechanism. - The purpose of this section is not to document this tool but to document - the more basic steps to writing an extension module that this tool depends - on. - -\end_layout - -\begin_layout Standard -When an extension module is written, compiled, and installed to somewhere - in the Python path (sys.path), the code can then be imported into Python - as if it were a standard python file. - It will contain objects and methods that have been defined and compiled - in C code. - The basic steps for doing this in Python are well-documented and you can - find more information in the documentation for Python itself available - online at -\begin_inset LatexCommand url -name "www.python.org" -target "http://www.python.org" - -\end_inset - -. - -\end_layout - -\begin_layout Standard -In addition to the Python C-API, there is a full and rich C-API for NumPy - allowing sophisticated manipulations on a C-level. - However, for most applications, only a few API calls will typically be - used. - If all you need to do is extract a pointer to memory along with some shape - information to pass to another calculation routine, then you will use very - different calls, then if you are trying to create a new array-like type - or add a new data type for ndarrays. - This chapter documents the API calls and macros that are most commonly - used. -\end_layout - -\begin_layout Section -Required subroutine -\end_layout - -\begin_layout Standard -There is exactly one function that must be defined in your C-code in order - for Python to use it as an extension module. - The function must be called init<name> where <name> is the name of the - module from Python. - This function must be declared so that it is visible to code outside of - the routine. - Besides adding the methods and constants you desire, this subroutine must - also contain calls to import_array() and/or import_ufunc() depending on - which C-API is needed. - Forgetting to place these commands will show itself as an ugly segmentation - fault (crash) as soon as any C-API subroutine is actually called. - It is actually possible to have multiple init<name> functions in a single - file in which case multiple modules will be defined by that file. - However, there are some tricks to get that to work correctly and it is - not covered here. -\end_layout - -\begin_layout Standard -A minimal init<name> method looks like -\end_layout - -\begin_layout LyX-Code -PyMODINIT_FUNC -\newline -init<name>(void) -\newline -{ -\newline - (void)Py_InitModule( -\begin_inset Quotes erd -\end_inset - -<name> -\begin_inset Quotes erd -\end_inset - -, mymethods); -\newline - import_array(); -\newline -} -\end_layout - -\begin_layout Standard -The mymethods must be an array (usually statically declared) of PyMethodDef - structures which contain method names, actual C-functions, a variable indicatin -g whether the method uses keyword arguments or not, and docstrings. - These are explained in the next section. - If you want to add constants to the module, then you store the returned - value from Py_InitModule which is a module object. - The most general way to add itmes to the module is to get the module dictionary - using PyModule_GetDict(module). - With the module dictionary, you can add whatever you like to the module - manually. - An easier way to add objects to the module is to use one of three additional - Python C-API calls that do not require a separate extraction of the module - dictionary. - These are documented in the Python documentation, but repeated here for - convenience: -\end_layout - -\begin_layout Description -PyModule_AddObject ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - module, -\family typewriter -char* -\family default - name, -\family typewriter -PyObject* -\family default - value) -\end_layout - -\begin_layout Description -PyModule_AddIntConstant ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - module, -\family typewriter -char* -\family default - name, -\family typewriter -long -\family default - value) -\end_layout - -\begin_layout Description -PyModule_AddStringConstant ( -\family typewriter -int -\family default -) ( -\family typewriter -PyObject* -\family default - module, -\family typewriter -char* -\family default - name, -\family typewriter -char* -\family default - value) -\end_layout - -\begin_layout Description -\InsetSpace ~ - All three of these functions require the -\family typewriter -module -\family default - object (the return value of Py_InitModule). - The -\family typewriter -name -\family default - is a string that labels the value in the module. - Depending on which function is called, the -\family typewriter -value -\family default - argument is either a general object (PyModule_AddObject steals a reference - to it), an integer constant, or a string constant. -\end_layout - -\begin_layout Section -Defining functions -\end_layout - -\begin_layout Standard -The second argument passed in to the Py_InitModule function is a structure - that makes it easy to to define functions in the module. - In the example given above, the mymethods structure would have been defined - earlier in the file (usually right before the init<name> subroutine) to - -\end_layout - -\begin_layout LyX-Code -static PyMethodDef mymethods[] = { -\newline -{ -\begin_inset Quotes erd -\end_inset - -nokeywordfunc -\begin_inset Quotes erd -\end_inset - -,nokeyword_cfunc, -\newline -METH_VARARGS, -\newline - -\begin_inset Quotes erd -\end_inset - -Doc string -\begin_inset Quotes erd -\end_inset - -}, -\newline -{ -\begin_inset Quotes erd -\end_inset - -keywordfunc -\begin_inset Quotes erd -\end_inset - -, keyword_cfunc, -\end_layout - -\begin_layout LyX-Code -METH_VARARGS|METH_KEYWORDS, -\newline - -\begin_inset Quotes erd -\end_inset - -Doc string -\begin_inset Quotes erd -\end_inset - -}, -\newline -{NULL, NULL, 0, NULL} /* Sentinel */ -\newline -} -\end_layout - -\begin_layout Standard -Each entry in the mymethods array is a PyMethodDef structure containing - 1) the Python name, 2) the C-function that implements the function, 3) - flags indicating whether or not keywords are accepted for this function, - and 4) The docstring for the function. - Any number of functions may be defined for a single module by adding more - entries to this table. - The last entry must be all NULL as shown to act as a sentinel. - Python looks for this entry to know that all of the functions for the module - have been defined. - -\end_layout - -\begin_layout Standard -The last thing that must be done to finish the extension module is to actually - write the code that performs the desired functions. - There are two kinds of functions: those that don't accept keyword arguments, - and those that do. -\end_layout - -\begin_layout Subsection -Functions without keyword arguments -\end_layout - -\begin_layout Standard -Functions that don't accept keyword arguments should be written as -\end_layout - -\begin_layout LyX-Code -static PyObject* -\newline -nokeyword_cfunc (PyObject *dummy, PyObject *args) -\newline -{ -\newline - /* - convert Python arguments */ -\newline - /* do function */ -\end_layout - -\begin_layout LyX-Code - /* return something */ -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Standard -The dummy argument is not used in this context and can be safely ignored. - The -\emph on -args -\emph default - argument contains all of the arguments passed in to the function as a tuple. - You can do anything you want at this point, but usually the easiest way - to manage the input arguments is to call -\family typewriter -PyArg_ParseTuple -\family default - (args, format_string, addresses_to_C_variables...) or -\family typewriter -PyArg_UnpackTuple -\family default - (tuple, -\begin_inset Quotes eld -\end_inset - -name -\begin_inset Quotes erd -\end_inset - -, min, max, ...). - A good description of how to use the first function is contained in the - Python C-API reference manual under section 5.5 (Parsing arguments and building - values). - You should pay particular attention to the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - format which uses converter functions to go between the Python object and - the C object. - All of the other format functions can be (mostly) thought of as special - cases of this general rule. - There are several converter functions defined in the NumPy C-API that may - be of use. - In particular, the -\family typewriter -PyArray_DescrConverter -\family default - function is very useful to support arbitrary data-type specification. - This function transforms any valid data-type Python object into a -\family typewriter -PyArray_Descr* -\family default - object. - Remember to pass in the address of the C-variables that should be filled - in. -\end_layout - -\begin_layout Standard -There are lots of examples of how to use -\family typewriter -PyArg_ParseTuple -\family default - throughout the NumPy source code. - The standard usage is like this: -\end_layout - -\begin_layout LyX-Code -PyObject *input; -\end_layout - -\begin_layout LyX-Code -PyArray_Descr *dtype; -\end_layout - -\begin_layout LyX-Code -if (!PyArg_ParseTuple(args, "OO&", &input, -\newline - PyArray_DescrCon -verter, -\newline - &dtype)) return NULL; -\end_layout - -\begin_layout Standard -It is important to keep in mind that you get a -\emph on -borrowed -\emph default - reference to the object when using the -\begin_inset Quotes eld -\end_inset - -O -\begin_inset Quotes erd -\end_inset - - format string. - However, the converter functions usually require some form of memory handling. - In this example, if the conversion is successful, -\emph on -dtype -\emph default - will hold a new reference to a -\family typewriter -PyArray_Descr* -\family default - object, while -\emph on -input -\emph default - will hold a borrowed reference. - Therefore, if this conversion were mixed with another conversion (say to - an integer) and the data-type conversion was successful but the integer - conversion failed, then you would need to release the reference count to - the data-type object before returning. - A typical way to do this is to set -\emph on -dtype -\emph default - to -\family typewriter -NULL -\family default - before calling PyArg_ParseTuple and then use -\family typewriter -Py_XDECREF -\family default - on -\emph on -dtype -\emph default - before returning. - -\end_layout - -\begin_layout Standard -After the input arguments are processed, the code that actually does the - work is written (likely calling other functions as needed). - The final step of the C-function is to return something. - If an error is encountered then -\family typewriter -NULL -\family default - should be returned (making sure an error has actually been set). - If nothing should be returned then increment -\family typewriter -Py_None -\family default - and return it. - If a single object should be returned then it is returned (ensuring that - you own a reference to it first). - If multiple objects should be returned then you need to return a tuple. - The -\family typewriter -Py_BuildValue -\family default - (format_string, c_variables...) function makes it easy to build tuples of - Python objects from C variables. - Pay special attention to the difference between 'N' and 'O' in the format - string or you can easily create memory leaks. - The 'O' format string increments the reference count of the -\family typewriter -PyObject* -\family default - C-variable it corresponds to, while the 'N' format string steals a reference - to the corresponding -\family typewriter -PyObject* -\family default - C-variable. - You should use 'N' if you ave already created a reference for the object - and just want to give that reference to the tuple. - You should use 'O' if you only have a borrowed reference to an object and - need to create one to provide for the tuple. - -\end_layout - -\begin_layout Subsection -Functions with keyword arguments -\end_layout - -\begin_layout Standard -These functions are very similar to functions without keyword arguments. - The only difference is that the function signature is -\end_layout - -\begin_layout LyX-Code -static PyObject* -\newline -keyword_cfunc (PyObject *dummy, PyObject *args, PyObject - *kwds) -\newline -{ -\newline -... -\newline -} -\end_layout - -\begin_layout Standard -The kwds argument holds a Python dictionary whose keys are the names of - the keyword arguments and whose values are the corresponding keyword-argument - values. - This dictionary can be processed however you see fit. - The easiest way to handle it, however, is to replace the -\family typewriter -PyArg_ParseTuple -\family default - (args, format_string, addresses...) function with a call to -\family typewriter -PyArg_ParseTupleAndKeywords -\family default - (args, kwds, format_string, char *kwlist[], addresses...). - The kwlist parameter to this function is a -\family typewriter -NULL -\family default --terminated array of strings providing the expected keyword arguments. - There should be one string for each entry in the format_string. - Using this function will raise a TypeError if invalid keyword arguments - are passed in. - -\end_layout - -\begin_layout Standard -For more help on this function please see section 1.8 (Keyword Paramters - for Extension Functions) of the Extending and Embedding tutorial in the - Python documentation. -\end_layout - -\begin_layout Subsection -Reference counting -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "reference counting|(" - -\end_inset - -The biggest difficulty when writing extension modules is reference counting. - It is an important reason for the popularity of f2py, weave, pyrex, ctypes, - etc.... - If you mis-handle reference counts you can get problems from memory-leaks - to segmentation faults. - The only strategy I know of to handle reference counts correctly is blood, - sweat, and tears. - First, you force it into your head that every Python variable has a reference - count. - Then, you understand exactly what each function does to the reference count - of your objects, so that you can properly use DECREF and INCREF when you - need them. - Reference counting can really test the amount of patience and diligence - you have towards your programming craft. - Despite the grim depiction, most cases of reference counting are quite - straightforward with the most common difficulty being not using DECREF - on objects before exiting early from a routine due to some error. - In second place, is the common error of not owning the reference on an - object that is passed to a function or macro that is going to steal the - reference ( -\emph on -e.g. - -\emph default - -\family typewriter -PyTuple_SET_ITEM -\family default -, and most functions that take -\family typewriter -PyArray_Descr -\family default - objects). - -\end_layout - -\begin_layout Standard -Typically you get a new reference to a variable when it is created or is - the return value of some function (there are some prominent exceptions, - however --- such as getting an item out of a tuple or a dictionary). - When you own the reference, you are responsible to make sure that -\family typewriter -Py_DECREF -\family default -(var) is called when the variable is no longer necessary (and no other function - has -\begin_inset Quotes eld -\end_inset - -stolen -\begin_inset Quotes erd -\end_inset - - its reference). - Also, if you are passing a Python object to a function that will -\begin_inset Quotes eld -\end_inset - -steal -\begin_inset Quotes erd -\end_inset - - the reference, then you need to make sure you own it (or use -\family typewriter -Py_INCREF -\family default - to get your own reference). - You will also encounter the notion of borrowing a reference. - A function that borrows a reference does not alter the reference count - of the object and does not expect to -\begin_inset Quotes eld -\end_inset - -hold on -\begin_inset Quotes erd -\end_inset - - to the reference. - It's just going to use the object temporarily. - When you use -\family typewriter -PyArg_ParseTuple -\family default - or -\family typewriter -PyArg_UnpackTuple -\family default - you receive a borrowed reference to the objects in the tuple and should - not alter their reference count inside your function. - With practice, you can learn to get reference counting right, but it can - be frustrating at first. - -\end_layout - -\begin_layout Standard -One common source of reference-count errors is the -\family typewriter -Py_BuildValue -\family default - function. - Pay careful attention to the difference between the 'N' format character - and the 'O' format character. - If you create a new object in your subroutine (such as an output array), - and you are passing it back in a tuple of return values, then you should - most-likely use the 'N' format character in -\family typewriter -Py_BuildValue -\family default -. - The 'O' character will increase the reference count by one. - This will leave the caller with two reference counts for a brand-new array. - When the variable is deleted and the reference count decremented by one, - there will still be that extra reference count, and the array will never - be deallocated. - You will have a reference-counting induced memory leak. - Using the 'N' character will avoid this situation as it will return to - the caller an object (inside the tuple) with a single reference count. - -\begin_inset LatexCommand index -name "reference counting|)" - -\end_inset - - -\end_layout - -\begin_layout Section -Dealing with array objects -\end_layout - -\begin_layout Standard -Most extension modules for NumPy will need to access the memory for an ndarray - object (or one of it's sub-classes). - The easiest way to do this doesn't require you to know much about the internals - of NumPy. - The method is to -\end_layout - -\begin_layout Enumerate -Ensure you are dealing with a well-behaved array (aligned, in machine byte-order - and single-segment) of the correct type and number of dimensions. - -\end_layout - -\begin_deeper -\begin_layout Enumerate -By converting it from some Python object using -\family typewriter -PyArray_FromAny -\family default - or a macro built on it. - -\end_layout - -\begin_layout Enumerate -By constructing a new ndarray of your desired shape and type using -\family typewriter -PyArray_NewFromDescr -\family default - or a simpler macro or function based on it. - -\end_layout - -\end_deeper -\begin_layout Enumerate -Get the shape of the array and a pointer to its actual data. - -\end_layout - -\begin_layout Enumerate -Pass the data and shape information on to a subroutine or other section - of code that actually performs the computation. - -\end_layout - -\begin_layout Enumerate -If you are writing the algorithm, then I recommend that you use the stride - information contained in the array to access the elements of the array - (the -\family typewriter -PyArray_GETPTR -\family default - macros make this painless). - Then, you can relax your requirements so as not to force a single-segment - array and the data-copying that might result. - -\end_layout - -\begin_layout Standard -Each of these sub-topics is covered in the following sub-sections. -\end_layout - -\begin_layout Subsection -Converting an arbitrary sequence object -\end_layout - -\begin_layout Standard -The main routine for obtaining an array from any Python object that can - be converted to an array is -\family typewriter -PyArray_FromAny -\family default -. - This function is very flexible with many input arguments. - Several macros make it easier to use the basic function. - -\family typewriter -PyArray_FROM_OTF -\family default - is arguably the most useful of these macros for the most common uses. - It allows you to convert an arbitrary Python object to an array of a specific - builtin data-type ( -\emph on -e.g. - -\emph default - float), while specifying a particular set of requirements ( -\emph on -e.g. - -\emph default - contiguous, aligned, and writeable). - The syntax is -\end_layout - -\begin_layout Description -PyArray_FROM_OTF ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyObject* -\family default - obj, -\family typewriter -int -\family default - typenum, -\family typewriter -int -\family default - requirements) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Return an ndarray from any Python object, -\emph on -obj -\emph default -, that can be converted to an array. - The number of dimensions in the returned array is determined by the object. - The desired data-type of the returned array is provided in -\emph on -typenum -\emph default - which should be one of the enumerated types. - The -\emph on -requirements -\emph default - for the returned array can be any combination of standard array flags. - Each of these arguments is explained in more detail below. - You receive a new reference to the array on success. - On failure, -\family typewriter -NULL -\family default - is returned and an exception is set. - -\end_layout - -\begin_deeper -\begin_layout Description -obj The object can be any Python object convertable to an ndarray. - If the object is already (a subclass of) the ndarray that satisfies the - requirements then a new reference is returned. - Otherwise, a new array is constructed. - The contents of -\emph on -obj -\emph default - are copied to the new array unless the array interface is used so that - data does not have to be copied. - Objects that can be converted to an array include: 1) any nested sequence - object, 2) any object exposing the array interface, 3) any object with - an -\series bold -__array__ -\series default - method (which should return an ndarray), and 4) any scalar object (becomes - a zero-dimensional array). - Sub-classes of the ndarray that otherwise fit the requirements will be - passed through. - If you want to ensure a base-class ndarray, then use -\family typewriter -NPY_ENSUREARRAY -\family default - in the requirements flag. - A copy is made only if necessary. - If you want to guarantee a copy, then pass in -\family typewriter -NPY_ENSURECOPY -\family default - to the requirements flag. - -\end_layout - -\begin_layout Description -typenum One of the enumerated types or -\family typewriter -NPY_NOTYPE -\family default - if the data-type should be determined from the object itself. - The C-based names can be used: -\end_layout - -\begin_deeper -\begin_layout Quote - -\family typewriter -NPY_BOOL -\family default -, -\family typewriter -NPY_BYTE -\family default -, -\family typewriter -NPY_UBYTE -\family default -, -\family typewriter -NPY_SHORT -\family default -, -\family typewriter -NPY_USHORT -\family default -, -\family typewriter -NPY_INT -\family default -, -\family typewriter -NPY_UINT -\family default -, -\family typewriter -NPY_LONG -\family default -, -\family typewriter -NPY_ULONG -\family default -, -\family typewriter -NPY_LONGLONG -\family default -, -\family typewriter -NPY_ULONGLONG -\family default -, -\family typewriter -NPY_DOUBLE -\family default -, -\family typewriter -NPY_LONGDOUBLE -\family default -, -\family typewriter -NPY_CFLOAT -\family default -, -\family typewriter -NPY_CDOUBLE -\family default -, -\family typewriter -NPY_CLONGDOUBLE -\family default -, -\family typewriter -NPY_OBJECT -\family default -. - -\end_layout - -\end_deeper -\begin_layout Description -\InsetSpace ~ - Alternatively, the bit-width names can be used as supported on the platform. - For example: -\end_layout - -\begin_deeper -\begin_layout Quote - -\family typewriter -NPY_INT8 -\family default -, -\family typewriter -NPY_INT16 -\family default -, -\family typewriter -NPY_INT32 -\family default -, -\family typewriter -NPY_INT64 -\family default -, -\family typewriter -NPY_UINT8 -\family default -, -\family typewriter -NPY_UINT16 -\family default -, -\family typewriter -NPY_UINT32 -\family default -, -\family typewriter -NPY_UINT64 -\family default -, -\family typewriter -NPY_FLOAT32 -\family default -, -\family typewriter -NPY_FLOAT64 -\family default -, -\family typewriter -NPY_COMPLEX64 -\family default -, -\family typewriter -NPY_COMPLEX128 -\family default -. - -\end_layout - -\end_deeper -\begin_layout Description -\InsetSpace ~ - The object will be converted to the desired type only if it can be done - without losing precision. - Otherwise -\family typewriter -NULL -\family default - will be returned and an error raised. - Use -\family typewriter -NPY_FORCECAST -\family default - in the requirements flag to override this behavior. - -\end_layout - -\begin_layout Description -requirements The memory model for an ndarray admits arbitrary strides in - each dimension to advance to the next element of the array. - Often, however, you need to interface with code that expects a C-contiguous - or a Fortran-contiguous memory layout. - In addition, an ndarray can be misaligned (the address of an element is - not at an integral multiple of the size of the element) which can cause - your program to crash (or at least work more slowly) if you try and dereference - a pointer into the array data. - Both of these problems can be solved by converting the Python object into - an array that is more -\begin_inset Quotes eld -\end_inset - -well-behaved -\begin_inset Quotes erd -\end_inset - - for your specific usage. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - The requirements flag allows specification of what kind of array is acceptable. - If the object passed in does not satisfy this requirements then a copy - is made so that thre returned object will satisfy the requirements. - these ndarray can use a very generic pointer to memory. - This flag allows specification of the desired properties of the returned - array object. - All of the flags are explained in the detailed API chapter. - The flags most commonly needed are NPY_IN_ARRAY, NPY_OUT_ARRAY, and NPY_INOUT_A -RRAY: -\end_layout - -\begin_deeper -\begin_layout Description -NPY_IN_ARRAY Equivalent to NPY_CONTIGUOUS | NPY_ALIGNED. - This combination of flags is useful for arrays that must be in C-contiguous - order and aligned. - These kinds of arrays are usually input arrays for some algorithm. -\end_layout - -\begin_layout Description -NPY_OUT_ARRAY Equivalent to NPY_CONTIGUOUS | NPY_ALIGNED | NPY_WRITEABLE. - This combination of flags is useful to specify an array that is in C-contiguous - order, is aligned, and can be written to as well. - Such an array is usually returned as output (although normally such output - arrays are created from scratch). - -\end_layout - -\begin_layout Description -NPY_INOUT_ARRAY Equivalent to NPY_CONTIGUOUS | NPY_ALIGNED | NPY_WRITEABLE - | NPY_UPDATEIFCOPY. - This combination of flags is useful to specify an array that will be used - for both input and output. - If a copy is needed, then when the temporary is deleted (by your use of - Py_DECREF at the end of the interface routine), the temporary array will - be copied back into the original array passed in. - Use of the UPDATEIFCOPY flag requires that the input object is already - an array (because other objects cannot be automatically updated in this - fashion). - If an error occurs use -\series bold -PyArray_DECREF_ERR -\series default -(obj) on an array with the NPY_UPDATEIFCOPY flag set. - This will delete the array without causing the contents to be copied back - into the original array. - -\end_layout - -\end_deeper -\begin_layout Description -\InsetSpace ~ - Other useful flags that can be OR'd as additional requirements are: -\end_layout - -\begin_deeper -\begin_layout Description -NPY_FORCECAST Cast to the desired type, even if it can't be done without - losing information. -\end_layout - -\begin_layout Description -NPY_ENSURECOPY Make sure the resulting array is a copy of the original. -\end_layout - -\begin_layout Description -NPY_ENSUREARRAY Make sure the resulting object is an actual ndarray and - not a sub-class. -\end_layout - -\end_deeper -\end_deeper -\begin_layout Note -Whether or not an array is byte-swapped is determined by the data-type of - the array. - Native byte-order arrays are always requested by PyArray_FROM_OTF and so - there is no need for a NPY_NOTSWAPPED flag in the requirements argument. - There is also no way to get a byte-swapped array from this routine. -\end_layout - -\begin_layout Subsection -Creating a brand-new ndarray -\end_layout - -\begin_layout Standard -Quite often new arrays must be created from within extension-module code. - Perhaps an output array is needed and you don't want the caller to have - to supply it. - Perhaps only a temporary array is needed to hold an intermediate calculation. - Whatever the need there are simple ways to get an ndarray object of whatever - data-type is needed. - The most general function for doing this is PyArray_NewFromDescr. - All array creation functions go through this heavily re-used code. - Because of its flexibility, it can be somewhat confusing to use. - As a result, simpler forms exist that are easier to use. - -\end_layout - -\begin_layout Description -PyArray_SimpleNew ( -\family typewriter -PyObject* -\family default -)( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - typenum) -\end_layout - -\begin_layout Description -\InsetSpace ~ - This function allocates new memory and places it in an ndarray with -\family typewriter -nd -\family default - dimensions whose shape is determined by the array of at least -\family typewriter -nd -\family default - items pointed to by -\family typewriter -dims -\family default -. - The memory for the array is uninitialized (unless typenum is -\series bold -NPY_OBJECT -\series default - in which case each element in the array is set to NULL). - The -\family typewriter -typenum -\family default - argument allows specification of any of the builtin data-types such as - -\series bold -NPY_FLOAT -\series default - or -\series bold -NPY_LONG -\series default -. - The memory for the array can be set to zero if desired using -\series bold -PyArray_FILLWBYTE -\series default -(return_object, 0). - -\end_layout - -\begin_layout Description -PyArray_SimpleNewFromData ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -int -\family default - nd, -\family typewriter -npy_intp* -\family default - dims, -\family typewriter -int -\family default - typenum, -\family typewriter -void* -\family default - data) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Sometimes, you want to wrap memory allocated elsewhere into an ndarray - object for downstream use. - This routine makes it straightforward to do that. - The first three arguments are the same as in -\series bold -PyArray_SimpleNew -\series default -, the final argument is a pointer to a block of contiguous memory that the - ndarray should use as it's data-buffer which will be interpreted in C-style - contiguous fashion. - A new reference to an ndarray is returned, but the ndarray will not own - its data. - When this ndarray is deallocated, the pointer will not be freed. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - You should ensure that the provided memory is not freed while the returned - array is in existence. - The easiest way to handle this is if data comes from another reference-counted - Python object. - The reference count on this object should be increased after the pointer - is passed in, and the base member of the returned ndarray should point - to the Python object that owns the data. - Then, when the ndarray is deallocated, the base-member will be DECREF'd - appropriately. - If you want the memory to be freed as soon as the ndarray is deallocated - then simply set the OWNDATA flag on the returned ndarray. - -\end_layout - -\begin_layout Subsection -Getting at ndarray memory and accessing elements of the ndarray -\end_layout - -\begin_layout Standard -If obj is an ndarray (PyArrayObject *), then the data-area of the ndarray - is pointed to by the void* pointer -\series bold -PyArray_DATA -\series default -(obj) or the char* pointer -\series bold -PyArray_BYTES -\series default -(obj). - Remember that (in general) this data-area may not be aligned according - to the data-type, it may represent byte-swapped data, and/or it may not - be writeable. - If the data area is aligned and in native byte-order, then how to get at - a specific element of the array is determined only by the array of npy_intp - variables, -\series bold -PyArray_STRIDES -\series default -(obj). - In particular, this c-array of integers shows how many -\series bold -bytes -\series default - must be added to the current element pointer to get to the next element - in each dimension. - For arrays less than 4-dimensions there are -\series bold -PyArray_GETPTR<k> -\series default -(obj, ...) macros where <k> is the integer 1, 2, 3, or 4 that make using the - array strides easier. - The arguments .... - represent <k> non-negative integer indices into the array. - For example, suppose -\family typewriter -E -\family default - is a 3-dimensional ndarray. - A (void*) pointer to the element -\family typewriter -E[i,j,k] -\family default - is obtained as PyArray_GETPTR3(E, i, j, k). - -\end_layout - -\begin_layout Standard -As explained previously, C-style contiguous arrays and Fortran-style contiguous - arrays have particular striding patterns. - Two array flags (NPY_C_CONTIGUOUS and NPY_F_CONTIGUOUS) indicate whether - or not the striding pattern of a particular array matches the C-style contiguou -s or Fortran-style contiguous or neither. - Whether or not the striding pattern matches a standard C or Fortran one - can be tested Using -\family typewriter -PyArray_ISCONTIGUOUS -\family default -(obj) and -\family typewriter -PyArray_ISFORTRAN -\family default -(obj) respectively. - Most third-party libraries expect contiguous arrays. - But, often it is not difficult to support general-purpose striding. - I encourage you to use the striding information in your own code whenever - possible, and reserve single-segment requirements for wrapping third-party - code. - Using the striding information provided with the ndarray rather than requiring - a contiguous striding reduces copying that otherwise must be made. - -\end_layout - -\begin_layout Section -Example -\end_layout - -\begin_layout Standard -The following example shows how you might write a wrapper that accepts two - input arguments (that will be converted to an array) and an output argument - (that must be an array). - The function returns None and updates the output array. - -\begin_inset LatexCommand index -name "extension module|)" - -\end_inset - - -\end_layout - -\begin_layout LyX-Code -static PyObject * -\end_layout - -\begin_layout LyX-Code -example_wrapper(PyObject *dummy, PyObject *args) -\end_layout - -\begin_layout LyX-Code -{ -\end_layout - -\begin_layout LyX-Code - PyObject *arg1=NULL, *arg2=NULL, *out=NULL; -\end_layout - -\begin_layout LyX-Code - PyObject *arr1=NULL, *arr2=NULL, *oarr=NULL; -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - if (!PyArg_ParseTuple(args, -\begin_inset Quotes eld -\end_inset - -OOO& -\begin_inset Quotes erd -\end_inset - -, &arg1, *arg2, -\end_layout - -\begin_layout LyX-Code - &PyArrayType, *out)) return NULL; -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); -\end_layout - -\begin_layout LyX-Code - if (arr1 == NULL) return NULL; -\end_layout - -\begin_layout LyX-Code - arr2 = PyArray_FROM_OTF(arg2, NPY_DOUBLE, NPY_IN_ARRAY); -\end_layout - -\begin_layout LyX-Code - if (arr2 == NULL) goto fail; -\end_layout - -\begin_layout LyX-Code - oarr = PyArray_FROM_OTF(out, NPY_DOUBLE, NPY_INOUT_ARRAY); -\end_layout - -\begin_layout LyX-Code - if (oarr == NULL) goto fail; -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - /* code that makes use of arguments */ -\end_layout - -\begin_layout LyX-Code - /* You will probably need at least -\end_layout - -\begin_layout LyX-Code - nd = PyArray_NDIM(<..>) -- number of dimensions -\end_layout - -\begin_layout LyX-Code - dims = PyArray_DIMS(<..>) -- npy_intp array of length nd -\end_layout - -\begin_layout LyX-Code - showing length in each dim. -\end_layout - -\begin_layout LyX-Code - dptr = (double *)PyArray_DATA(<..>) -- pointer to data. -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - If an error occurs goto fail. -\end_layout - -\begin_layout LyX-Code - */ -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - Py_DECREF(arr1); -\end_layout - -\begin_layout LyX-Code - Py_DECREF(arr2); -\end_layout - -\begin_layout LyX-Code - Py_DECREF(oarr); -\end_layout - -\begin_layout LyX-Code - Py_INCREF(Py_None); -\end_layout - -\begin_layout LyX-Code - return Py_None; -\end_layout - -\begin_layout LyX-Code - -\end_layout - -\begin_layout LyX-Code - fail: -\end_layout - -\begin_layout LyX-Code - Py_XDECREF(arr1); -\end_layout - -\begin_layout LyX-Code - Py_XDECREF(arr2); -\end_layout - -\begin_layout LyX-Code - PyArray_XDECREF_ERR(oarr); -\end_layout - -\begin_layout LyX-Code - return NULL; -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Chapter -Beyond the Basics -\end_layout - -\begin_layout Quotation -The voyage of discovery is not in seeking new landscapes but in having new - eyes. -\end_layout - -\begin_layout Right Address ---- -\emph on -Marcel Proust -\end_layout - -\begin_layout Quotation -Discovery is seeing what everyone else has seen and thinking what no one - else has thought. -\end_layout - -\begin_layout Right Address ---- -\emph on -Albert Szent-Gyorgi -\end_layout - -\begin_layout Section -Iterating over elements in the array -\end_layout - -\begin_layout Subsection -Basic Iteration -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand label -name "sec:array_iterator" - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "array iterator|(" - -\end_inset - -One common algorithmic requirement is to be able to walk over all elements - in a multidimensional array. - The array iterator object makes this easy to do in a generic way that works - for arrays of any dimension. - Naturally, if you know the number of dimensions you will be using, then - you can always write nested for loops to accomplish the iteration. - If, however, you want to write code that works with any number of dimensions, - then you can make use of the array iterator. - An array iterator object is returned when accessing the .flat attribute - of an array. - -\end_layout - -\begin_layout Standard -Basic usage is to call -\series bold -PyArray_IterNew -\series default - ( -\family typewriter -array -\family default -) where array is an ndarray object (or one of its sub-classes). - The returned object is an array-iterator object (the same object returned - by the .flat attribute of the ndarray). - This object is usually cast to PyArrayIterObject* so that its members can - be accessed. - The only members that are needed are -\family typewriter -iter->size -\family default - which contains the total size of the array, -\family typewriter -iter->index -\family default -, which contains the current 1-d index into the array, and -\family typewriter -iter->dataptr -\family default - which is a pointer to the data for the current element of the array. - Sometimes it is also useful to access -\family typewriter -iter->ao -\family default - which is a pointer to the underlying ndarray object. - -\end_layout - -\begin_layout Standard -After processing data at the current element of the array, the next element - of the array can be obtained using the macro -\series bold -PyArray_ITER_NEXT -\series default -( -\family typewriter -iter -\family default -). - The iteration always proceeds in a C-style contiguous fashion (last index - varying the fastest). - The -\series bold -PyArray_ITER_GOTO -\series default -( -\family typewriter -iter -\family default -, -\family typewriter -destination -\family default -) can be used to jump to a particular point in the array, where -\family typewriter -destination -\family default - is an array of npy_intp data-type with space to handle at least the number - of dimensions in the underlying array. - Occasionally it is useful to use -\series bold -PyArray_ITER_GOTO1D -\series default -( -\family typewriter -iter -\family default -, -\family typewriter -index -\family default -) which will jump to the 1-d index given by the value of -\family typewriter -index -\family default -. - The most common usage, however, is given in the following example. - -\end_layout - -\begin_layout LyX-Code -PyObject *obj; /* assumed to be some ndarray object */ -\end_layout - -\begin_layout LyX-Code -PyArrayIterObject *iter; -\end_layout - -\begin_layout LyX-Code -... -\end_layout - -\begin_layout LyX-Code -iter = (PyArrayIterObject *)PyArray_IterNew(obj); -\end_layout - -\begin_layout LyX-Code -if (iter == NULL) goto fail; /* Assume fail has clean-up code */ -\end_layout - -\begin_layout LyX-Code -while (iter->index < iter->size) { -\end_layout - -\begin_layout LyX-Code - /* do something with the data at it->dataptr */ -\end_layout - -\begin_layout LyX-Code - PyArray_ITER_NEXT(it); -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout LyX-Code -... -\end_layout - -\begin_layout Standard -You can also use -\series bold -PyArrayIter_Check -\series default -( -\family typewriter -obj -\family default -) to ensure you have an iterator object and -\series bold -PyArray_ITER_RESET -\series default -( -\family typewriter -iter -\family default -) to reset an iterator object back to the beginning of the array. - -\end_layout - -\begin_layout Standard -It should be emphasized at this point that you may not need the array iterator - if your array is already contiguous (using an array iterator will work - but will be slower than the fastest code you could write). - The major purpose of array iterators is to encapsulate iteration over N-dimensi -onal arrays with arbitrary strides. - They are used in many, many places in the NumPy source code itself. - If you already know your array is contiguous (Fortran or C), then simply - adding the element-size to a running pointer variable will step you through - the array very efficiently. - In other words, code like this will probably be faster for you in the contiguou -s case (assuming doubles). - -\end_layout - -\begin_layout LyX-Code -npy_intp size; -\end_layout - -\begin_layout LyX-Code -double *dptr; /* could make this any variable type */ -\end_layout - -\begin_layout LyX-Code -size = PyArray_SIZE(obj); -\end_layout - -\begin_layout LyX-Code -dptr = PyArray_DATA(obj); -\end_layout - -\begin_layout LyX-Code -while(size--) { -\end_layout - -\begin_layout LyX-Code - /* do something with the data at dptr */ -\end_layout - -\begin_layout LyX-Code - dptr++; -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Subsection -Iterating over all but one axis -\end_layout - -\begin_layout Standard -A common algorithm is to loop over all elements of an array and perform - some function with each element by issuing a function call. - As function calls can be time consuming, one way to speed up this kind - of algorithm is to write the function so it takes a vector of data and - then write the iteration so the function call is performed for an entire - dimension of data at a time. - This increases the amount of work done per function call, thereby reducing - the function-call over-head to a small(er) fraction of the total time. - Even if the interior of the loop is performed without a function call it - can be advantageous to perform the inner loop over the dimension with the - highest number of elements to take advantage of speed enhancements available - on micro-processors that use pipelining to enhance fundmental operations. - -\end_layout - -\begin_layout Standard -The -\series bold -PyArray_IterAllButAxis -\series default -( -\family typewriter -array -\family default -, -\family typewriter -&dim -\family default -) constructs an iterator object that is modified so that it will not iterate - over the dimension indicated by dim. - The only restriction on this iterator object, is that the -\series bold -PyArray_Iter_GOTO1D -\series default -( -\family typewriter -it -\family default -, -\family typewriter -ind -\family default -) macro cannot be used (thus flat indexing won't work either if you pass - this object back to Python --- so you shouldn't do this). - Note that the returned object from this routine is still usually cast to - PyArrayIterObject *. - All that's been done is to modify the strides and dimensions of the returned - iterator to simulate iterating over array[...,0,...] where 0 is placed on the - -\begin_inset Formula $\textrm{dim}^{\textrm{th}}$ -\end_inset - - dimension. - If dim is negative, then the dimension with the largest axis is found and - used. - -\end_layout - -\begin_layout Subsection -Iterating over multiple arrays -\end_layout - -\begin_layout Standard -Very often, it is desireable to iterate over several arrays at the same - time. - The universal functions are an example of this kind of behavior. - If all you want to do is iterate over arrays with the same shape, then - simply creating several iterator objects is the standard procedure. - For example, the following code iterates over two arrays assumed to be - the same shape and size (actually obj1 just has to have at least as many - total elements as does obj2): -\end_layout - -\begin_layout LyX-Code -/* It is already assumed that obj1 and obj2 -\end_layout - -\begin_layout LyX-Code - are ndarrays of the same shape and size. -\end_layout - -\begin_layout LyX-Code -*/ -\end_layout - -\begin_layout LyX-Code -iter1 = (PyArrayIterObject *)PyArray_IterNew(obj1); -\end_layout - -\begin_layout LyX-Code -if (iter1 == NULL) goto fail; -\end_layout - -\begin_layout LyX-Code -iter2 = (PyArrayIterObject *)PyArray_IterNew(obj2); -\end_layout - -\begin_layout LyX-Code -if (iter2 == NULL) goto fail; /* assume iter1 is DECREF'd at fail */ -\end_layout - -\begin_layout LyX-Code -while (iter2->index < iter2->size) { -\end_layout - -\begin_layout LyX-Code - /* process with iter1->dataptr and iter2->dataptr */ -\end_layout - -\begin_layout LyX-Code - PyArray_ITER_NEXT(iter1); -\end_layout - -\begin_layout LyX-Code - PyArray_ITER_NEXT(iter2); -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Subsection -Broadcasting over multiple arrays -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "broadcasting" - -\end_inset - -When multiple arrays are involved in an operation, you may want to use the - same broadcasting rules that the math operations ( -\emph on -i.e. - -\emph default - the ufuncs) use. - This can be done easily using the PyArrayMultiIterObject. - This is the object returned from the Python command numpy.broadcast and - it is almost as easy to use from C. - The function -\series bold -PyArray_MultiIterNew -\series default - ( -\family typewriter -n -\family default -, -\family typewriter -... -\family default -) is used (with -\family typewriter -n -\family default - input objects in place of -\family typewriter -... -\family default -). - The input objects can be arrays or anything that can be converted into - an array. - A pointer to a PyArrayMultiIterObject is returned. - Broadcasting has already been accomplished which adjusts the iterators - so that all that needs to be done to advance to the next element in each - array is for PyArray_ITER_NEXT to be called for each of the inputs. - This incrementing is automatically performed by -\series bold -PyArray_MultiIter_NEXT -\series default -( -\family typewriter -obj -\family default -) macro (which can handle a multiterator -\family typewriter -obj -\family default - as either a PyArrayMultiObject* or a PyObject*). - The data from input number -\family typewriter -i -\family default - is available using -\series bold -PyArray_MultiIter_DATA -\series default -( -\family typewriter -obj -\family default -, -\family typewriter -i -\family default -) and the total (broadcasted) size as -\series bold -PyArray_MultiIter_SIZE -\series default -( -\family typewriter -obj -\family default -). - An example of using this feature follows. -\end_layout - -\begin_layout LyX-Code -mobj = PyArray_MultiIterNew(2, obj1, obj2); -\end_layout - -\begin_layout LyX-Code -size = PyArray_MultiIter_SIZE(obj); -\end_layout - -\begin_layout LyX-Code -while(size--) { -\end_layout - -\begin_layout LyX-Code - ptr1 = PyArray_MultiIter_DATA(mobj, 0); -\end_layout - -\begin_layout LyX-Code - ptr2 = PyArray_MultiIter_DATA(mobj, 1); -\end_layout - -\begin_layout LyX-Code - /* code using contents of ptr1 and ptr2 */ -\end_layout - -\begin_layout LyX-Code - PyArray_MultiIter_NEXT(mobj); -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Standard -The function -\series bold -PyArray_RemoveSmallest -\series default -( -\family typewriter -multi -\family default -) can be used to take a multi-iterator object and adjust all the iterators - so that iteration does not take place over the largest dimension (it makes - that dimension of size 1). - The code being looped over that makes use of the pointers will very-likely - also need the strides data for each of the iterators. - This information is stored in multi->iters[i]->strides. -\end_layout - -\begin_layout Standard -There are several examples of using the multi-iterator in the NumPy source - code as it makes N-dimensional broadcasting-code very simple to write. - Browse the source for more examples. - -\begin_inset LatexCommand index -name "array iterator|)" - -\end_inset - - -\end_layout - -\begin_layout Section -Creating a new universal function -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand label -name "sec:Creating-a-new" - -\end_inset - - -\begin_inset LatexCommand index -name "ufunc!adding new|(" - -\end_inset - -The umath module is a computer-generated C-module that creates many ufuncs. - It provides a great many examples of how to create a universal function. - Creating your own ufunc that will make use of the ufunc machinery is not - difficult either. - Suppose you have a function that you want to operate element-by-element - over its inputs. - By creating a new ufunc you will obtain a function that handles -\end_layout - -\begin_layout Itemize -broadcasting -\end_layout - -\begin_layout Itemize -N-dimensional looping -\end_layout - -\begin_layout Itemize -automatic type-conversions with minimal memory usage -\end_layout - -\begin_layout Itemize -optional output arrays -\end_layout - -\begin_layout Standard -It is not difficult to create your own ufunc. - All that is required is a 1-d loop for each data-type you want to support. - Each 1-d loop must have a specific signature, and only ufuncs for fixed-size - data-types can be used. - The function call used to create a new ufunc to work on built-in data-types - is given below. - A different mechanism is used to register ufuncs for user-defined data-types. -\end_layout - -\begin_layout Description -PyUFunc_FromFuncAndData ( -\family typewriter -PyObject* -\family default -) ( -\family typewriter -PyUFuncGenericFunction* -\family default - func, -\family typewriter -void** -\family default - data, -\family typewriter -char* -\family default - types, -\family typewriter -int -\family default - ntypes, -\family typewriter -int -\family default - nin, -\family typewriter -int -\family default - nout, -\family typewriter -int -\family default - identity, -\family typewriter -char* -\family default - name, -\family typewriter -char* -\family default - doc, -\family typewriter -int -\family default - check_return) -\end_layout - -\begin_deeper -\begin_layout Description -func A pointer to an array of 1-d functions to use. - This array must be at least ntypes long. - Each entry in the array must be a -\family typewriter -PyUFuncGenericFunction -\family default - function. - This function has the following signature. - An example of a valid 1d loop function is also given. - -\end_layout - -\begin_layout Description -\InsetSpace ~ - -\family typewriter -void -\family default - loop1d ( -\family typewriter -char** -\family default - args, -\family typewriter -npy_intp* -\family default - dimensions, -\family typewriter -npy_intp* -\family default - steps, -\family typewriter -void* -\family default - data) -\end_layout - -\begin_deeper -\begin_layout Description -args An array of pointers to the actual data for the input and output arrays. - The input arguments are given first followed by the output arguments. -\end_layout - -\begin_layout Description -dimensions A pointer to the size of the dimension over which this function - is looping. - -\end_layout - -\begin_layout Description -steps A pointer to the number of bytes to jump to get to the next element - in this dimension for each of the input and output arguments. - -\end_layout - -\begin_layout Description -data Arbitrary data (extra arguments, function names, -\emph on -etc. -\emph default -) that can be stored with the ufunc and will be passed in when it is called. - -\end_layout - -\end_deeper -\begin_layout LyX-Code -static void -\newline -double_add(char *args, npy_intp *dimensions, npy_intp *steps, - void *extra) -\newline -{ -\newline - npy_intp i; -\newline - npy_intp is1=steps[0], is2=steps[1]; -\newline - - npy_intp os=steps[2], n=dimensions[0]; -\newline - char *i1=args[0], *i2=args[1], - *op=args[2]; -\newline - for (i=0; i<n; i++) { -\newline - *((double *)op) = *((double - *)i1) + -\backslash - -\newline - *((double *)i2); -\newline - i1 += is1; i2 += is2; - op += os; -\newline - } -\newline -} -\end_layout - -\begin_layout Description -data An array of data. - There should be ntypes entries (or NULL) --- one for every loop function - defined for this ufunc. - This data will be passed in to the 1-d loop. - One common use of this data variable is to pass in an actual function to - call to compute the result when a generic 1-d loop (e.g. - PyUFunc_d_d) is being used. - -\end_layout - -\begin_layout Description -types An array of type-number signatures (type -\family typewriter -char -\family default -). - This array should be of size (nin+nout)*ntypes and contain the data-types - for the corresponding 1-d loop. - The inputs should be first followed by the outputs. - For example, suppose I have a ufunc that supports 1 integer and 1 double - 1-d loop (length-2 func and data arrays) that takes 2 inputs and returns - 1 output that is always a complex double, then the types array would be -\end_layout - -\begin_layout LyX-Code -char my_sigs[] = -\backslash - -\newline -{NPY_INT, NPY_INT, NPY_CDOUBLE, -\newline -NPY_DOUBLE, NPY_DOUBLE, NPY_CDOUBLE}; -\end_layout - -\begin_layout Description -\InsetSpace ~ - The bit-width names can also be used (e.g. - -\family typewriter -NPY_INT32 -\family default -, -\family typewriter -NPY_COMPLEX128 -\family default -) if desired. - -\end_layout - -\begin_layout Description -ntypes The number of data-types supported. - This is equal to the number of 1-d loops provided. - -\end_layout - -\begin_layout Description -nin The number of input arguments. -\end_layout - -\begin_layout Description -nout The number of output arguments. -\end_layout - -\begin_layout Description -identity Either -\series bold -PyUFunc_One -\series default -, -\series bold -PyUFunc_Zero -\series default -, -\series bold -PyUFunc_None -\series default -. - This specifies what should be returned when an empty array is passed to - the reduce method of the ufunc. - -\end_layout - -\begin_layout Description -name A -\family typewriter -NULL -\family default --terminated string providing the name of this ufunc (should be the Python - name it will be called). - -\end_layout - -\begin_layout Description -doc A documentation string for this ufunc (will be used in generating the - response to <ufunc_name>.__doc__). - Do not include the function signature or the name as this is generated - automatically. - -\end_layout - -\begin_layout Description -check_return Not presently used, but this integer value does get set in - the structure-member of similar name. - -\end_layout - -\end_deeper -\begin_layout Standard -The returned ufunc object is a callable Python object. - It should be placed in a (module) dictionary under the same name as was - used in the name argument to the ufunc-creation routine. - The following example is adapted from the umath module: -\begin_inset LatexCommand index -name "ufunc!adding new|)" - -\end_inset - - -\end_layout - -\begin_layout LyX-Code -static PyUFuncGenericFunction atan2_functions[]= -\backslash - -\newline - {PyUFunc_ff_f, PyUFunc_dd_d, -\newline - PyUFunc_gg_g, PyUFunc_OO_O_method}; -\newline -static - void* atan2_data[]= -\backslash - -\newline - {(void *)atan2f,(void *) atan2, -\newline - (void *)atan2l,(void *)"arctan2"}; -\newline -stati -c char atan2_signatures[]= -\backslash - -\newline - {NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, -\newline - NPY_DOUBLE, NPY_DOUBLE, -\newline - NPY_DOUBLE -, NPY_LONGDOUBLE, -\newline - NPY_LONGDOUBLE, NPY_LONGDOUBLE -\newline - NPY_OBJECT, NPY_OBJECT, - -\newline - NPY_OBJECT}; -\newline -... -\newline -/* in the module initialization code */ -\newline -PyObject *f, *dict, - *module; -\newline -... -\newline -dict = PyModule_GetDict(module); -\newline -... -\newline -f = PyUFunc_FromFuncAndData(atan2_funct -ions, -\newline - atan2_data, atan2_signatures, 4, 2, 1, -\newline - PyUFunc_None, "arctan2", - -\newline - "a safe and correct arctan(x1/x2)", 0); -\newline -PyDict_SetItemString(dict, "arctan2" -, f); -\newline -Py_DECREF(f); -\newline -... -\end_layout - -\begin_layout Section -User-defined data-types -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "dtype!adding new|(" - -\end_inset - -NumPy comes with 21 builtin data-types. - While this covers a large majority of possible use cases, it is conceivable - that a user may have a need for an additional data-type. - There is some support for adding an additional data-type into the NumPy - system. - This additional data-type will behave much like a regular data-type except - ufuncs must have 1-d loops registered to handle it separately. - Also checking for whether or not other data-types can be cast -\begin_inset Quotes eld -\end_inset - -safely -\begin_inset Quotes erd -\end_inset - - to and from this new type or not will always return -\begin_inset Quotes eld -\end_inset - -can cast -\begin_inset Quotes erd -\end_inset - - unless you also register which types your new data-type can be cast to - and from. - Adding data-types is one of the less well-tested areas for NumPy 1.0, so - there may be bugs remaining in the approach. - Only add a new data-type if you can't do what you want to do using the - OBJECT or VOID data-types that are already available. - As an example of what I consider a useful application of the ability to - add data-types is the possibility of adding a data-type of arbitrary precision - floats to NumPy. - -\end_layout - -\begin_layout Subsection -Adding the new data-type -\end_layout - -\begin_layout Standard -To begin to make use of the new data-type, you need to first define a new - Python type to hold the scalars of your new data-type. - It should be acceptable to inherit from one of the array scalars if your - new type has a binary compatible layout. - This will allow your new data type to have the methods and attributes of - array scalars. - New data-types must have a fixed memory size (if you want to define a data-type - that needs a flexible representation, like a variable-precision number, - then use a pointer to the object as the data-type). - The memory layout of the object structure for the new Python type must - be PyObject_HEAD followed by the fixed-size memory needed for the data-type. - For example, a suitable structure for the new Python type is: -\end_layout - -\begin_layout LyX-Code -typedef struct { -\end_layout - -\begin_layout LyX-Code - PyObject_HEAD; -\end_layout - -\begin_layout LyX-Code - some_data_type obval; -\end_layout - -\begin_layout LyX-Code - /* the name can be whatever you want */ -\end_layout - -\begin_layout LyX-Code -} PySomeDataTypeObject; -\end_layout - -\begin_layout Standard -After you have defined a new Python type object, you must then define a - new PyArray_Descr structure whose typeobject member will contain a pointer - to the data-type you've just defined. - In addition, the required functions in the -\begin_inset Quotes eld -\end_inset - -.f -\begin_inset Quotes erd -\end_inset - - member must be defined: nonzero, copyswap, copyswapn, setitem, getitem, - and cast. - The more functions in the -\begin_inset Quotes eld -\end_inset - -.f -\begin_inset Quotes erd -\end_inset - - member you define, however, the more useful the new data-type will be. - It is very important to intialize unused functions to NULL. - This can be achieved using -\series bold -PyArray_InitArrFuncs -\series default -(f). -\end_layout - -\begin_layout Standard -Once a new PyArray_Descr structure is created and filled with the needed - information and useful functions you call -\series bold -PyArray_RegisterDataType -\series default -(new_descr). - The return value from this call is an integer providing you with a unique - type_number that specifies your data-type. - This type number should be stored and made available by your module so - that other modules can use it to recognize your data-type (the other mechanism - for finding a user-defined data-type number is to search based on the name - of the type-object associated with the data-type using -\series bold -PyArray_TypeNumFromName -\series default -). - -\end_layout - -\begin_layout Subsection -Registering a casting function -\end_layout - -\begin_layout Standard -You may want to allow builtin (and other user-defined) data-types to be - cast automatically to your data-type. - In order to make this possible, you must register a casting function with - the data-type you want to be able to cast from. - This requires writing low-level casting functions for each conversion you - want to support and then registering these functions with the data-type - descriptor. - A low-level casting function has the signature. - -\end_layout - -\begin_layout Description -castfunc ( -\family typewriter -void -\family default -) ( -\family typewriter -void* -\family default - from, -\family typewriter -void* -\family default - to, -\family typewriter -npy_intp -\family default - n, -\family typewriter -void* -\family default - fromarr, -\family typewriter -void* -\family default - toarr) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Cast -\family typewriter -n -\family default - elements -\family typewriter -from -\family default - one type -\family typewriter -to -\family default - another. - The data to cast from is in a contiguous, correctly-swapped and aligned - chunk of memory pointed to by from. - The buffer to cast to is also contiguous, correctly-swapped and aligned. - The fromarr and toarr arguments should only be used for flexible-element-sized - arrays (string, unicode, void). - -\end_layout - -\begin_layout Standard -An example castfunc is -\end_layout - -\begin_layout LyX-Code -static void -\end_layout - -\begin_layout LyX-Code -double_to_float(double *from, float* to, npy_intp n, -\newline - void* ig1, void* - ig2); -\newline -while (n--) { -\newline - (*to++) = (double) *(from++); -\newline -} -\end_layout - -\begin_layout Standard -This could then be registered to convert doubles to floats using the code -\end_layout - -\begin_layout LyX-Code -doub = PyArray_DescrFromType(NPY_DOUBLE); -\newline -PyArray_RegisterCastFunc(doub, - NPY_FLOAT, -\newline - (PyArray_VectorUnaryFunc *)double_to_float); -\newline -Py_DECREF(doub); -\end_layout - -\begin_layout Subsection -Registering coercion rules -\end_layout - -\begin_layout Standard -By default, all user-defined data-types are not presumed to be safely castable - to any builtin data-types. - In addition builtin data-types are not presumed to be safely castable to - user-defined data-types. - This situation limits the ability of user-defined data-types to participate - in the coercion system used by ufuncs and other times when automatic coercion - takes place in NumPy. - This can be changed by registering data-types as safely castable from a - particlar data-type object. - The function -\series bold -PyArray_RegisterCanCast -\series default - (from_descr, totype_number, scalarkind) should be used to specify that - the data-type object from_descr can be cast to the data-type with type - number totype_number. - If you are not trying to alter scalar coercion rules, then use -\series bold -NPY_NOSCALAR -\series default - for the scalarkind argument. -\end_layout - -\begin_layout Standard -If you want to allow your new data-type to also be able to share in the - scalar coercion rules, then you need to specify the scalarkind function - in the data-type object's -\begin_inset Quotes eld -\end_inset - -.f -\begin_inset Quotes erd -\end_inset - - member to return the kind of scalar the new data-type should be seen as - (the value of the scalar is available to that function). - Then, you can register data-types that can be cast to separately for each - scalar kind that may be returned from your user-defined data-type. - If you don't register scalar coercion handling, then all of your user-defined - data-types will be seen as -\series bold -NPY_NOSCALAR -\series default -. - -\end_layout - -\begin_layout Subsection -Registering a ufunc loop -\end_layout - -\begin_layout Standard -You may also want to register low-level ufunc loops for your data-type so - that an ndarray of your data-type can have math applied to it seamlessly. - Registering a new loop with exactly the same arg_types signature, silently - replaces any previously registered loops for that data-type. - -\end_layout - -\begin_layout Standard -Before you can register a 1-d loop for a ufunc, the ufunc must be previously - created. - Then you call -\series bold -PyUFunc_RegisterLoopForType -\series default -(...) with the information needed for the loop. - The return value of this function is -\family typewriter -0 -\family default - if the process was successful and -\family typewriter --1 -\family default - with an error condition set if it was not successful. - -\end_layout - -\begin_layout Description -PyUFunc_RegisterLoopForType ( -\family typewriter -int -\family default -) ( -\family typewriter -PyUFuncObject* -\family default - ufunc, -\family typewriter -int -\family default - usertype, -\family typewriter -PyUFuncGenericFunction -\family default - function, -\family typewriter -int* -\family default - arg_types, -\family typewriter -void* -\family default - data) -\end_layout - -\begin_layout Description -ufunc The ufunc to attach this loop to. -\end_layout - -\begin_layout Description -usertype The user-defined type this loop should be indexed under. - This number must be a user-defined type or an error occurs. - -\end_layout - -\begin_layout Description -function The ufunc inner 1-d loop. - This function must have the signature as explained in Section -\begin_inset LatexCommand ref -reference "sec:Creating-a-new" - -\end_inset - -. -\end_layout - -\begin_layout Description -arg_types (optional) If given, this should contain an array of integers - of at least size ufunc.nargs containing the data-types expected by the loop - function. - The data will be copied into a NumPy-managed structure so the memory for - this argument should be deleted after calling this function. - If this is NULL, then it will be assumed that all data-types are of type - usertype. -\end_layout - -\begin_layout Description -data (optional) Specify any optional data needed by the function which will - be passed when the function is called. - -\begin_inset LatexCommand index -name "dtype!adding new|)" - -\end_inset - - -\end_layout - -\begin_layout Section -Subtyping the ndarray in C -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ndarray!subtyping|(" - -\end_inset - -One of the lesser-used features that has been lurking in Python since 2.2 - is the ability to sub-class types in C. - This facility is one of the important reasons for basing NumPy off of the - Numeric code-base which was already in C. - A sub-type in C allows much more flexibility with regards to memory management. - Sub-typing in C is not difficult even if you have only a rudimentary understand -ing of how to create new types for Python. - While it is easiest to sub-type from a single parent type, sub-typing from - multiple parent types is also possible. - Multiple inheritence in C is generally less useful than it is in Python - because a restriction on Python sub-types is that they have a binary compatible - memory layout. - Perhaps for this reason, it is somewhat easier to sub-type from a single - parent type. - -\end_layout - -\begin_layout Standard -All C-structures corresponding to Python objects must begin with PyObject_HEAD - (or PyObject_VAR_HEAD). - In the same way, any sub-type must have a C-structure that begins with - exactly the same memory layout as the parent type (or all of the parent - types in the case of multiple-inheritance). - The reason for this is that Python may attempt to access a member of the - sub-type structure as if it had the parent structure ( -\emph on -i.e. - -\emph default - it will cast a given pointer to a pointer to the parent structure and then - dereference one of it's members). - If the memory layouts are not compatible, then this attempt will cause - unpredictable behavior (eventually leading to a memory violation and program - crash). - -\end_layout - -\begin_layout Standard -One of the elements in PyObject_HEAD is a pointer to a type-object structure. - A new Python type is created by creating a new type-object structure and - populating it with functions and pointers to describe the desired behavior - of the type. - Typically, a new C-structure is also created to contain the instance-specific - information needed for each object of the type as well. - For example, &PyArray_Type is a pointer to the type-object table for the - ndarray while a PyArrayObject* variable is a pointer to a particular instance - of an ndarray (one of the members of the ndarray structure is, in turn, - a pointer to the type-object table &PyArray_Type). - Finally -\series bold -PyType_Ready -\series default -(<pointer_to_type_object>) must be called for every new Python type. - -\end_layout - -\begin_layout Subsection -Creating sub-types -\end_layout - -\begin_layout Standard -To create a sub-type, a similar proceedure must be followed except only - behaviors that are different require new entries in the type-object structure. - All other entires can be NULL and will be filled in by -\series bold -PyType_Ready -\series default - with appropriate functions from the parent type(s). - In particular, to create a sub-type in C follow these steps: -\end_layout - -\begin_layout Enumerate -If needed create a new C-structure to handle each instance of your type. - A typical C-structure would be -\end_layout - -\begin_deeper -\begin_layout LyX-Code -typedef _new_struct { -\newline - PyArrayObject base; -\newline - /* new things here */ -\newline -} NewArrayO -bject; -\end_layout - -\begin_layout Standard -Notice that the full PyArrayObject is used as the first entry in order to - ensure that the binary layout of instances of the new type is identical - to the PyArrayObject. - -\end_layout - -\end_deeper -\begin_layout Enumerate -Fill in a new Python type-object structure with pointers to new functions - that will over-ride the default behavior while leaving any function that - should remain the same unfilled (or NULL). - The tp_name element should be different. -\end_layout - -\begin_layout Enumerate -Fill in the tp_base member of the new type-object structure with a pointer - to the (main) parent type object. - For multiple-inheritance, also fill in the tp_bases member with a tuple - containing all of the parent objects in the order they should be used to - define inheritance. - Remember, all parent-types must have the same C-structure for multiple - inheritance to work properly. - -\end_layout - -\begin_layout Enumerate -Call -\series bold -PyType_Ready -\series default -(<pointer_to_new_type>). - If this function returns a negative number, a failure occurred and the - type is not initialized. - Otherwise, the type is ready to be used. - It is generally important to place a reference to the new type into the - module dictionary so it can be accessed from Python. - -\end_layout - -\begin_layout Standard -More information on creating sub-types in C can be learned by reading PEP - 253 (available at http://www.python.org/dev/peps/pep-0253). -\end_layout - -\begin_layout Subsection -Specific features of ndarray sub-typing -\end_layout - -\begin_layout Standard -Some special methods and attributes are used by arrays in order to facilitate - the interoperation of sub-types with the base ndarray type. - -\end_layout - -\begin_layout Subsubsection -The __array_finalize__ method -\end_layout - -\begin_layout Standard -Several array-creation functions of the ndarray allow specification of a - particular sub-type to be created. - This allows sub-types to be handled seamlessly in many routines. - When a sub-type is created in such a fashion, however, neither the __new__ - method nor the __init__ method gets called. - Instead, the sub-type is allocated and the appropriate instance-structure - members are filled in. - Finally, the -\series bold -__array_finalize__ -\series default - attribute is looked-up in the object dictionary. - If it is present and not None, then it can be either a CObject containing - a pointer to a -\series bold -PyArray_FinalizeFunc -\series default - or it can be a method taking a single argument (which could be None). - -\end_layout - -\begin_layout Standard -If the -\series bold -__array_finalize__ -\series default - attribute is a CObject, then the pointer must be a pointer to a function - with the signature: -\end_layout - -\begin_layout Description -\InsetSpace ~ - (int) (PyArrayObject *, PyObject *) -\end_layout - -\begin_layout Standard -The first argument is the newly created sub-type. - The second argument (if not NULL) is the -\begin_inset Quotes eld -\end_inset - -parent -\begin_inset Quotes erd -\end_inset - - array (if the array was created using slicing or some other operation where - a clearly-distinguishable parent is present). - This routine can do anything it wants to. - It should return a -1 on error and 0 otherwise. - -\end_layout - -\begin_layout Standard -If the -\series bold -__array_finalize__ -\series default - attribute is not None nor a CObject, then it must be a Python method that - takes the parent array as an argument (which could be None if there is - no parent), and returns nothing. - Errors in this method will be caught and handled. - -\end_layout - -\begin_layout Subsubsection -The __array_priority__ attribute -\end_layout - -\begin_layout Standard -This attribute allows simple but flexible determination of which sub-type - should be considered -\begin_inset Quotes eld -\end_inset - -primary -\begin_inset Quotes erd -\end_inset - - when an operation involving two or more sub-types arises. - In operations where different sub-types are being used, the sub-type with - the largest -\series bold -__array_priority__ -\series default - attribute will determine the sub-type of the output(s). - If two sub-types have the same -\series bold -__array_prioirty__ -\series default - then the sub-type of the first argument determines the output. - The default -\series bold -__array_priority__ -\series default - attribute returns a value of 0.0 for the base ndarray type and 1.0 for a - sub-type. - This attribute can also be defined by objects that are not sub-types of - the ndarray and can be used to determine which -\series bold -__array_wrap__ -\series default - method should be called for the return output. - -\end_layout - -\begin_layout Subsubsection -The __array_wrap__ method -\end_layout - -\begin_layout Standard -Any class or type can define this method which should take an ndarray argument - and return an instance of the type. - It can be seen as the opposite of the -\series bold -__array__ -\series default - method. - This method is used by the ufuncs (and other NumPy functions) to allow - other objects to pass through. - For Python >2.4, it can also be used to write a decorator that converts - a function that works only with ndarrays to one that works with any type - with -\series bold -__array__ -\series default - and -\series bold -__array_wrap__ -\series default - methods. - -\begin_inset LatexCommand index -name "ndarray!subtyping|)" - -\end_inset - - -\end_layout - -\begin_layout Chapter -Using Python as glue -\end_layout - -\begin_layout Quotation -There is no conversation more boring than the one where everybody agrees. -\end_layout - -\begin_layout Right Address ---- -\emph on -Michel de Montaigne -\end_layout - -\begin_layout Quotation -Duct tape is like the force. - It has a light side, and a dark side, and it holds the universe together. -\end_layout - -\begin_layout Right Address ---- -\emph on -Carl Zwanzig -\end_layout - -\begin_layout Standard -Many people like to say that Python is a fantastic glue language. - Hopefully, this Chapter will convince you that this is true. - The first adopters of Python for science were typically people who used - it to glue together large applicaton codes running on super-computers. - Not only was it much nicer to code in Python than in a shell script or - Perl, in addition, the ability to easily extend Python made it relatively - easy to create new classes and types specifically adapted to the problems - being solved. - From the interactions of these early contributors, Numeric emerged as an - array-like object that could be used to pass data between these applications. -\end_layout - -\begin_layout Standard -As Numeric has matured and developed into NumPy, people have been able to - write more code directly in NumPy. - Often this code is fast-enough for production use, but there are still - times that there is a need to access compiled code. - Either to get that last bit of efficiency out of the algorithm or to make - it easier to access widely-available codes written in C/C++ or Fortran. - -\end_layout - -\begin_layout Standard -This chapter will review many of the tools that are available for the purpose - of accessing code written in other compiled languages. - There are many resources available for learning to call other compiled - libraries from Python and the purpose of this Chapter is not to make you - an expert. - The main goal is to make you aware of some of the possibilities so that - you will know what to -\begin_inset Quotes eld -\end_inset - -Google -\begin_inset Quotes erd -\end_inset - - in order to learn more. - -\end_layout - -\begin_layout Standard -The http://www.scipy.org website also contains a great deal of useful information - about many of these tools. - For example, there is a nice description of using several of the tools - explained in this chapter at http://www.scipy.org/PerformancePython. - This link provides several ways to solve the same problem showing how to - use and connect with compiled code to get the best performance. - In the process you can get a taste for several of the approaches that will - be discussed in this chapter. - -\end_layout - -\begin_layout Section -Calling other compiled libraries from Python -\end_layout - -\begin_layout Standard -While Python is a great language and a pleasure to code in, its dynamic - nature results in overhead that can cause some code ( -\emph on -i.e. - -\emph default - raw computations inside of for loops) to be up 10-100 times slower than - equivalent code written in a static compiled language. - In addition, it can cause memory usage to be larger than necessary as temporary - arrays are created and destroyed during computation. - For many types of computing needs the extra slow-down and memory consumption - can often not be spared (at least for time- or memory-critical portions - of your code). - Therefore one of the most common needs is to call out from Python code - to a fast, machine-code routine (e.g. - compiled using C/C++ or Fortran). - The fact that this is relatively easy to do is a big reason why Python - is such an excellent high-level language for scientific and engineering - programming. - -\end_layout - -\begin_layout Standard -Their are two basic approaches to calling compiled code: writing an extension - module that is then imported to Python using the import command, or calling - a shared-library subroutine directly from Python using the ctypes module - (included in the standard distribution with Python 2.5). - The first method is the most common (but with the inclusion of ctypes into - Python 2.5 this status may change). -\end_layout - -\begin_layout Warning -Calling C-code from Python can result in Python crashes if you are not careful. - None of the approaches in this chapter are immune. - You have to know something about the way data is handled by both NumPy - and by the third-party library being used. - -\end_layout - -\begin_layout Section -Hand-generated wrappers -\end_layout - -\begin_layout Standard -Extension modules were discussed in Chapter -\begin_inset LatexCommand ref -reference "sec:Writing-an-extension" - -\end_inset - -. - The most basic way to interface with compiled code is to write an extension - module and construct a module method that calls the compiled code. - For improved readability, your method should take advantage of the PyArg_ParseT -uple call to convert between Python objects and C data-types. - For standard C data-types there is probably already a built-in converter. - For others you may need to write your own converter and use the -\begin_inset Quotes eld -\end_inset - -O& -\begin_inset Quotes erd -\end_inset - - format string which allows you to specify a function that will be used - to perform the conversion from the Python object to whatever C-structures - are needed. - -\end_layout - -\begin_layout Standard -Once the conversions to the appropriate C-structures and C data-types have - been performed, the next step in the wrapper is to call the underlying - function. - This is straightforward if the underlying function is in C or C++. - However, in order to call Fortran code you must be familiar with how Fortran - subroutines are called from C/C++ using your compiler and platform. - This can vary somewhat platforms and compilers (which is another reason - f2py makes life much simpler for interfacing Fortran code) but generally - involves underscore mangling of the name and the fact that all variables - are passed by reference (i.e. - all arguments are pointers). - -\end_layout - -\begin_layout Standard -The advantage of the hand-generated wrapper is that you have complete control - over how the C-library gets used and called which can lead to a lean and - tight interface with minimal over-head. - The disadvantage is that you have to write, debug, and maintain C-code, - although most of it can be adapted using the time-honored technique of - -\begin_inset Quotes eld -\end_inset - -cutting-pasting-and-modifying -\begin_inset Quotes erd -\end_inset - - from other extension modules. - Because, the procedure of calling out to additional C-code is fairly regimented -, code-generation procedures have been developed to make this process easier. - One of these code-generation techniques is distributed with NumPy and allows - easy integration with Fortran and (simple) C code. - This package, f2py, will be covered briefly in the next session. - -\end_layout - -\begin_layout Section -f2py -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "f2py|(" - -\end_inset - -F2py allows you to automatically construct an extension module that interfaces - to routines in Fortran 77/90/95 code. - It has the ability to parse Fortran 77/90/95 code and automatically generate - Python signatures for the subroutines it encounters, or you can guide how - the subroutine interfaces with Python by constructing an interface-defintion-fi -le (or modifying the f2py-produced one). - -\end_layout - -\begin_layout Subsection -Creating source for a basic extension module -\end_layout - -\begin_layout Standard -Probably the easiest way to introduce f2py is to offer a simple example. - Here is one of the subroutines contained in a file named add.f -\end_layout - -\begin_layout LyX-Code -C -\newline - SUBROUTINE ZADD(A,B,C,N) -\newline -C -\newline - DOUBLE COMPLEX A(*) -\newline - DOUBLE COMPLEX - B(*) -\newline - DOUBLE COMPLEX C(*) -\newline - INTEGER N -\newline - DO 20 J = 1, N -\newline - - C(J) = A(J)+B(J) -\newline - 20 CONTINUE -\newline - END -\end_layout - -\begin_layout Standard -This routine simply adds the elements in two contiguous arrays and places - the result in a third. - The memory for all three arrays must be provided by the calling routine. - A very basic interface to this routine can be automatically generated by - f2py: -\end_layout - -\begin_layout LyX-Code -f2py -m add add.f -\end_layout - -\begin_layout Standard -You should be able to run this command assuming your search-path is set-up - properly. - This command will produce an extension module named addmodule.c in the current - directory. - This extension module can now be compiled and used from Python just like - any other extension module. - -\end_layout - -\begin_layout Subsection -Creating a compiled extension module -\end_layout - -\begin_layout Standard -You can also get f2py to compile add.f and also compile its produced extension - module leaving only a shared-library extension file that can be imported - from Python: -\end_layout - -\begin_layout LyX-Code -f2py -c -m add add.f -\end_layout - -\begin_layout Standard -This command leaves a file named add.<ext> in the current directory (where - <ext> is the appropriate extension for a python extension module on your - platform --- so, pyd, -\emph on -etc. -\emph default -). - This module may then be imported from Python. - It will contain a method for each subroutin in add (zadd, cadd, dadd, sadd). - The docstring of each method contains information about how the module - method may be called: -\end_layout - -\begin_layout LyX-Code ->>> import add -\newline ->>> print add.zadd.__doc__ -\newline -zadd - Function signature: -\newline - zadd(a,b,c,n) -\newline - -Required arguments: -\newline - a : input rank-1 array('D') with bounds (*) -\newline - b : input - rank-1 array('D') with bounds (*) -\newline - c : input rank-1 array('D') with bounds - (*) -\newline - n : input int -\end_layout - -\begin_layout Subsection -Improving the basic interface -\end_layout - -\begin_layout Standard -The default interface is a very literal translation of the fortran code - into Python. - The Fortran array arguments must now be NumPy arrays and the integer argument - should be an integer. - The interface will attempt to convert all arguments to their required types - (and shapes) and issue an error if unsuccessful. - However, because it knows nothing about the semantics of the arguments - (such that C is an output and n should really match the array sizes), it - is possible to abuse this function in ways that can cause Python to crash. - For example -\end_layout - -\begin_layout LyX-Code ->>> add.zadd([1,2,3],[1,2],[3,4],1000) -\end_layout - -\begin_layout Standard -will cause a program crash on most systems. - Under the covers, the lists are being converted to proper arrays but then - the underlying add loop is told to cycle way beyond the borders of the - allocated memory. - -\end_layout - -\begin_layout Standard -In order to improve the interface, directives should be provided. - This is accomplished by constructing an interface definition file. - It is usually best to start from the interface file that f2py can produce - (where it gets its default behavior from). - To get f2py to generate the interface file use the -h option: -\end_layout - -\begin_layout LyX-Code -f2py -h add.pyf -m add add.f -\end_layout - -\begin_layout Standard -This command leaves the file add.pyf in the current directory. - The section of this file corresponding to zadd is: -\end_layout - -\begin_layout LyX-Code -subroutine zadd(a,b,c,n) ! in :add:add.f -\newline - double complex dimension(*) :: - a -\newline - double complex dimension(*) :: b -\newline - double complex dimension(*) :: - c -\newline - integer :: n -\newline -end subroutine zadd -\end_layout - -\begin_layout Standard -By placing intent directives and checking code, the interface can be cleaned - up quite a bit until the Python module method is both easier to use and - more robust. - -\end_layout - -\begin_layout LyX-Code -subroutine zadd(a,b,c,n) ! in :add:add.f -\newline - double complex dimension(n) :: - a -\newline - double complex dimension(n) :: b -\newline - double complex intent(out),dimension(n -) :: c -\newline - integer intent(hide),depend(a) :: n=len(a) -\newline -end subroutine zadd -\end_layout - -\begin_layout Standard -The intent directive, intent(out) is used to tell f2py that -\family typewriter -c -\family default - is an output variable and should be created by the interface before being - passed to the underlying code. - The intent(hide) directive tells f2py to not allow the user to specify - the variable, -\family typewriter -n -\family default -, but instead to get it from the size of -\family typewriter -a -\family default -. - The depend( -\family typewriter -a -\family default -) directive is necessary to tell f2py that the value of n depends on the - input a (so that it won't try to create the variable n until the variable - a is created). - -\end_layout - -\begin_layout Standard -The new interface has docstring: -\end_layout - -\begin_layout LyX-Code ->>> print add.zadd.__doc__ -\newline -zadd - Function signature: -\newline - c = zadd(a,b) -\newline -Required - arguments: -\newline - a : input rank-1 array('D') with bounds (n) -\newline - b : input rank-1 - array('D') with bounds (n) -\newline -Return objects: -\newline - c : rank-1 array('D') with - bounds (n) -\end_layout - -\begin_layout Standard -Now, the function can be called in a much more robust way: -\end_layout - -\begin_layout LyX-Code ->>> add.zadd([1,2,3],[4,5,6]) -\newline -array([ 5.+0.j, 7.+0.j, 9.+0.j]) -\end_layout - -\begin_layout Standard -Notice the automatic conversion to the correct format that occurred. - -\end_layout - -\begin_layout Subsection -Inserting directives in Fortran source -\end_layout - -\begin_layout Standard -The nice interface can also be generated automatically by placing the variable - directives as special comments in the original fortran code. - Thus, if I modify the source code to contain: -\end_layout - -\begin_layout LyX-Code -C -\newline - SUBROUTINE ZADD(A,B,C,N) -\newline -C -\newline -CF2PY INTENT(OUT) :: C -\newline -CF2PY INTENT(HIDE) - :: N -\newline -CF2PY DOUBLE COMPLEX :: A(N) -\newline -CF2PY DOUBLE COMPLEX :: B(N) -\newline -CF2PY DOUBLE - COMPLEX :: C(N) -\newline - DOUBLE COMPLEX A(*) -\newline - DOUBLE COMPLEX B(*) -\newline - - DOUBLE COMPLEX C(*) -\newline - INTEGER N -\newline - DO 20 J = 1, N -\newline - C(J) = A(J) - + B(J) -\newline - 20 CONTINUE -\newline - END -\end_layout - -\begin_layout Standard -Then, I can compile the extension module using -\end_layout - -\begin_layout LyX-Code -f2py -c -m add add.f -\end_layout - -\begin_layout Standard -The resulting signature for the function add.zadd is exactly the same one - that was created previously. - If the original source code had contained A(N) instead of A(*) and so forth - with B and C, then I could obtain (nearly) the same interface simply by - placing the INTENT(OUT) :: C comment line in the source code. - The only difference is that N would be an optional input that would default - to the length of A. - -\end_layout - -\begin_layout Subsection -A filtering example -\end_layout - -\begin_layout Standard -For comparison with the other methods to be discussed. - Here is another example of a function that filters a two-dimensional array - of double precision floating-point numbers using a fixed averaging filter. - The advantage of using Fortran to index into multi-dimensional arrays should - be clear from this example. - -\end_layout - -\begin_layout LyX-Code - SUBROUTINE DFILTER2D(A,B,M,N) -\newline -C -\newline - DOUBLE PRECISION A(M,N) -\newline - DOUBLE - PRECISION B(M,N) -\newline - INTEGER N, M -\newline -CF2PY INTENT(OUT) :: B -\newline -CF2PY INTENT(HIDE) - :: N -\newline -CF2PY INTENT(HIDE) :: M -\newline - DO 20 I = 2,M-1 -\newline - DO 40 J=2,N-1 -\newline - - B(I,J) = A(I,J) + -\newline - $ (A(I-1,J)+A(I+1,J) + -\newline - - $ A(I,J-1)+A(I,J+1) )*0.5D0 + -\newline - $ (A(I-1,J-1) + A(I-1,J+1 -) + -\newline - $ A(I+1,J-1) + A(I+1,J+1))*0.25D0 -\newline - 40 CONTINUE -\newline - 20 - CONTINUE -\newline - END -\end_layout - -\begin_layout Standard -This code can be compiled and linked into an extension module named filter - using -\end_layout - -\begin_layout LyX-Code -f2py -c -m filter filter.f -\end_layout - -\begin_layout Standard -This will produce an extension module named filter.so in the current directory - with a method named dfilter2d that returns a filtered version of the input. - -\end_layout - -\begin_layout Subsection -Calling f2py from Python -\end_layout - -\begin_layout Standard -The f2py program is written in Python and can be run from inside your module. - This provides a facility that is somewhat similar to the use of weave.ext_tools - described below. - An example of the final interface executed using Python code is -\end_layout - -\begin_layout LyX-Code -import numpy.f2py as f2py -\end_layout - -\begin_layout LyX-Code -fid = open('add.f') -\end_layout - -\begin_layout LyX-Code -source = fid.read() -\end_layout - -\begin_layout LyX-Code -fid.close() -\end_layout - -\begin_layout LyX-Code -f2py.compile(source, modulename='add') -\end_layout - -\begin_layout LyX-Code -import add -\end_layout - -\begin_layout Standard -The source string can be any valid Fortran code. - If you want to save the extension-module source code then a suitable file-name - can be provided by the source_fn keyword to the compile function. - -\end_layout - -\begin_layout Subsection -Automatic extension module generation -\end_layout - -\begin_layout Standard -If you want to distribute your f2py extension module, then you only need - to include the .pyf file and the Fortran code. - The distutils extensions in NumPy allow you to define an extension module - entirely in terms of this interface file. - A valid setup.py file allowing distribution of the add.f module (as part - of the package f2py_examples so that it would be loaded as f2py_examples.add) - is -\end_layout - -\begin_layout LyX-Code -def configuration(parent_package='', top_path=None) -\newline - from numpy.distutils.misc_u -til import Configuration -\newline - config = Configuration('f2py_examples',parent_packag -e, top_path) -\newline - config.add_extension('add', sources=['add.pyf','add.f']) -\newline - - return config -\newline - -\newline -if __name__ == '__main__': -\newline - from numpy.distutils.core import - setup -\newline - setup(**configuration(top_path='').todict()) -\end_layout - -\begin_layout Standard -Installation of the new package is easy using -\end_layout - -\begin_layout LyX-Code -python setup.py install -\end_layout - -\begin_layout Standard -assuming you have the proper permissions to write to the main site-packages - directory for the version of Python you are using. - For the resulting package to work, you need to create a file named __init__.py - (in the same directory as add.pyf). - Notice the extension module is defined entirely in terms of the -\begin_inset Quotes eld -\end_inset - -add.pyf -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - -add.f -\begin_inset Quotes erd -\end_inset - - files. - The conversion of the .pyf file to a .c file is handled by numpy.disutils. - -\end_layout - -\begin_layout Subsection -Conclusion -\end_layout - -\begin_layout Standard -The interface definition file (.pyf) is how you can fine-tune the interface - between Python and Fortran. - There is decent documentation for f2py found in the numpy/f2py/docs directory - where-ever NumPy is installed on your system (usually under site-packages). - There is also more information on using f2py (including how to use it to - wrap C codes) at http://www.scipy.org/Cookbook under the -\begin_inset Quotes eld -\end_inset - -Using NumPy with Other Languages -\begin_inset Quotes erd -\end_inset - - heading. - -\end_layout - -\begin_layout Standard -The f2py method of linking compiled code is currently the most sophisticated - and integrated approach. - It allows clean separation of Python with compiled code while still allowing - for separate distribution of the extension module. - The only draw-back is that it requires the existence of a Fortran compiler - in order for a user to install the code. - However, with the existence of the free-compilers g77, gfortran, and g95, - as well as high-quality commerical compilers, this restriction is not particula -rly onerous. - In my opinion, Fortran is still the easiest way to write fast and clear - code for scientific computing. - It handles complex numbers, and multi-dimensional indexing in the most - straightforward way. - Be aware, however, that some Fortran compilers will not be able to optimize - code as well as good hand-written C-code. - -\begin_inset LatexCommand index -name "f2py|)" - -\end_inset - - -\end_layout - -\begin_layout Section -weave -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "weave|(" - -\end_inset - -Weave is a scipy package that can be used to automate the process of extending - Python with C/C++ code. - It can be used to speed up evaluation of an array expression that would - otherwise create temporary variables, to directly -\begin_inset Quotes eld -\end_inset - -inline -\begin_inset Quotes erd -\end_inset - - C/C++ code into Python, or to create a fully-named extension module. - You must either install scipy or get the weave package separately and install - it using the standard python setup.py install. - You must also have a C/C++-compiler installed and useable by Python distutils - in order to use weave. -\end_layout - -\begin_layout Standard -Somewhat dated, but still useful documentation for weave can be found at - the link http://www.scipy/Weave. - There are also many examples found in the examples directory which is installed - under the weave directory in the place where weave is installed on your - system. -\end_layout - -\begin_layout Subsection -Speed up code involving arrays (also see scipy.numexpr) -\end_layout - -\begin_layout Standard -This is the easiest way to use weave and requires minimal changes to your - Python code. - It involves placing quotes around the expression of interest and calling - weave.blitz. - Weave will parse the code and generate C++ code using Blitz C++ arrays. - It will then compile the code and catalog the shared library so that the - next time this exact string is asked for (and the array types are the same), - the already-compiled shared library will be loaded and used. - Because Blitz makes extensive use of C++ templating, it can take a long - time to compile the first time. - After that, however, the code should evaluate more quickly than the equivalent - NumPy expression. - This is especially true if your array sizes are large and the expression - would require NumPy to create several temporaries. - Only expressions involving basic arithmetic operations and basic array - slicing can be converted to Blitz C++ code. - -\end_layout - -\begin_layout Standard -For example, consider the expression -\end_layout - -\begin_layout LyX-Code -d = 4*a + 5*a*b + 6*b*c -\end_layout - -\begin_layout Standard -where a, b, and c are all arrays of the same type and shape. - When the data-type is double-precision and the size is 1000x1000, this - expression takes about 0.5 seconds to compute on an 1.1Ghz AMD Athlon machine. - When this expression is executed instead using blitz: -\end_layout - -\begin_layout LyX-Code -d = empty(a.shape, 'd'); weave.blitz(expr) -\end_layout - -\begin_layout Standard -execution time is only about 0.20 seconds (about 0.14 seconds spent in weave - and the rest in allocating space for d). - Thus, we've sped up the code by a factor of 2 using only a simnple command - (weave.blitz). - Your mileage may vary, but factors of 2-8 speed-ups are possible with this - very simple technique. - -\end_layout - -\begin_layout Standard -If you are interested in using weave in this way, then you should also look - at scipy.numexpr which is another similar way to speed up expressions by - eliminating the need for temporary variables. - Using numexpr does not require a C/C++ compiler. - -\end_layout - -\begin_layout Subsection -Inline C-code -\end_layout - -\begin_layout Standard -Probably the most widely-used method of employing weave is to -\begin_inset Quotes eld -\end_inset - -in-line -\begin_inset Quotes erd -\end_inset - - C/C++ code into Python in order to speed up a time-critical section of - Python code. - In this method of using weave, you define a string containing useful C-code - and then pass it to the function -\series bold -weave.inline -\series default -( -\family typewriter -code_string -\family default -, -\family typewriter -variables -\family default -), where code_string is a string of valid C/C++ code and variables is a - list of variables that should be passed in from Python. - The C/C++ code should refer to the variables with the same names as they - are defined with in Python. - If weave.line should return anything the the special value return_val should - be set to whatever object should be returned. - The following example shows how to use weave on basic Python objects -\end_layout - -\begin_layout LyX-Code -code = r""" -\newline -int i; -\newline -py::tuple results(2); -\newline -for (i=0; i<a.length(); i++) { -\newline - - a[i] = i; -\newline -} -\newline -results[0] = 3.0; -\newline -results[1] = 4.0; -\newline -return_val = results; -\newline -""" - -\newline -a = [None]*10 -\newline -res = weave.inline(code,['a']) -\end_layout - -\begin_layout Standard -The C++ code shown in the code string uses the name 'a' to refer to the - Python list that is passed in. - Because the Python List is a mutable type, the elements of the list itself - are modified by the C++ code. - A set of C++ classes are used to access Python objects using simple syntax. - -\end_layout - -\begin_layout Standard -The main advantage of using C-code, however, is to speed up processing on - an array of data. - Accessing a NumPy array in C++ code using weave, depends on what kind of - type converter is chosen in going from NumPy arrays to C++ code. - The default converter creates 5 variables for the C-code for every NumPy - array passed in to weave.inline. - The following table shows these variables which can all be used in the - C++ code. - The table assumes that -\family typewriter -myvar -\family default - is the name of the array in Python with data-type <dtype> (i.e. - float64, float32, int8, etc.) -\end_layout - -\begin_layout Standard -\align center -\begin_inset Tabular -<lyxtabular version="3" rows="6" columns="3"> -<features> -<column alignment="center" valignment="top" leftline="true" width="0"> -<column alignment="center" valignment="top" leftline="true" width="0"> -<column alignment="center" valignment="top" leftline="true" rightline="true" width="0"> -<row topline="true" bottomline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Variable -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Type -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Contents -\end_layout - -\end_inset -</cell> -</row> -<row topline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -myvar -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -<dtype>* -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Pointer to the first element of the array -\end_layout - -\end_inset -</cell> -</row> -<row topline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Nmyvar -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -npy_intp* -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -A pointer to the dimensions array -\end_layout - -\end_inset -</cell> -</row> -<row topline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Smyvar -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -npy_intp* -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -A pointer to the strides array -\end_layout - -\end_inset -</cell> -</row> -<row topline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -Dmyvar -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -int -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -The number of dimensions -\end_layout - -\end_inset -</cell> -</row> -<row topline="true" bottomline="true"> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -myvar_array -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -PyArrayObject* -\end_layout - -\end_inset -</cell> -<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> -\begin_inset Text - -\begin_layout Standard -The entire structure for the array -\end_layout - -\end_inset -</cell> -</row> -</lyxtabular> - -\end_inset - - -\end_layout - -\begin_layout Standard -The in-lined code can contain references to any of these variables as well - as to the standard macros MYVAR1(i), MYVAR2(i,j), MYVAR3(i,j,k), and MYVAR4(i,j -,k,l). - These name-based macros (they are the Python name capitalized followed - by the number of dimensions needed) will de-reference the memory for the - array at the given location with no error checking (be-sure to use the - correct macro and ensure the array is aligned and in correct byte-swap - order in order to get useful results). - The following code shows how you might use these variables and macros to - code a loop in C that computes a simple 2-d weighted averaging filter. -\end_layout - -\begin_layout LyX-Code -int i,j; -\newline -for(i=1;i<Na[0]-1;i++) { -\newline - for(j=1;j<Na[1]-1;j++) { -\newline - B2(i,j) - = A2(i,j) + (A2(i-1,j) + -\newline - A2(i+1,j)+A2(i,j-1) -\newline - - + A2(i,j+1))*0.5 -\newline - + (A2(i-1,j-1) -\newline - + - A2(i-1,j+1) -\newline - + A2(i+1,j-1) -\newline - + A2(i+1,j+1))*0.25 -\newline - - } -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout Standard -The above code doesn't have any error checking and so could fail with a - Python crash if, -\family typewriter -a -\family default - had the wrong number of dimensions, or -\family typewriter -b -\family default - did not have the same shape as -\family typewriter -a -\family default -. - However, it could be placed inside a standard Python function with the - necessary error checking to produce a robust but fast subroutine. -\end_layout - -\begin_layout Standard -One final note about weave.inline: if you have additional code you want to - include in the final extension module such as supporting function calls, - include statments, etc. - you can pass this code in as a string using the keyword support_code: -\family typewriter -weave.inline(code, variables, support_code=support) -\family default -. - If you need the extension module to link against an additional library - then you can also pass in distutils-style keyword arguments such as library_dir -s, libraries, and/or runtime_library_dirs which point to the appropriate - libraries and directories. - -\end_layout - -\begin_layout Subsection -Simplify creation of an extension module -\end_layout - -\begin_layout Standard -The inline function creates one extension module for each function to-be - inlined. - It also generates a lot of intermediate code that is duplicated for each - extension module. - If you have several related codes to execute in C, it would be better to - make them all separate functions in a single extension module with multiple - functions. - You can also use the tools weave provides to produce this larger extension - module. - In fact, the weave.inline function just uses these more general tools to - do its work. - -\end_layout - -\begin_layout Standard -The approach is to: -\end_layout - -\begin_layout Enumerate -construct a extension module object using ext_tools.ext_module( -\family typewriter -module_name -\family default -); -\end_layout - -\begin_layout Enumerate -create function objects using ext_tools.ext_function( -\family typewriter -func_name -\family default -, -\family typewriter -code -\family default -, -\family typewriter -variables -\family default -); -\end_layout - -\begin_layout Enumerate -(optional) add support code to the function using the .customize.add_support_code( -\family typewriter -support_code -\family default -) method of the function object; -\end_layout - -\begin_layout Enumerate -add the functions to the extension module object using the .add_function( -\family typewriter -func -\family default -) method; -\end_layout - -\begin_layout Enumerate -when all the functions are added, compile the extension with its .compile() - method. -\end_layout - -\begin_layout Standard -Several examples are available in the examples directory where weave is - installed on your system. - Look particularly at ramp2.py, increment_example.py and fibonacii.py -\end_layout - -\begin_layout Subsection -Conclusion -\end_layout - -\begin_layout Standard -Weave is a useful tool for quickly routines in C/C++ and linking them into - Python. - It's caching-mechanism allows for on-the-fly compilation which makes it - particularly attractive for in-house code. - Because of the requirement that the user have a C++-compiler, it can be - difficult (but not impossible) to distribute a package that uses weave - to other users who don't have a compiler installed. - Of course, weave could be used to construct an extension module which is - then distributed in the normal way -\emph on -( -\emph default -using a setup.py file). - While you can use weave to build larger extension modules with many methods, - creating methods with a variable-number of arguments is not possible. - Thus, for a more sophisticated module, you will still probably want a Python-la -yer that calls the weave-produced extension. - -\begin_inset LatexCommand index -name "weave|)" - -\end_inset - - -\end_layout - -\begin_layout Section -Pyrex -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "pyrex|(" - -\end_inset - -Pyrex is a way to write C-extension modules using Python-like syntax. - It is an interesting way to generate extension modules that is growing - in popularity, particularly among people who have rusty or non-existent - C-skills. - It does require the user to write the -\begin_inset Quotes eld -\end_inset - -interface -\begin_inset Quotes erd -\end_inset - - code and so is more time-consuming than SWIG or f2py if you are trying - to interface to a large library of code. - However, if you are writing an extension module that will include quite - a bit of your own algorithmic code, as well, then Pyrex is a good match. - A big weakness perhaps is the inability to easily and quickly access the - elements of a multidimensional array. - -\end_layout - -\begin_layout Standard -Notice that Pyrex is an extension-module generator only. - Unlike weave or f2py, it includes no automatic facility for compiling and - linking the extension module (which must be done in the usual fashion). - It does provide a modified distutils class called build_ext which lets - you build an extension module from a .pyx source. - Thus, you could write in a setup.py file -\end_layout - -\begin_layout LyX-Code -from Pyrex.Distutils import build_ext -\newline -from distutils.extension import Extension -\newline -from - distutils.core import setup -\newline - -\newline -import numpy -\newline -py_ext = Extension('mine', ['mine.pyx'], -\newline - - include_dirs=[numpy.get_include()]) -\newline - -\newline -setup(name='mine', description='Nothi -ng', -\newline - ext_modules=[pyx_ext], -\newline - cmdclass = {'build_ext':build_ext}) -\end_layout - -\begin_layout Standard -Adding the NumPy include directory is, of course, only necessary if you - are using NumPy arrays in the extension module (which is what I assume - you are using Pyrex for). - The distutils extensions in NumPy also include support for automatically - producing the extension-module and linking it from a -\family typewriter -.pyx -\family default - file. - It works so that if the user does not have Pyrex installed, then it looks - for a file with the same file-name but a -\family typewriter -.c -\family default - extension which it then uses instead of trying to produce the -\family typewriter -.c -\family default - file again. - -\end_layout - -\begin_layout Standard -Pyrex does not natively understand NumPy arrays. - However, it is not difficult to include information that lets Pyrex deal - with them usefully. - In fact, the numpy.random.mtrand module was written using Pyrex so an example - of Pyrex usage is already included in the NumPy source distribution. - That experience led to the creation of a standard c_numpy.pxd file that - you can use to simplify interacting with NumPy array objects in a Pyrex-written - extension. - The file may not be complete (it wasn't at the time of this writing). - If you have additions you'd like to contribute, please send them. - The file is located in the .../site-packages/numpy/doc/pyrex directory where - you have Python installed. - There is also an example in that directory of using Pyrex to construct - a simple extension module. - It shows that Pyrex looks a lot like Python but also contains some new - syntax that is necessary in order to get C-like speed. - -\end_layout - -\begin_layout Standard -If you just use Pyrex to compile a standard Python module, then you will - get a C-extension module that runs either as fast or, possibly, more slowly - than the equivalent Python module. - Speed increases are possible only when you use cdef to statically define - C variables and use a special construct to create for loops: -\end_layout - -\begin_layout LyX-Code -cdef int i -\newline -for i from start <= i < stop -\end_layout - -\begin_layout Standard -Let's look at two examples we've seen before to see how they might be implemente -d using Pyrex. - These examples were compiled into extension modules using Pyrex-0.9.3.1. -\end_layout - -\begin_layout Subsection -Pyrex-add -\end_layout - -\begin_layout Standard -Here is part of a Pyrex-file I named add.pyx which implements the add functions - we previously implemented using f2py: -\end_layout - -\begin_layout LyX-Code -cimport c_numpy -\newline -from c_numpy cimport import_array, ndarray, npy_intp, npy_cdouble -, -\backslash - -\newline - npy_cfloat, NPY_DOUBLE, NPY_CDOUBLE, NPY_FLOAT, -\backslash - -\newline - NPY_CFLOAT -\newline - -\newline -#We need to initialize NumPy -\newline -import_array() -\newline - -\newline -def zadd(object - ao, object bo): -\newline - cdef ndarray c, a, b -\newline - cdef npy_intp i -\newline - a = c_numpy.PyArra -y_ContiguousFromAny(ao, -\newline - NPY_CDOUBLE, 1, 1) -\newline - b = c_numpy.PyArr -ay_ContiguousFromAny(bo, -\newline - NPY_CDOUBLE, 1, 1) -\newline - c = c_numpy.PyAr -ray_SimpleNew(a.nd, a.dimensions, -\newline - a.descr.type_num) -\newline - for i - from 0 <= i < a.dimensions[0]: -\newline - (<npy_cdouble *>c.data)[i].real = -\backslash - -\newline - (<npy_cdouble *>a.data)[i].real + -\backslash - -\newline - (<npy_cdouble *>b.data)[i].real -\newline - (<npy_cdouble *>c.data)[i].imag - = -\backslash - -\newline - (<npy_cdouble *>a.data)[i].imag + -\backslash - -\newline - (<npy_cdouble *>b.data)[i].imag -\newline - return c -\end_layout - -\begin_layout Standard -This module shows use of the -\family typewriter -cimport -\family default - statement to load the definitions from the c_numpy.pxd file. - As shown, both versions of the import statement are supported. - It also shows use of the NumPy C-API to construct NumPy arrays from arbitrary - input objects. - The array c is created using PyArray_SimpleNew. - Then the c-array is filled by addition. - Casting to a particiular data-type is accomplished using <cast *>. - Pointers are de-referenced with bracket notation and members of structures - are accessed using '.' notation even if the object is techinically a pointer - to a structure. - The use of the special for loop construct ensures that the underlying code - will have a similar C-loop so the addition calculation will proceed quickly. - Notice that we have not checked for NULL after calling to the C-API --- - a cardinal sin when writing C-code. - For routines that return Python objects, Pyrex inserts the checks for NULL - into the C-code for you and returns with failure if need be. - There is also a way to get Pyrex to automatically check for exceptions - when you call functions that don't return Python objects. - See the documentation of Pyrex for details. - -\end_layout - -\begin_layout Subsection -Pyrex-filter -\end_layout - -\begin_layout Standard -The two-dimensional example we created using weave is a bit uglierto implement - in Pyrex because two-dimensional indexing using Pyrex is not as simple. - But, it is straightforward (and possibly faster because of pre-computed - indices). - Here is the Pyrex-file I named image.pyx. -\end_layout - -\begin_layout LyX-Code -cimport c_numpy -\newline -from c_numpy cimport import_array, ndarray, npy_intp, -\backslash - -\newline - NPY_DOUBLE, NPY_CDOUBLE, -\backslash - -\newline - NPY_FLOAT, NPY_CFLOAT, NPY_ALIGNED -\backslash - -\newline - -\newline -#We need to initialize NumPy -\newline -import_array() -\newline -def filter(object ao): -\newline - cdef - ndarray a, b -\newline - cdef npy_intp i, j, M, N, oS -\newline - cdef npy_intp r,rm1,rp1,c,cm1,c -p1 -\newline - cdef double value -\newline - # Require an ALIGNED array -\newline - # (but not necessarily - contiguous) -\newline - # We will use strides to access the elements. -\newline - a = c_numpy.PyAr -ray_FROMANY(ao, NPY_DOUBLE, -\backslash - -\newline - 2, 2, NPY_ALIGNED) -\newline - b = c_numpy.PyArray_SimpleNew(a.nd,a.dimensio -ns, -\backslash - -\newline - a.descr.type_num) -\newline - M = a.dimensions[0] -\newline - - N = a.dimensions[1] -\newline - S0 = a.strides[0] -\newline - S1 = a.strides[1] -\newline - for i - from 1 <= i < M-1: -\newline - r = i*S0 -\newline - rm1 = r-S0 -\newline - rp1 = r+S0 -\newline - - oS = i*N -\newline - for j from 1 <= j < N-1: -\newline - c = j*S1 -\newline - - cm1 = c-S1 -\newline - cp1 = c+S1 -\newline - (<double *>b.data)[oS+j] - = -\backslash - -\newline - (<double *>(a.data+r+c))[0] + -\backslash - -\newline - ((<double *>(a.data+rm1+c))[0] + -\backslash - -\newline - (<double *>(a.data+rp1+c))[0] + -\backslash - -\newline - (<double *>(a.data+r+cm1))[0] + -\backslash - -\newline - (<double *>(a.data+r+cp1))[0])*0.5 + -\backslash - -\newline - ((<double *>(a.data+rm1+cm1))[0] + -\backslash - -\newline - (<double *>(a.data+rp1+cm1))[0] + -\backslash - -\newline - (<double *>(a.data+rp1+cp1))[0] + -\backslash - -\newline - (<double *>(a.data+rm1+cp1))[0])*0.25 -\newline - return b -\end_layout - -\begin_layout Standard -This 2-d averaging filter runs quickly because the loop is in C and the - pointer computations are done only as needed. - However, it is not particularly easy to understand what is happening. - A 2-d image, -\family typewriter -in -\family default -, can be filtered using this code very quickly using -\end_layout - -\begin_layout LyX-Code -import image -\end_layout - -\begin_layout LyX-Code -out = image.filter(in) -\end_layout - -\begin_layout Subsection -Conclusion -\end_layout - -\begin_layout Standard -There are several disadvantages of using Pyrex: -\end_layout - -\begin_layout Enumerate -The syntax for Pyrex can get a bit bulky, and it can be confusing at first - to understand what kind of objects you are getting and how to interface - them with C-like constructs. - -\end_layout - -\begin_layout Enumerate -Inappropriate Pyrex syntax or incorrect calls to C-code or type-mismatches - can result in failures such as -\end_layout - -\begin_deeper -\begin_layout Enumerate -Pyrex failing to generate the extension module source code, -\end_layout - -\begin_layout Enumerate -Compiler failure while generating the extension module binary due to incorrect - C syntax, -\end_layout - -\begin_layout Enumerate -Python failure when trying to use the module. - -\end_layout - -\end_deeper -\begin_layout Enumerate -It is easy to lose a clean separation between Python and C which makes re-using - your C-code for other non-Python-related projects more difficult. -\end_layout - -\begin_layout Enumerate -Multi-dimensional arrays are -\begin_inset Quotes eld -\end_inset - -bulky -\begin_inset Quotes erd -\end_inset - - to index (appropriate macros may be able to fix this). - -\end_layout - -\begin_layout Enumerate -The C-code generated by Prex is hard to read and modify (and typically compiles - with annoying but harmless warnings). - -\end_layout - -\begin_layout Standard -Writing a good Pyrex extension module still takes a bit of effort because - not only does it require (a little) familiarity with C, but also with Pyrex's - brand of Python-mixed-with C. - One big advantage of Pyrex-generated extension modules is that they are - easy to distribute using distutils. - In summary, Pyrex is a very capable tool for either gluing C-code or generating - an extension module quickly and should not be over-looked. - It is especially useful for people that can't or won't write C-code or - Fortran code. - But, if you are already able to write simple subroutines in C or Fortran, - then I would use one of the other approaches such as f2py (for Fortran), - ctypes (for C shared-libraries), or weave (for inline C-code). -\begin_inset LatexCommand index -name "pyrex|)" - -\end_inset - - -\end_layout - -\begin_layout Section -ctypes -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ctypes|(" - -\end_inset - -Ctypes is a python extension module (downloaded separately for Python <2.5 - and included with Python 2.5) that allows you to call an arbitrary function - in a shared library directly from Python. - This approach allows you to interface with C-code directly from Python. - This opens up an enormous number of libraries for use from Python. - The drawback, however, is that coding mistakes can lead to ugly program - crashes very easily (just as can happen in C) because there is little type - or bounds checking done on the parameters. - This is especially true when array data is passed in as a pointer to a - raw memory location. - The responsibility is then on you that the subroutine will not access memory - outside the actual array area. - But, if you don't mind living a little dangerously ctypes can be an effective - tool for quickly taking advantage of a large shared library (or writing - extended functionality in your own shared library). -\end_layout - -\begin_layout Standard -Because the ctypes approach exposes a raw interface to the compiled code - it is not always tolerant of user mistakes. - Robust use of the ctypes module typically involves an additional layer - of Python code in order to check the data types and array bounds of objects - passed to the underlying subroutine. - This additional layer of checking (not to mention the conversion from ctypes - objects to C-data-types that ctypes itself performs), will make the interface - slower than a hand-written extension-module interface. - However, this overhead should be neglible if the C-routine being called - is doing any significant amount of work. - If you are a great Python programmer with weak C-skills, ctypes is an easy - way to write a useful interface to a (shared) library of compiled code. - -\end_layout - -\begin_layout Standard -To use c-types you must -\end_layout - -\begin_layout Enumerate -Have a shared library. -\end_layout - -\begin_layout Enumerate -Load the shared library. -\end_layout - -\begin_layout Enumerate -Convert the python objects to ctypes-understood arguments. -\end_layout - -\begin_layout Enumerate -Call the function from the library with the ctypes arguments. -\end_layout - -\begin_layout Subsection -Having a shared library -\end_layout - -\begin_layout Standard -There are several requirements for a shared library that can be used with - c-types that are platform specific. - This guide assumes you have some familiarity with making a shared library - on your system (or simply have a shared library available to you). - Items to remember are: -\end_layout - -\begin_layout Itemize -A shared library must be compiled in a special way ( -\emph on -e.g. - -\emph default - using the -shared flag with gcc). -\end_layout - -\begin_layout Itemize -On some platforms ( -\emph on -e.g. - -\emph default - Windows) , a shared library requires a .def file that specifies the functions - to be exported. - For example a mylib.def file might contain. - -\end_layout - -\begin_deeper -\begin_layout LyX-Code -LIBRARY mylib.dll -\newline -EXPORTS -\newline -cool_function1 -\newline -cool_function2 -\end_layout - -\begin_layout Standard -Alternatively, you may be able to use the storage-class specifier __declspec(dll -export) in the C-definition of the function to avoid the need for this .def - file. - -\end_layout - -\end_deeper -\begin_layout Standard -There is no standard way in Python distutils to create a standard shared - library (an extension module is a -\begin_inset Quotes eld -\end_inset - -special -\begin_inset Quotes erd -\end_inset - - shared library Python understands) in a cross-platform manner. - Thus, a big disadvantage of ctypes at the time of writing this book is - that it is difficult to distribute in a cross-platform manner a Python - extension that uses c-types and includes your own code which should be - compiled as a shared library on the users system. - -\end_layout - -\begin_layout Subsection -Loading the shared library -\end_layout - -\begin_layout Standard -A simple, but robust way to load the shared library is to get the absolute - path name and load it using the cdll object of ctypes. - -\end_layout - -\begin_layout LyX-Code -lib = ctypes.cdll[<full_path_name>] -\end_layout - -\begin_layout Standard -However, on Windows accessing an attribute of the cdll method will load - the first DLL by that name found in the current directory or on the PATH. - Loading the absolute path name requires a little finesse for cross-platform - work since the extension of shared libraries varies. - There is a -\family typewriter -ctypes.util.find_library -\family default - utility available that can simplify the process of finding the library - to load but it is not foolproof. - Complicating matters, different platforms have different default extensions - used by shared libraries (e.g. - .dll -- Windows, .so -- Linux, .dylib -- Mac OS X). - This must also be taken into account if you are using c-types to wrap code - that needs to work on several platforms. - -\end_layout - -\begin_layout Standard -NumPy provides a convenience function called -\series bold -ctypeslib.load_library -\series default -(name, path). - This function takes the name of the shared library (including any prefix - like 'lib' but excluding the extension) and a path where the shared library - can be located. - It returns a ctypes library object or raises an OSError if the library - cannot be found or raises an ImportError if the ctypes module is not available. - (Windows users: the ctypes library object loaded using -\series bold -load_library -\series default - is always loaded assuming cdecl calling convention. - See the ctypes documentation under ctypes.windll and/or ctypes.oledll for - ways to load libraries under other calling conventions). - -\end_layout - -\begin_layout Standard -The functions in the shared library are available as attributes of the ctypes - library object (returned from -\series bold -ctypeslib.load_library -\series default -) or as items using lib['func_name'] syntax. - The latter method for retrieving a function name is particularly useful - if the function name contains characters that are not allowable in Python - variable names. - -\end_layout - -\begin_layout Subsection -Converting arguments -\end_layout - -\begin_layout Standard -Python ints/longs, strings, and unicode objects are automatically converted - as needed to equivalent c-types arguments The None object is also converted - automatically to a NULL pointer. - All other Python objects must be converted to ctypes-specific types. - There are two ways around this restriction that allow c-types to integrate - with other objects. - -\end_layout - -\begin_layout Enumerate -Don't set the argtypes attribute of the function object and define an _as_parame -ter_ method for the object you want to pass in. - The _as_parameter_ method must return a Python int which will be passed - directly to the function. - -\end_layout - -\begin_layout Enumerate -Set the argtypes attribute to a list whose entries contain objects with - a classmethod named from_param that knows how to convert your object to - an object that ctypes can understand (an int/long, string, unicode, or - object with the _as_parameter_ attribute). - -\end_layout - -\begin_layout Standard -NumPy uses both methods with a preference for the second method because - it can be safer. - The ctypes attribute of the ndarray returns an object that has an _as_parameter -_ attribute which returns an integer representing the address of the ndarray - to which it is associated. - As a result, one can pass this ctypes attribute object directly to a function - expecting a pointer to the data in your ndarray. - The caller must be sure that the ndarray object is of the correct type, - shape, and has the correct flags set or risk nasty crashes if the data-pointer - to inappropriate arrays are passsed in. - -\end_layout - -\begin_layout Standard -To implement the second method, NumPy provides the class-factory function - -\series bold -ndpointer -\series default - in the -\series bold -ctypeslib -\series default - module. - This class-factory function produces an appropriate class that can be placed - in an argtypes attribute entry of a ctypes function. - The class will contain a from_param method which ctypes will use to convert - any ndarray passed in to the function to a ctypes-recognized object. - In the process, the conversion will perform checking on any properties - of the ndarray that were specified by the user in the call to ndpointer. - Aspects of the ndarray that can be checked include the data-type, the number-of --dimensions, the shape, and/or the state of the flags on any array passed. - The return value of the from_param method is the ctypes attribute of the - array which (because it contains the _as_parameter_ attribute pointing - to the array data area) can be used by ctypes directly. - -\end_layout - -\begin_layout Standard -The ctypes attribute of an ndarray is also endowed with additional attributes - that may be convenient when passing additional information about the array - into a ctypes function. - The attributes -\series bold -data -\series default -, -\series bold -shape -\series default -, and -\series bold -strides -\series default - can provide c-types compatible types corresponding to the data-area, the - shape, and the strides of the array. - The data attribute reutrns a -\family typewriter -c_void_p -\family default - representing a pointer to the data area. - The shape and strides attributes each return an array of ctypes integers - (or None representing a NULL pointer, if a 0-d array). - The base ctype of the array is a ctype integer of the same size as a pointer - on the platform. - There are also methods data_as(<ctype>), shape_as(<base ctype>), and strides_as -(<base ctype>). - These return the data as a ctype object of your choice and the shape/strides - arrays using an underlying base type of your choice. - For convenience, the -\series bold -ctypeslib -\series default - module also contains -\series bold -c_intp -\series default - as a ctypes integer data-type whose size is the same as the size of -\family typewriter -c_void_p -\family default - on the platform (it's value is None if ctypes is not installed). - -\end_layout - -\begin_layout Subsection -Calling the function -\end_layout - -\begin_layout Standard -The function is accessed as an attribute of or an item from the loaded shared-li -brary. - Thus, if -\begin_inset Quotes eld -\end_inset - -./mylib.so -\begin_inset Quotes erd -\end_inset - - has a function named -\begin_inset Quotes eld -\end_inset - -cool_function1 -\begin_inset Quotes erd -\end_inset - -, I could access this function either as -\end_layout - -\begin_layout LyX-Code -lib = numpy.ctypeslib.load_library('mylib','.') -\newline -func1 = lib.cool_function1 # - or equivalently -\newline -func1 = lib['cool_function1'] -\end_layout - -\begin_layout Standard -In ctypes, the return-value of a function is set to be 'int' by default. - This behavior can be changed by setting the restype attribute of the function. - Use None for the restype if the function has no return value ('void'): -\end_layout - -\begin_layout LyX-Code -func1.restype = None -\end_layout - -\begin_layout Standard -As previously discussed, you can also set the argtypes attribute of the - function in order to have ctypes check the types of the input arguments - when the function is called. - Use the ndpointer factory function to generate a ready-made class for data-type -, shape, and flags checking on your new function. - The ndpointer function has the signature -\end_layout - -\begin_layout Description -ndpointer (dtype=None, ndim=None, shape=None, flags=None) -\end_layout - -\begin_layout Description -\InsetSpace ~ - Keyword arguments with the value -\family typewriter -None -\family default - are not checked. - Specifying a keyword enforces checking of that aspect of the ndarray on - conversion to a ctypes-compatible object. - The dtype keyword can be any object understood as a data-type object. - The ndim keyword should be an integer, and the shape keyword should be - an integer or a sequence of integers. - The flags keyword specifies the minimal flags that are required on any - array passed in. - This can be specified as a string of comma separated requirements, an integer - indicating the requirement bits OR'd together, or a flags object returned - from the flags attribute of an array with the necessary requirements. - -\end_layout - -\begin_layout Standard -Using an ndpointer class in the argtypes method can make it significantly - safer to call a C-function using ctypes and the data-area of an ndarray. - You may still want to wrap the function in an additional Python wrapper - to make it user-friendly (hiding some obvious arguments and making some - arguments output arguments). - In this process, the -\series bold -requires -\series default - function in NumPy may be useful to return the right kind of array from - a given input. - -\end_layout - -\begin_layout Subsection -Complete example -\end_layout - -\begin_layout Standard -In this example, I will show how the addition function and the filter function - implemented previously using the other approaches can be implemented using - ctypes. - First, the C-code which implements the algorithms contains the functions - zadd, dadd, sadd, cadd, and dfilter2d. - The zadd function is -\end_layout - -\begin_layout LyX-Code -/* Add arrays of contiguous data */ -\newline -typedef struct {double real; double imag;} - cdouble; -\newline -typedef struct {float real; float imag;} cfloat; -\newline -void zadd(cdouble - *a, cdouble *b, cdouble *c, long n) -\newline -{ -\newline - while (n--) { -\newline - c->real = - a->real + b->real; -\newline - c->imag = a->imag + b->imag; -\newline - a++; b++; - c++; -\newline - } -\newline -} -\end_layout - -\begin_layout Standard -with similar code for cadd, dadd, and sadd that handles complex float, double, - and float data-types, respectively: -\end_layout - -\begin_layout LyX-Code -void cadd(cfloat *a, cfloat *b, cfloat *c, long n) -\newline -{ -\newline - while (n--) { -\newline - - c->real = a->real + b->real; -\newline - c->imag = a->imag - + b->imag; -\newline - a++; b++; c++; -\newline - } -\newline -} -\newline -void dadd(double - *a, double *b, double *c, long n) -\newline -{ -\newline - while (n--) { -\newline - - *c++ = *a++ + *b++; -\newline - } -\newline -} -\newline -void sadd(float *a, float *b, float - *c, long n) -\newline -{ -\newline - while (n--) { -\newline - *c++ = *a++ + *b++; -\newline - - } -\newline -} -\end_layout - -\begin_layout Standard -The code.c file also contains the function dfilter2d: -\end_layout - -\begin_layout LyX-Code -/* Assumes b is contiguous and -\newline - a has strides that are multiples of sizeof(dou -ble) -\newline -*/ -\newline -void -\newline -dfilter2d(double *a, double *b, int *astrides, int *dims) -\newline -{ -\newline - - int i, j, M, N, S0, S1; -\newline - int r, c, rm1, rp1, cp1, cm1; -\newline - -\newline - M = dims[0]; - N = dims[1]; -\newline - S0 = astrides[0]/sizeof(double); -\newline - S1=astrides[1]/sizeof(doub -le); -\newline - for (i=1; i<M-1; i++) { -\newline - r = i*S0; rp1 = r+S0; rm1 = r-S0; -\newline - - for (j=1; j<N-1; j++) { -\newline - c = j*S1; cp1 = j+S1; cm1 = j-S1; -\newline - - b[i*N+j] = a[r+c] + -\backslash - -\newline - (a[rp1+c] + a[rm1+c] + -\backslash - -\newline - a[r+cp1] + a[r+cm1])*0.5 + -\backslash - -\newline - (a[rp1+cp1] + a[rp1+cm1] + -\backslash - -\newline - a[rm1+cp1] + a[rm1+cp1])*0.25; -\newline - } -\newline - } -\newline -} -\end_layout - -\begin_layout Standard -A possible advantage this code has over the Fortran-equivalent code is that - it takes arbitrarily strided (i.e. - non-contiguous arrays) and may also run faster depending on the optimization - capability of your compiler. - But, it is a obviously more complicated than the simple code in filter.f. - This code must be compiled into a shared library. - On my Linux system this is accomplished using -\end_layout - -\begin_layout LyX-Code -gcc -o code.so -shared code.c -\end_layout - -\begin_layout Standard -Which creates a shared_library named code.so in the current directory. - On Windows don't forget to either add __declspec(dllexport) in front of - void on the line preceeding each function definition, or write a code.def - file that lists the names of the functions to be exported. - -\end_layout - -\begin_layout Standard -A suitable Python interface to this shared library should be constructed. - To do this create a file named interface.py with the following lines at - the top: -\end_layout - -\begin_layout LyX-Code -__all__ = ['add', 'filter2d'] -\newline - -\newline -import numpy as N -\newline -import os -\newline - -\newline -_path = os.path.dirname('__ -file__') -\newline -lib = N.ctypeslib.load_library('code', _path) -\newline -_typedict = {'zadd' : - complex, 'sadd' : N.single, -\newline - 'cadd' : N.csingle, 'dadd' : float} -\newline -for - name in _typedict.keys(): -\newline - val = getattr(lib, name) -\newline - val.restype = None -\newline - - _type = _typedict[name] -\newline - val.argtypes = [N.ctypeslib.ndpointer(_type, - -\newline - flags='aligned, contiguous'), -\newline - - N.ctypeslib.ndpointer(_type, -\newline - flags='aligned, contiguous'), -\newline - - N.ctypeslib.ndpointer(_type, -\newline - flags='alig -ned, contiguous,' -\backslash - -\newline - 'writeable'), -\newline - N.ctypeslib.c_intp] -\end_layout - -\begin_layout Standard -This code loads the shared library named code.<ext> located in the same path - as this file. - It then adds a return type of void to the functions contained in the library. - It also adds argument checking to the functions in the library so that - ndarrays can be passed as the first three arguments along with an integer - (large enough to hold a pointer on the platform) as the fourth argument. - -\end_layout - -\begin_layout Standard -Setting up the filtering function is similar and allows the filtering function - to be called with ndarray arguments as the first two arguments and with - pointers to integers (large enough to handle the strides and shape of an - ndarray) as the last two arguments. - -\end_layout - -\begin_layout LyX-Code -lib.dfilter2d.restype=None -\newline -lib.dfilter2d.argtypes = [N.ctypeslib.ndpointer(float, - ndim=2, -\newline - flags='aligned'), -\newline - - N.ctypeslib.ndpointer(float, ndim=2, -\newline - - flags='aligned, contiguous,' -\backslash - -\newline - 'writeable'), -\newline - - ctypes.POINTER(N.ctypeslib.c_intp), -\newline - ctypes.POINTER -(N.ctypeslib.c_intp)] -\end_layout - -\begin_layout Standard -Next, define a simple selection function that chooses which addition function - to call in the shared library based on the data-type: -\end_layout - -\begin_layout LyX-Code -def select(dtype): -\newline - if dtype.char in ['?bBhHf']: -\newline - return lib.sadd, - single -\newline - elif dtype.char in ['F']: -\newline - return lib.cadd, csingle -\newline - elif - dtype.char in ['DG']: -\newline - return lib.zadd, complex -\newline - else: -\newline - return - lib.dadd, float -\newline - return func, ntype -\end_layout - -\begin_layout Standard -Finally, the two functions to be exported by the interface can be written - simply as -\end_layout - -\begin_layout LyX-Code -def add(a, b): -\newline - requires = ['CONTIGUOUS', 'ALIGNED'] -\newline - a = N.asanyarray(a) -\newline - - func, dtype = select(a.dtype) -\newline - a = N.require(a, dtype, requires) -\newline - - b = N.require(b, dtype, requires) -\newline - c = N.empty_like(a) -\newline - func(a,b,c,a.size) -\newline - - return c -\end_layout - -\begin_layout Standard -and -\end_layout - -\begin_layout LyX-Code -def filter2d(a): -\newline - a = N.require(a, float, ['ALIGNED']) -\newline - b = N.zeros_like(a) -\newline - - lib.dfilter2d(a, b, a.ctypes.strides, a.ctypes.shape) -\newline - return b -\end_layout - -\begin_layout Subsection -Conclusion -\end_layout - -\begin_layout Standard -Using ctypes is a powerful way to connect Python with arbitrary C-code. - It's advantages for extending Python include -\end_layout - -\begin_layout Itemize -clean separation of C-code from Python code -\end_layout - -\begin_deeper -\begin_layout Itemize -no need to learn a new syntax except Python and C -\end_layout - -\begin_layout Itemize -allows re-use of C-code -\end_layout - -\begin_layout Itemize -functionality in shared libraries written for other purposes can be obtained - with a simple Python wrapper and search for the library. - -\end_layout - -\end_deeper -\begin_layout Itemize -easy integration with NumPy through the ctypes attribute -\end_layout - -\begin_layout Itemize -full argument checking with the ndpointer class factory -\end_layout - -\begin_layout Standard -It's disadvantages include -\end_layout - -\begin_layout Itemize -It is difficult to distribute an extension module made using ctypes because - of a lack of support for building shared libraries in distutils (but I - suspect this will change in time). - -\end_layout - -\begin_layout Itemize -You must have shared-libraries of your code (no static libraries). - -\end_layout - -\begin_layout Itemize -Very little support for C++ code and it's different library-calling conventions. - You will probably need a C-wrapper around C++ code to use with ctypes (or - just use Boost.Python instead). -\end_layout - -\begin_layout Standard -Because of the difficulty in distributing an extension module made using - ctypes, f2py is still the easiest way to extend Python for package creation. - However, ctypes is a close second and will probably be growing in popularity - now that it is part of the Python distribution. - This should bring more features to ctypes that should eliminate the difficulty - in extending Python and distributing the extension using ctypes. - -\begin_inset LatexCommand index -name "ctypes|)" - -\end_inset - - -\end_layout - -\begin_layout Section -Additional tools you may find useful -\end_layout - -\begin_layout Standard -These tools have been found useful by others using Python and so are included - here. - They are discussed separately because I see them as either older ways to - do things more modernly handled by f2py, weave, Pyrex, or ctypes (SWIG, - PyFort, PyInline) or because I don't know much about them (SIP, Boost, - Instant). - I have not added links to these methods because my experience is that you - can find the most relevant link faster using Google or some other search - engine, and any links provided here would be quickly dated. - Do not assume that just because it is included in this list, I don't think - the package deserves your attention. - I'm including information about these packages because many people have - found them useful and I'd like to give you as many options as possible - for tackling the problem of easily integrating your code. - -\end_layout - -\begin_layout Subsection -SWIG -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "swig" - -\end_inset - -Simplified Wrapper and Interface Generator (SWIG) is an old and fairly stable - method for wrapping C/C++-libraries to a large variety of other languages. - It does not specifically understand NumPy arrays but can be made useable - with NumPy through the use of typemaps. - There are some sample typemaps in the numpy/doc/swig directory under numpy.i - along with an example module that makes use of them. - SWIG excels at wrapping large C/C++ libraries because it can (almost) parse - their headers and auto-produce an interface. - Technically, you need to generate a -\family typewriter -.i -\family default - file that defines the interface. - Often, however, this -\family typewriter -.i -\family default - file can be parts of the header itself. - The interface usually needs a bit of tweaking to be very useful. - This ability to parse C/C++ headers and auto-generate the interface still - makes SWIG a useful approach to adding functionalilty from C/C++ into Python, - despite the other methods that have emerged that are more targeted to Python. - SWIG can actually target extensions for several languages, but the typemaps - usually have to be language-specific. - Nonetheless, with modifications to the Python-specific typemaps, SWIG can - be used to interface a library with other languages such as Perl, Tcl, - and Ruby. - -\end_layout - -\begin_layout Standard -My experience with SWIG has been generally positive in that it is relatively - easy to use and quite powerful. - I used to use it quite often before becoming more proficient at writing - C-extensions. - However, I struggled writing custom interfaces with SWIG because it must - be done using the concept of typemaps which are not Python specific and - are written in a C-like syntax. - Therefore, I tend to prefer other gluing strategies and would only attempt - to use SWIG to wrap a very-large C/C++ library. - Nonetheless, there are others who use SWIG quite happily. - -\end_layout - -\begin_layout Subsection -SIP -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "SIP" - -\end_inset - -SIP is another tool for wrapping C/C++ libraries that is Python specific - and appears to have very good support for C++. - Riverbank Computing developed SIP in order to create Python bindings to - the QT library. - An interface file must be written to generate the binding, but the interface - file looks a lot like a C/C++ header file. - While SIP is not a full C++ parser, it understands quite a bit of C++ syntax - as well as its own special directives that allow modification of how the - Python binding is accomplished. - It also allows the user to define mappings between Python types and C/C++ - structrues and classes. - -\end_layout - -\begin_layout Subsection -Boost Python -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "Boost.Python" - -\end_inset - -Boost is a repository of C++ libraries and Boost.Python is one of those libraries - which provides a concise interface for binding C++ classes and functions - to Python. - The amazing part of the Boost.Python approach is that it works entirely - in pure C++ without introducing a new syntax. - Many users of C++ report that Boost.Python makes it possible to combine - the best of both worlds in a seamless fashion. - I have not used Boost.Python because I am not a big user of C++ and using - Boost to wrap simple C-subroutines is usually over-kill. - It's primary purpose is to make C++ classes available in Python. - So, if you have a set of C++ classes that need to be integrated cleanly - into Python, consider learning about and using Boost.Python. -\end_layout - -\begin_layout Subsection -Instant -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "Instant" - -\end_inset - -This is a relatively new package (called pyinstant at sourceforge) that - builds on top of SWIG to make it easy to inline C and C++ code in Python - very much like weave. - However, Instant builds extension modules on the fly with specific module - names and specific method names. - In this repsect it is more more like f2py in its behavior. - The extension modules are built on-the fly (as long as the SWIG is installed). - They can then be imported. - Here is an example of using Instant with NumPy arrays (adapted from the - test2 included in the Instant distribution): -\end_layout - -\begin_layout LyX-Code -code=""" -\end_layout - -\begin_layout LyX-Code -PyObject* add(PyObject* a_, PyObject* b_){ -\end_layout - -\begin_layout LyX-Code - /* -\end_layout - -\begin_layout LyX-Code - various checks -\end_layout - -\begin_layout LyX-Code - */ -\end_layout - -\begin_layout LyX-Code - PyArrayObject* a=(PyArrayObject*) a_; -\end_layout - -\begin_layout LyX-Code - PyArrayObject* b=(PyArrayObject*) b_; -\end_layout - -\begin_layout LyX-Code - int n = a->dimensions[0]; -\end_layout - -\begin_layout LyX-Code - int dims[1]; -\end_layout - -\begin_layout LyX-Code - dims[0] = n; -\end_layout - -\begin_layout LyX-Code - PyArrayObject* ret; -\end_layout - -\begin_layout LyX-Code - ret = (PyArrayObject*) PyArray_FromDims(1, dims, NPY_DOUBLE); -\end_layout - -\begin_layout LyX-Code - int i; -\end_layout - -\begin_layout LyX-Code - char *aj=a->data; -\end_layout - -\begin_layout LyX-Code - char *bj=b->data; -\end_layout - -\begin_layout LyX-Code - double *retj = (double *)ret->data; -\end_layout - -\begin_layout LyX-Code - for (i=0; i < n; i++) { -\end_layout - -\begin_layout LyX-Code - *retj++ = *((double *)aj) + *((double *)bj); -\end_layout - -\begin_layout LyX-Code - aj += a->strides[0]; -\end_layout - -\begin_layout LyX-Code - bj += b->strides[0]; -\end_layout - -\begin_layout LyX-Code - } -\end_layout - -\begin_layout LyX-Code -return (PyObject *)ret; -\end_layout - -\begin_layout LyX-Code -} -\end_layout - -\begin_layout LyX-Code -""" -\end_layout - -\begin_layout LyX-Code -import Instant, numpy -\end_layout - -\begin_layout LyX-Code -ext = Instant.Instant() -\end_layout - -\begin_layout LyX-Code -ext.create_extension(code=s, headers=["numpy/arrayobject.h"], - include_dirs=[numpy.get_include()], - init_code='import_array();', module="test2b_ext -") -\end_layout - -\begin_layout LyX-Code -import test2b_ext -\end_layout - -\begin_layout LyX-Code -a = numpy.arange(1000) -\end_layout - -\begin_layout LyX-Code -b = numpy.arange(1000) -\end_layout - -\begin_layout LyX-Code -d = test2b_ext.add(a,b) -\end_layout - -\begin_layout Standard -Except perhaps for the dependence on SWIG, Instant is a straightforward - utility for writing extension modules. - -\end_layout - -\begin_layout Subsection -PyInline -\end_layout - -\begin_layout Standard -This is a much older module that allows automatic building of extension - modules so that C-code can be included with Python code. - It's latest release (version 0.03) was in 2001, and it appears that it is - not being updated. - -\end_layout - -\begin_layout Subsection -PyFort -\end_layout - -\begin_layout Standard -PyFort is a nice tool for wrapping Fortran and Fortran-like C-code into - Python with support for Numeric arrays. - It was written by Paul Dubois, a distinguished computer scientist and the - very first maintainer of Numeric (now retired). - It is worth mentioning in the hopes that somebody will update PyFort to - work with NumPy arrays as well which now support either Fortran or C-style - contiguous arrays. - -\end_layout - -\begin_layout Chapter -Code Explanations -\end_layout - -\begin_layout Quotation -Fanaticism consists of redoubling your efforts when you have forgotten your - aim. -\end_layout - -\begin_layout Right Address ---- -\emph on -George Santayana -\end_layout - -\begin_layout Quotation -An authority is a person who can tell you more about something than you - really care to know. -\end_layout - -\begin_layout Right Address ---- -\emph on -Unknown -\end_layout - -\begin_layout Standard -This Chapter attempts to explain the logic behind some of the new pieces - of code. - The purpose behind these explanations is to enable somebody to be able - to understand the ideas behind the implementation somewhat more easily - than just staring at the code. - Perhaps in this way, the algorithms can be improved on, borrowed from, - and/or optimized. - -\end_layout - -\begin_layout Section -Memory model -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ndarray!memory model" - -\end_inset - -One fundamental aspect of the ndarray is that an array is seen as a -\begin_inset Quotes eld -\end_inset - -chunk -\begin_inset Quotes erd -\end_inset - - of memory starting at some location. - The interpretation of this memory depends on the stride information. - For each dimension in an -\begin_inset Formula $N$ -\end_inset - --dimensional array, an integer (stride) dictates how many bytes must be - skipped to get to the next element in that dimension. - Unless you have a single-segment array, this stride information must be - consulted when traversing through an array. - It is not difficult to write code that accepts strides, you just have to - use (char *) pointers because strides are in units of bytes. - Keep in mind also that strides do not have to be unit-multiples of the - element size. - Also, remember that if the number of dimensions of the array is 0 (sometimes - called a rank-0 array), then the strides and dimensions variables are NULL. - -\end_layout - -\begin_layout Standard -Besides the structural information contained in the strides and dimensions - members of the PyArrayObject, the flags contain important information about - how the data may be accessed. - In particular, the NPY_ALIGNED flag is set when the memory is on a suitable - boundary according to the data-type array. - Even if you have a contiguous chunk of memory, you cannot just assume it - is safe to dereference a data-type-specific pointer to an element. - Only if the NPY_ALIGNED flag is set is this a safe operation (on some platforms - it will work but on others, like Solaris, it will cause a bus error). - The NPY_WRITEABLE should also be ensured if you plan on writing to the - memory area of the array. - It is also possible to obtain a pointer to an unwriteable memory area. - Sometimes, writing to the memory area when the NPY_WRITEABLE flag is not - set will just be rude. - Other times it can cause program crashes ( -\emph on -e.g. - -\emph default - a data-area that is a read-only memory-mapped file). -\end_layout - -\begin_layout Section -Data-type encapsulation -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "dtype" - -\end_inset - -The data-type is an important abstraction of the ndarray. - Operations will look to the data-type to provide the key functionality - that is needed to operate on the array. - This functionality is provided in the list of function pointers pointed - to by the 'f' member of the PyArray_Descr structure. - In this way, the number of data-types can be extended simply by providing - a PyArray_Descr structure with suitable function pointers in the 'f' member. - For built-in types there are some optimizations that by-pass this mechanism, - but the point of the data-type abstraction is to allow new data-types to - be added. -\end_layout - -\begin_layout Standard -One of the built-in data-types, the void data-type allows for arbitrary - records containing 1 or more fields as elements of the array. - A field is simply another data-type object along with an offset into the - current record. - In order to support arbitrarily nested fields, several recursive implementation -s of data-type access are implemented for the void type. - A common idiom is to cycle through the elements of the dictionary and perform - a specific operation based on the data-type object stored at the given - offset. - These offsets can be arbitrary numbers. - Therefore, the possibility of encountering mis-aligned data must be recognized - and taken into account if necessary. - -\end_layout - -\begin_layout Section -N-D Iterators -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "array iterator" - -\end_inset - -A very common operation in much of NumPy code is the need to iterate over - all the elements of a general, strided, N-dimensional array. - This operation of a general-purpose N-dimensional loop is abstracted in - the notion of an iterator object. - To write an N-dimensional loop, you only have to create an iterator object - from an ndarray, work with the dataptr member of the iterator object structure - and call the macro PyArray_ITER_NEXT(it) on the iterator object to move - to the next element. - The -\begin_inset Quotes eld -\end_inset - -next -\begin_inset Quotes erd -\end_inset - - element is always in C-contiguous order. - The macro works by first special casing the C-contiguous, 1-d, and 2-d - cases which work very simply. - -\end_layout - -\begin_layout Standard -For the general case, the iteration works by keeping track of a list of - coordinate counters in the iterator object. - At each iteration, the last coordinate counter is increased (starting from - 0). - If this counter is smaller then one less than the size of the array in - that dimension (a pre-computed and stored value), then the counter is increased - and the dataptr member is increased by the strides in that dimension and - the macro ends. - If the end of a dimension is reached, the counter for the last dimension - is reset to zero and the dataptr is moved back to the beginning of that - dimension by subtracting the strides value times one less than the number - of elements in that dimension (this is also pre-computed and stored in - the backstrides member of the iterator object). - In this case, the macro does not end, but a local dimension counter is - decremented so that the next-to-last dimension replaces the role that the - last dimension played and the previously-described tests are executed again - on the next-to-last dimension. - In this way, the dataptr is adjusted appropriately for arbitrary striding. - -\end_layout - -\begin_layout Standard -The coordinates member of the PyArrayIterObject structure maintains the - current N-d counter unless the underlying array is C-contiguous in which - case the coordinate counting is by-passed. - The index member of the PyArrayIterObject keeps track of the current flat - index of the iterator. - It is updated by the PyArray_ITER_NEXT macro. - -\end_layout - -\begin_layout Section -Broadcasting -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "broadcasting" - -\end_inset - -In Numeric, broadcasting was implemented in several lines of code buried - deep in ufuncobject.c. - In NumPy, the notion of broadcasting has been abstracted so that it can - be performed in multiple places. - Broadcasting is handled by the function PyArray_Broadcast. - This function requires a PyArrayMultiIterObject (or something that is a - binary equivalent) to be passed in. - The PyArrayMultiIterObject keeps track of the broadcasted number of dimensions - and size in each dimension along with the total size of the broadcasted - result. - It also keeps track of the number of arrays being broadcast and a pointer - to an iterator for each of the arrays being broadcasted. - -\end_layout - -\begin_layout Standard -The PyArray_Broadcast function takes the iterators that have already been - defined and uses them to determine the broadcast shape in each dimension - (to create the iterators at the same time that broadcasting occurs then - use the PyMuliIter_New function). - Then, the iterators are adjusted so that each iterator thinks it is iterating - over an array with the broadcasted size. - This is done by adjusting the iterators number of dimensions, and the shape - in each dimension. - This works because the iterator strides are also adjusted. - Broadcasting only adjusts (or adds) length-1 dimensions. - For these dimensions, the strides variable is simply set to 0 so that the - data-pointer for the iterator over that array doesn't move as the broadcasting - operation operates over the extended dimension. - -\end_layout - -\begin_layout Standard -Broadcasting was always implemented in Numeric using 0-valued strides for - the extended dimensions. - It is done in exactly the same way in NumPy. - The big difference is that now the array of strides is kept track of in - a PyArrayIterObject, the iterators involved in a broadcasted result are - kept track of in a PyArrayMultiIterObject, and the PyArray_BroadCast call - implements the broad-casting rules. - -\end_layout - -\begin_layout Section -Array Scalars -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "array scalars" - -\end_inset - -The array scalars offer a hierarchy of Python types that allow a one-to-one - correspondence between the data-type stored in an array and the Python-type - that is returned when an element is extracted from the array. - An exception to this rule was made with object arrays. - Object arrays are heterogeneous collections of arbitrary Python objects. - When you select an item from an object array, you get back the original - Python object (and not an object array scalar which does exist but is rarely - used for practical purposes). -\end_layout - -\begin_layout Standard -The array scalars also offer the same methods and attributes as arrays with - the intent that the same code can be used to support arbitrary dimensions - (including 0-dimensions). - The array scalars are read-only (immutable) with the exception of the void - scalar which can also be written to so that record-array field setting - works more naturally (a[0]['f1'] = -\family typewriter -value -\family default -). -\end_layout - -\begin_layout Section -Advanced ( -\begin_inset Quotes eld -\end_inset - -Fancy -\begin_inset Quotes erd -\end_inset - -) Indexing -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "indexing" - -\end_inset - -The implementation of advanced indexing represents some of the most difficult - code to write and explain. - In fact, there are two implementations of advanced indexing. - The first works only with 1-d arrays and is implemented to handle expressions - involving a.flat[obj]. - The second is general-purpose that works for arrays of -\begin_inset Quotes eld -\end_inset - -arbitrary dimension -\begin_inset Quotes erd -\end_inset - - (up to a fixed maximum). - The one-dimensional indexing approaches were implemented in a rather straightfo -rward fashion, and so it is the general-purpose indexing code that will - be the focus of this section. - -\end_layout - -\begin_layout Standard -There is a multi-layer approach to indexing because the indexing code can - at times return an array scalar and at other times return an array. - The functions with -\begin_inset Quotes eld -\end_inset - -_nice -\begin_inset Quotes erd -\end_inset - - appended to their name do this special handling while the function without - the _nice appendage always return an array (perhaps a 0-dimensional array). - Some special-case optimizations (the index being an integer scalar, and - the index being a tuple with as many dimensions as the array) are handled - in array_subscript_nice function which is what Python calls when presented - with the code -\begin_inset Quotes eld -\end_inset - -a[obj]. -\begin_inset Quotes erd -\end_inset - - These optimizations allow fast single-integer indexing, and also ensure - that a 0-dimensional array is not created only to be discarded as the array - scalar is returned instead. - This provides significant speed-up for code that is selecting many scalars - out of an array (such as in a loop). - However, it is still not faster than simply using a list to store standard - Python scalars, because that is optimized by the Python interpreter itself. - -\end_layout - -\begin_layout Standard -After these optimizations, the array_subscript function itself is called. - This function first checks for field selection which occurs when a string - is passed as the indexing object. - Then, 0-d arrays are given special-case consideration. - Finally, the code determines whether or not advanced, or fancy, indexing - needs to be performed. - If fancy indexing is not needed, then standard view-based indexing is performed - using code borrowed from Numeric which parses the indexing object and returns - the offset into the data-buffer and the dimensions necessary to create - a new view of the array. - The strides are also changed by multiplying each stride by the step-size - requested along the corresponding dimension. - -\end_layout - -\begin_layout Subsection -Fancy-indexing check -\end_layout - -\begin_layout Standard -The fancy_indexing_check routine determines whether or not to use standard - view-based indexing or new copy-based indexing. - If the indexing object is a tuple, then view-based indexing is assumed - by default. - Only if the tuple contains an array object or a sequence object is fancy-indexi -ng assumed. - If the indexing object is an array, then fancy indexing is automatically - assumed. - If the indexing object is any other kind of sequence, then fancy-indexing - is assumed by default. - This is over-ridden to simple indexing if the sequence contains any slice, - newaxis, or Ellipsis objects, and no arrays or additional sequences are - also contained in the sequence. - The purpose of this is to allow the construction of -\begin_inset Quotes eld -\end_inset - -slicing -\begin_inset Quotes erd -\end_inset - - sequences which is a common technique for building up code that works in - arbitrary numbers of dimensions. - -\end_layout - -\begin_layout Subsection -Fancy-indexing implementation -\end_layout - -\begin_layout Standard -The concept of indexing was also abstracted using the idea of an iterator. - If fancy indexing is performed, then a PyArrayMapIterObject is created. - This internal object is not exposed to Python. - It is created in order to handle the fancy-indexing at a high-level. - Both get and set fancy-indexing operations are implemented using this object. - Fancy indexing is abstracted into three separate operations: (1) creating - the PyArrayMapIterObject from the indexing object, (2) binding the PyArrayMapIt -erObject to the array being indexed, and (3) getting (or setting) the items - determined by the indexing object. - There is an optimization implemented so that the PyArrayIterObject (which - has it's own less complicated fancy-indexing) is used for indexing when - possible. - -\end_layout - -\begin_layout Subsubsection -Creating the mapping object -\end_layout - -\begin_layout Standard -The first step is to convert the indexing objects into a standard form where - iterators are created for all of the index array inputs and all Boolean - arrays are converted to equivalent integer index arrays (as if nonzero(arr) - had been called). - Finally, all integer arrays are replaced with the integer 0 in the indexing - object and all of the index-array iterators are -\begin_inset Quotes eld -\end_inset - -broadcast -\begin_inset Quotes erd -\end_inset - - to the same shape. - -\end_layout - -\begin_layout Subsubsection -Binding the mapping object -\end_layout - -\begin_layout Standard -When the mapping object is created it does not know which array it will - be used with so once the index iterators are constructed during mapping-object - creation, the next step is to associate these iterators with a particular - ndarray. - This process interprets any ellipsis and slice objects so that the index - arrays are associated with the appropriate axis (the axis indicated by - the iteraxis entry corresponding to the iterator for the integer index - array). - This information is then used to check the indices to be sure they are - within range of the shape of the array being indexed. - The presence of ellipsis and/or slice objects implies a sub-space iteration - that is accomplished by extracting a sub-space view of the array (using - the index object resulting from replacing all the integer index arrays - with 0) and storing the information about where this sub-space starts in - the mapping object. - This is used later during mapping-object iteration to select the correct - elements from the underlying array. - -\end_layout - -\begin_layout Subsubsection -Getting (or Setting) -\end_layout - -\begin_layout Standard -After the mapping object is successfully bound to a particular array, the - mapping object contains the shape of the resulting item as well as iterator - objects that will walk through the currently-bound array and either get - or set its elements as needed. - The walk is implemented using the PyArray_MapIterNext function. - This function sets the coordinates of an iterator object into the current - array to be the next coordinate location indicated by all of the indexing-objec -t iterators while adjusting, if necessary, for the presence of a sub-space. - The result of this function is that the dataptr member of the mapping object - structure is pointed to the next position in the array that needs to be - copied out or set to some value. - -\end_layout - -\begin_layout Standard -When advanced indexing is used to extract an array, an iterator for the - new array is constructed and advanced in phase with the mapping object - iterator. - When advanced indexing is used to place values in an array, a special -\begin_inset Quotes eld -\end_inset - -broadcasted -\begin_inset Quotes erd -\end_inset - - iterator is constructed from the object being placed into the array so - that it will only work if the values used for setting have a shape that - is -\begin_inset Quotes eld -\end_inset - -broadcastable -\begin_inset Quotes erd -\end_inset - - to the shape implied by the indexing object. - -\end_layout - -\begin_layout Section -Universal Functions -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ufunc|(" - -\end_inset - -Universal functions are callable objects that take -\begin_inset Formula $N$ -\end_inset - - inputs and produce -\begin_inset Formula $M$ -\end_inset - - outputs by wrapping basic 1-d loops that work element-by-element into full - easy-to use functions that seamlessly implement broadcasting, type-checking - and buffered coercion, and output-argument handling. - New universal functions are normally created in C, although there is a - mechanism for creating ufuncs from Python functions ( -\series bold -frompyfunc -\series default -). - The user must supply a 1-d loop that implements the basic function taking - the input scalar values and placing the resulting scalars into the appropriate - output slots as explaine n implementation. - -\end_layout - -\begin_layout Subsection -Setup -\end_layout - -\begin_layout Standard -Every ufunc calculation involves some overhead related to setting up the - calculation. - The practical significance of this overhead is that even though the actual - calculation of the ufunc is very fast, you will be able to write array - and type-specific code that will work faster for small arrays than the - ufunc. - In particular, using ufuncs to perform many calculations on 0-d arrays - will be slower than other Python-based solutions (the silently-imported - scalarmath module exists precisely to give array scalars the look-and-feel - of ufunc-based calculations with significantly reduced overhead). - -\end_layout - -\begin_layout Standard -When a ufunc is called, many things must be done. - The information collected from these setup operations is stored in a loop-objec -t. - This loop object is a C-structure (that could become a Python object but - is not initialized as such because it is only used internally). - This loop object has the layout needed to be used with PyArray_Broadcast - so that the broadcasting can be handled in the same way as it is handled - in other sections of code. - -\end_layout - -\begin_layout Standard -The first thing done is to look-up in the thread-specific global dictionary - the current values for the buffer-size, the error mask, and the associated - error object. - The state of the error mask controls what happens when an error-condiction - is found. - It should be noted that checking of the hardware error flags is only performed - after each 1-d loop is executed. - This means that if the input and output arrays are contiguous and of the - correct type so that a single 1-d loop is performed, then the flags may - not be checked until all elements of the array have been calcluated. - Looking up these values in a thread-specific dictionary takes time which - is easily ignored for all but very small arrays. - -\end_layout - -\begin_layout Standard -After checking, the thread-specific global variables, the inputs are evaluated - to determine how the ufunc should proceed and the input and output arrays - are constructed if necessary. - Any inputs which are not arrays are converted to arrays (using context - if necessary). - Which of the inputs are scalars (and therefore converted to 0-d arrays) - is noted. - -\end_layout - -\begin_layout Standard -Next, an appropriate 1-d loop is selected from the 1-d loops available to - the ufunc based on the input array types. - This 1-d loop is selected by trying to match the signature of the data-types - of the inputs against the available signatures. - The signatures corresponding to built-in types are stored in the types - member of the ufunc structure. - The signatures corresponding to user-defined types are stored in a linked-list - of function-information with the head element stored as a -\family typewriter -CObject -\family default - in the userloops dictionary keyed by the data-type number (the first user-defin -ed type in the argument list is used as the key). - The signatures are searched until a signature is found to which the input - arrays can all be cast safely (ignoring any scalar arguments which are - not allowed to determine the type of the result). - The implication of this search procedure is that -\begin_inset Quotes eld -\end_inset - -lesser types -\begin_inset Quotes erd -\end_inset - - should be placed below -\begin_inset Quotes eld -\end_inset - -larger types -\begin_inset Quotes erd -\end_inset - - when the signatures are stored. - If no 1-d loop is found, then an error is reported. - Otherwise, the argument_list is updated with the stored signature --- in - case casting is necessary and to fix the output types assumed by the 1-d - loop. -\end_layout - -\begin_layout Standard -If the ufunc has 2 inputs and 1 output and the second input is an Object - array then a special-case check is performed so that NotImplemented is - returned if the second input is not an ndarray, has the __array_priority__ - attribute, and has an __r<op>__ special method. - In this way, Python is signaled to give the other object a chance to complete - the operation instead of using generic object-array calculations. - This allows (for example) sparse matrices to override the multiplication - operator 1-d loop. - -\end_layout - -\begin_layout Standard -For input arrays that are smaller than the specified buffer size, copies - are made of all non-contiguous, mis-aligned, or out-of-byteorder arrays - to ensure that for small arrays, a single-loop is used. - Then, array iterators are created for all the input arrays and the resulting - collection of iterators is broadcast to a single shape. - -\end_layout - -\begin_layout Standard -The output arguments (if any) are then processed and any missing return - arrays are constructed. - If any provided output array doesn't have the correct type (or is mis-aligned) - and is smaller than the buffer size, then a new output array is constructed - with the special UPDATEIFCOPY flag set so that when it is DECREF'd on completio -n of the function, it's contents will be copied back into the output array. - Iterators for the output arguments are then processed. - -\end_layout - -\begin_layout Standard -Finally, the decision is made about how to execute the looping mechanism - to ensure that all elements of the input arrays are combined to produce - the output arrays of the correct type. - The options for loop execution are one-loop (for contiguous, aligned, and - correct data-type), strided-loop (for non-contiguous but still aligned - and correct data-type), and a buffered loop (for mis-aligned or incorrect - data-type situations). - Depending on which execution method is called for, the loop is then setup - and computed. - -\end_layout - -\begin_layout Subsection -Function call -\end_layout - -\begin_layout Standard -This section describes how the basic universal function computation loop - is setup and executed for each of the three different kinds of execution - possibilities. - If NPY_ALLOW_THREADS is defined during compilation, then the Python Global - Interpreter Lock (GIL) is released prior to calling all of these loops - (as long as they don't involve object arrays). - It is re-acquired if necessary to handle error conditions. - The hardware error flags are checked only after the 1-d loop is calcluated. - -\end_layout - -\begin_layout Subsubsection -One Loop -\end_layout - -\begin_layout Standard -This is the simplest case of all. - The ufunc is executed by calling the underlying 1-d loop exactly once. - This is possible only when we have aligned data of the correct type (including - byte-order) for both input and output and all arrays have uniform strides - (either contiguous, 0-d, or 1-d). - In this case, the 1-d computational loop is called once to compute the - calculation for the entire array. - Note that the hardware error flags are only checked after the entire calculatio -n is complete. - -\end_layout - -\begin_layout Subsubsection -Strided Loop -\end_layout - -\begin_layout Standard -When the input and output arrays are aligned and of the correct type, but - the striding is not uniform (non-contiguous and 2-d or larger), then a - second looping structure is employed for the calculation. - This approach converts all of the iterators for the input and output arguments - to iterate over all but the largest dimension. - The inner loop is then handled by the underlying 1-d computational loop. - The outer loop is a standard iterator loop on the converted iterators. - The hardware error flags are checked after each 1-d loop is completed. - -\end_layout - -\begin_layout Subsubsection -Buffered Loop -\end_layout - -\begin_layout Standard -This is the code that handles the situation whenever the input and/or output - arrays are either misaligned or of the wrong data-type (including being - byte-swapped) from what the underlying 1-d loop expects. - The arrays are also assumed to be non-contiguous. - The code works very much like the strided loop except for the inner 1-d - loop is modified so that pre-processing is performed on the inputs and - post-processing is performed on the outputs in bufsize chunks (where bufsize - is a user-settable parameter). - The underlying 1-d computational loop is called on data that is copied - over (if it needs to be). - The setup code and the loop code is considerably more complicated in this - case because it has to handle: -\end_layout - -\begin_layout Itemize -memory allocation of the temporary buffers -\end_layout - -\begin_layout Itemize -deciding whether or not to use buffers on the input and output data (mis-aligned - and/or wrong data-type) -\end_layout - -\begin_layout Itemize -copying and possibly casting data for any inputs or outputs for which buffers - are necessary. -\end_layout - -\begin_layout Itemize -special-casing Object arrays so that reference counts are properly handled - when copies and/or casts are necessary. - -\end_layout - -\begin_layout Itemize -breaking up the inner 1-d loop into bufsize chunks (with a possible remainder). - -\end_layout - -\begin_layout Standard -Again, the hardware error flags are checked at the end of each 1-d loop. -\end_layout - -\begin_layout Subsection -Final output manipulation -\end_layout - -\begin_layout Standard -Ufuncs allow other array-like classes to be passed seamlessly through the - interface in that inputs of a particular class will induce the outputs - to be of that same class. - The mechanism by which this works is the following. - If any of the inputs are not ndarrays and define the -\series bold -__array_wrap__ -\series default - method, then the class with the largest -\series bold -__array_priority__ -\series default - attribute determines the type of all the outputs (with the exception of - any output arrays passed in). - The -\series bold -__array_wrap__ -\series default - method of the input array will be called with the ndarray being returned - from the ufunc as it's input. - There are two calling styles of the -\series bold -__array_wrap__ -\series default - function supported. - The first takes the ndarray as the first argument and a tuple of -\begin_inset Quotes eld -\end_inset - -context -\begin_inset Quotes erd -\end_inset - - as the second argument. - The context is (ufunc, arguments, output argument number). - This is the first call tried. - If a TypeError occurs, then the function is called with just the ndarray - as the first argument. - -\end_layout - -\begin_layout Subsection -Methods -\end_layout - -\begin_layout Standard -Their are three methods of ufuncs that require calculation similar to the - general-purpose ufuncs. - These are reduce, accumulate, and reduceat. - Each of these methods requires a setup command followed by a loop. - There are four loop styles possible for the methods corresponding to no-element -s, one-element, strided-loop, and buffered-loop. - These are the same basic loop styles as implemented for the general purpose - function call except for the no-element and one-element cases which are - special-cases occurring when the input array objects have 0 and 1 elements - respectively. - -\end_layout - -\begin_layout Subsubsection -Setup -\end_layout - -\begin_layout Standard -The setup function for all three methods is -\family typewriter -construct_reduce -\family default -. - This function creates a reducing loop object and fills it with parameters - needed to complete the loop. - All of the methods only work on ufuncs that take 2-inputs and return 1 - output. - Therefore, the underlying 1-d loop is selected assuming a signature of - [ -\family typewriter -otype -\family default -, -\family typewriter -otype -\family default -, -\family typewriter -otype -\family default -] where -\family typewriter -otype -\family default - is the requested reduction data-type. - The buffer size and error handling is then retrieved from (per-thread) - global storage. - For small arrays that are mis-aligned or have incorrect data-type, a copy - is made so that the un-buffered section of code is used. - Then, the looping strategy is selected. - If there is 1 element or 0 elements in the array, then a simple looping - method is selected. - If the array is not mis-aligned and has the correct data-type, then strided - looping is selected. - Otherwise, buffered looping must be performed. - Looping parameters are then established, and the return array is constructed. - The output array is of a different shape depending on whether the method - is reduce, accumulate, or reduceat. - If an output array is already provided, then it's shape is checked. - If the output array is not C-contiguous, aligned, and of the correct data - type, then a temporary copy is made with the UPDATEIFCOPY flag set. - In this way, the methods will be able to work with a well-behaved output - array but the result will be copied back into the true output array when - the method computation is complete. - Finally, iterators are set up to loop over the correct axis (depending - on the value of axis provided to the method) and the setup routine returns - to the actual computation routine. - -\end_layout - -\begin_layout Subsubsection -Reduce -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ufunc!methods!reduce" - -\end_inset - -All of the ufunc methods use the same underlying 1-d computational loops - with input and output arguments adjusted so that the appropriate reduction - takes place. - For example, the key to the functioning of reduce is that the 1-d loop - is called with the output and the second input pointing to the same position - in memory and both having a step-size of 0. - The first input is pointing to the input array with a step-size given by - the appropriate stride for the selected axis. - In this way, the operation performed is -\begin_inset Formula \begin{eqnarray*} -o & = & i[0]\\ -o & = & i[k]\textrm{ <op> }o\quad k=1\ldots N\end{eqnarray*} - -\end_inset - - where -\begin_inset Formula $N+1$ -\end_inset - - is the number of elements in the input, -\begin_inset Formula $i$ -\end_inset - -, -\begin_inset Formula $o$ -\end_inset - - is the output, and -\begin_inset Formula $i[k]$ -\end_inset - - is the -\begin_inset Formula $k^{\textrm{th}}$ -\end_inset - - element of -\begin_inset Formula $i$ -\end_inset - - along the selected axis. - This basic operations is repeated for arrays with greater than 1 dimension - so that the reduction takes place for every 1-d sub-array along the selected - axis. - An iterator with the selected dimension removed handles this looping. - -\end_layout - -\begin_layout Standard -For buffered loops, care must be taken to copy and cast data before the - loop function is called because the underlying loop expects aligned data - of the correct data-type (including byte-order). - The buffered loop must handle this copying and casting prior to calling - the loop function on chunks no greater than the user-specified bufsize. - -\end_layout - -\begin_layout Subsubsection -Accumulate -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ufunc!methods!accumulate" - -\end_inset - -The accumulate function is very similar to the reduce function in that the - output and the second input both point to the output. - The difference is that the second input points to memory one stride behind - the current output pointer. - Thus, the operation performed is -\end_layout - -\begin_layout Standard -\begin_inset Formula \begin{eqnarray*} -o[0] & = & i[0]\\ -o[k] & = & i[k]\textrm{ <op> }o[k-1]\quad k=1\ldots N.\end{eqnarray*} - -\end_inset - - The output has the same shape as the input and each 1-d loop operates over - -\begin_inset Formula $N$ -\end_inset - - elements when the shape in the selected axis is -\begin_inset Formula $N+1$ -\end_inset - -. - Again, buffered loops take care to copy and cast the data before calling - the underlying 1-d computational loop. - -\end_layout - -\begin_layout Subsubsection -Reduceat -\end_layout - -\begin_layout Standard -\begin_inset LatexCommand index -name "ufunc!methods!reduceat" - -\end_inset - -The reduceat function is a generalization of both the reduce and accumulate - functions. - It implements a reduce over ranges of the input array specified by indices. - The extra indices argument is checked to be sure that every input is not - too large for the input array along the selected dimension before the loop - calculations take place. - The loop implementation is handled using code that is very similar to the - reduce code repeated as many times as there are elements in the indices - input. - In particular: the first input pointer passed to the underlying 1-d computation -al loop points to the input array at the correct location indicated by the - index array. - In addition, the output pointer and the second input pointer passed to - the underlying 1-d loop point to the same position in memory. - The size of the 1-d computational loop is fixed to be the difference between - the current index and the next index (when the current index is the last - index, then the next index is assumed to be the length of the array along - the selected dimension). - In this way, the 1-d loop will implement a reduce over the specified indices. - -\end_layout - -\begin_layout Standard -Mis-aligned or a loop data-type that does not match the input and/or output - data-type is handled using buffered code where-in data is copied to a temporary - buffer and cast to the correct data-type if necessary prior to calling - the underlying 1-d function. - The temporary buffers are created in (element) sizes no bigger than the - user settable buffer-size value. - Thus, the loop must be flexible enough to call the underlying 1-d computational - loop enough times to complete the total calculation in chunks no bigger - than the buffer-size. - -\begin_inset LatexCommand index -name "ufunc|)" - -\end_inset - - -\end_layout - -\end_body -\end_document |