summaryrefslogtreecommitdiff
path: root/numpy/doc/numpybook/capi.lyx
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/doc/numpybook/capi.lyx')
-rw-r--r--numpy/doc/numpybook/capi.lyx24232
1 files changed, 24232 insertions, 0 deletions
diff --git a/numpy/doc/numpybook/capi.lyx b/numpy/doc/numpybook/capi.lyx
new file mode 100644
index 000000000..04522d13d
--- /dev/null
+++ b/numpy/doc/numpybook/capi.lyx
@@ -0,0 +1,24232 @@
+#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
+ hasobject;
+\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
+hasobject
+\family default
+ flag.
+\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
+hasobject 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[PyArray_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[PyArray_NSORTS];
+\end_layout
+
+\begin_layout LyX-Code
+
+\emph on
+PyArray_ArgSortFunc
+\emph default
+ *argsort[PyArray_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
+PyArray_QUICKSORT
+\family default
+,
+\family typewriter
+PyArray_HEAPSORT
+\family default
+, and
+\family typewriter
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_INTP
+\series default
+ and
+\series bold
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_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
+PyArray_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 PyArray_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
+PyArray_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
+tostring
+\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
+PyArray_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
+PyArrayDescr_Check (
+\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
+PyArray_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
+PyArray_FLOAT
+\series default
+ or
+\series bold
+PyArray_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_RemoveLargest
+\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
+PyArray_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
+PyArray_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