numpy 2.0.0
src/multiarray/iterators.c File Reference
#include <Python.h>
#include "structmember.h"
#include "numpy/arrayobject.h"
#include "numpy/arrayscalars.h"
#include "npy_config.h"
#include "numpy/npy_3kcompat.h"
#include "arrayobject.h"
#include "iterators.h"
#include "ctors.h"
#include "common.h"

Defines

#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API
#define _MULTIARRAYMODULE
#define NPY_NO_PREFIX
#define PseudoIndex   -1
#define RubberIndex   -2
#define SingleIndex   -3
#define _INF_SET_PTR(c)
#define _NPY_IS_EVEN(x)   ((x) % 2 == 0)
#define _INF_SET_PTR_MIRROR(c)
#define _INF_SET_PTR_CIRCULAR(c)

Functions

NPY_NO_EXPORT npy_intp parse_subindex (PyObject *op, npy_intp *step_size, npy_intp *n_steps, npy_intp max)
NPY_NO_EXPORT int parse_index (PyArrayObject *self, PyObject *op, npy_intp *dimensions, npy_intp *strides, npy_intp *offset_ptr)
static int slice_coerce_index (PyObject *o, npy_intp *v)
NPY_NO_EXPORT int slice_GetIndices (PySliceObject *r, npy_intp length, npy_intp *start, npy_intp *stop, npy_intp *step, npy_intp *slicelength)
static char * get_ptr_simple (PyArrayIterObject *iter, npy_intp *coordinates)
static PyObject * array_iter_base_init (PyArrayIterObject *it, PyArrayObject *ao)
static void array_iter_base_dealloc (PyArrayIterObject *it)
NPY_NO_EXPORT PyObject * PyArray_IterNew (PyObject *obj)
NPY_NO_EXPORT PyObject * PyArray_BroadcastToShape (PyObject *obj, npy_intp *dims, int nd)
NPY_NO_EXPORT PyObject * PyArray_IterAllButAxis (PyObject *obj, int *inaxis)
NPY_NO_EXPORT int PyArray_RemoveSmallest (PyArrayMultiIterObject *multi)
static PyObject * arrayiter_next (PyArrayIterObject *it)
static void arrayiter_dealloc (PyArrayIterObject *it)
static Py_ssize_t iter_length (PyArrayIterObject *self)
static PyObject * iter_subscript_Bool (PyArrayIterObject *self, PyArrayObject *ind)
static PyObject * iter_subscript_int (PyArrayIterObject *self, PyArrayObject *ind)
NPY_NO_EXPORT PyObject * iter_subscript (PyArrayIterObject *self, PyObject *ind)
static int iter_ass_sub_Bool (PyArrayIterObject *self, PyArrayObject *ind, PyArrayIterObject *val, int swap)
static int iter_ass_sub_int (PyArrayIterObject *self, PyArrayObject *ind, PyArrayIterObject *val, int swap)
NPY_NO_EXPORT int iter_ass_subscript (PyArrayIterObject *self, PyObject *ind, PyObject *val)
static PyObject * iter_array (PyArrayIterObject *it, PyObject *NPY_UNUSED(op))
static PyObject * iter_copy (PyArrayIterObject *it, PyObject *args)
static PyObject * iter_richcompare (PyArrayIterObject *self, PyObject *other, int cmp_op)
static PyObject * iter_coords_get (PyArrayIterObject *self)
NPY_NO_EXPORT int PyArray_Broadcast (PyArrayMultiIterObject *mit)
NPY_NO_EXPORT PyObject * PyArray_MultiIterFromObjects (PyObject **mps, int n, int nadd,...)
NPY_NO_EXPORT PyObject * PyArray_MultiIterNew (int n,...)
static PyObject * arraymultiter_new (PyTypeObject *NPY_UNUSED(subtype), PyObject *args, PyObject *kwds)
static PyObject * arraymultiter_next (PyArrayMultiIterObject *multi)
static void arraymultiter_dealloc (PyArrayMultiIterObject *multi)
static PyObject * arraymultiter_size_get (PyArrayMultiIterObject *self)
static PyObject * arraymultiter_index_get (PyArrayMultiIterObject *self)
static PyObject * arraymultiter_shape_get (PyArrayMultiIterObject *self)
static PyObject * arraymultiter_iters_get (PyArrayMultiIterObject *self)
static PyObject * arraymultiter_reset (PyArrayMultiIterObject *self, PyObject *args)
static void neighiter_dealloc (PyArrayNeighborhoodIterObject *iter)
static char * _set_constant (PyArrayNeighborhoodIterObject *iter, PyArrayObject *fill)
static char * get_ptr_constant (PyArrayIterObject *_iter, npy_intp *coordinates)
static NPY_INLINE npy_intp __npy_pos_remainder (npy_intp i, npy_intp n)
static char * get_ptr_mirror (PyArrayIterObject *_iter, npy_intp *coordinates)
static NPY_INLINE npy_intp __npy_euclidean_division (npy_intp i, npy_intp n)
static char * get_ptr_circular (PyArrayIterObject *_iter, npy_intp *coordinates)
NPY_NO_EXPORT PyObject * PyArray_NeighborhoodIterNew (PyArrayIterObject *x, npy_intp *bounds, int mode, PyArrayObject *fill)

Variables

static PyMappingMethods iter_as_mapping
static PyMethodDef iter_methods []
static PyMemberDef iter_members []
static PyGetSetDef iter_getsets []
NPY_NO_EXPORT PyTypeObject PyArrayIter_Type
static PyGetSetDef arraymultiter_getsetlist []
static PyMemberDef arraymultiter_members []
static PyMethodDef arraymultiter_methods []
NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type
NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type

Define Documentation

#define _INF_SET_PTR (   c)
Value:
bd = coordinates[c] + p->coordinates[c]; \
    if (bd < p->limits[c][0] || bd > p->limits[c][1]) { \
        return niter->constant; \
    } \
    _coordinates[c] = bd;

Referenced by arraymultiter_new().

#define _INF_SET_PTR_CIRCULAR (   c)
Value:
lb = p->limits[c][0]; \
    bd = coordinates[c] + p->coordinates[c] - lb; \
    _coordinates[c] = lb + __npy_euclidean_division(bd, p->limits_sizes[c]);

Referenced by arraymultiter_size_get().

#define _INF_SET_PTR_MIRROR (   c)
Value:
lb = p->limits[c][0]; \
    bd = coordinates[c] + p->coordinates[c] - lb; \
    _coordinates[c] = lb + __npy_pos_remainder(bd, p->limits_sizes[c]);

Referenced by arraymultiter_next().

#define _MULTIARRAYMODULE
#define _NPY_IS_EVEN (   x)    ((x) % 2 == 0)
#define NPY_NO_DEPRECATED_API
#define NPY_NO_PREFIX
#define PseudoIndex   -1
#define PY_SSIZE_T_CLEAN
#define RubberIndex   -2
#define SingleIndex   -3

Function Documentation

static NPY_INLINE npy_intp __npy_euclidean_division ( npy_intp  i,
npy_intp  n 
) [static]
compute l such as i = k * n + l, 0 <= l < |k|

Docutils System Messages

System Message: ERROR/3 (<string>, line 1); backlink Undefined substitution referenced: "k".
static NPY_INLINE npy_intp __npy_pos_remainder ( npy_intp  i,
npy_intp  n 
) [static]
For an array x of dimension n, and given index i, returns j, 0 <= j < n such as x[i] = x[j], with x assumed to be mirrored. For example, for x = {1, 2, 3} (n = 3)
index -5 -4 -3 -2 -1 0 1 2 3 4 5 6 value 2 3 3 2 1 1 2 3 3 2 1 1
_npy_pos_index_mirror(4, 3) will return 1, because x[4] = x[1]

Mirror i such as it is guaranteed to be positive
compute k and l such as i = k * n + l, 0 <= l < k

static char* _set_constant ( PyArrayNeighborhoodIterObject iter,
PyArrayObject fill 
) [static]

Non-object types

static void array_iter_base_dealloc ( PyArrayIterObject it) [static]
static PyObject* array_iter_base_init ( PyArrayIterObject it,
PyArrayObject ao 
) [static]
This is common initialization code between PyArrayIterObject and PyArrayNeighborhoodIterObject
Increase ao refcount

Referenced by arraymultiter_index_get().

static void arrayiter_dealloc ( PyArrayIterObject it) [static]
static PyObject* arrayiter_next ( PyArrayIterObject it) [static]
Returns an array scalar holding the element desired

References Bool.

static void arraymultiter_dealloc ( PyArrayMultiIterObject multi) [static]

References NPY_MAXDIMS.

static PyObject* arraymultiter_index_get ( PyArrayMultiIterObject self) [static]
static PyObject* arraymultiter_iters_get ( PyArrayMultiIterObject self) [static]
static PyObject* arraymultiter_new ( PyTypeObject *  NPY_UNUSEDsubtype,
PyObject *  args,
PyObject *  kwds 
) [static]
static PyObject* arraymultiter_next ( PyArrayMultiIterObject multi) [static]

References _INF_SET_PTR_MIRROR.

static PyObject* arraymultiter_reset ( PyArrayMultiIterObject self,
PyObject *  args 
) [static]
static PyObject* arraymultiter_shape_get ( PyArrayMultiIterObject self) [static]
static PyObject* arraymultiter_size_get ( PyArrayMultiIterObject self) [static]

References _INF_SET_PTR_CIRCULAR.

static char* get_ptr_circular ( PyArrayIterObject _iter,
npy_intp coordinates 
) [static]
static char* get_ptr_constant ( PyArrayIterObject _iter,
npy_intp coordinates 
) [static]
set the dataptr from its current coordinates
static char* get_ptr_mirror ( PyArrayIterObject _iter,
npy_intp coordinates 
) [static]
set the dataptr from its current coordinates
static char* get_ptr_simple ( PyArrayIterObject iter,
npy_intp coordinates 
) [static]
***************** Element-wise Array Iterator ******************
Aided by Peter J. Verveer's nd_image package and numpy's arraymap ***

System Message: WARNING/2 (<string>, line 1); backlink Inline strong start-string without end-string.
System Message: WARNING/2 (<string>, line 1); backlink Inline emphasis start-string without end-string.
and Python's array iterator **
get the dataptr from its current coordinates for simple iterator

References PyArrayIterObject_tag::contiguous.

static PyObject* iter_array ( PyArrayIterObject it,
PyObject *  NPY_UNUSEDop 
) [static]

Any argument ignored
Two options:
1) underlying array is contiguous -- return 1-d wrapper around it
System Message: WARNING/2 (<string>, line 4) Definition list ends without a blank line; unexpected unindent.
2) underlying array is not contiguous -- make new 1-d contiguous array with updateifcopy flag set to copy back to the old array

static int iter_ass_sub_Bool ( PyArrayIterObject self,
PyArrayObject ind,
PyArrayIterObject val,
int  swap 
) [static]

Loop over Boolean array

static int iter_ass_sub_int ( PyArrayIterObject self,
PyArrayObject ind,
PyArrayIterObject val,
int  swap 
) [static]
NPY_NO_EXPORT int iter_ass_subscript ( PyArrayIterObject self,
PyObject *  ind,
PyObject *  val 
)

Check for Boolean -- this is first becasue Bool is a subclass of Int
Check Slice
Integer
convert to INTP array if Integer array scalar or List
Check for Boolean object
Check for integer array

References PyArrayIterObject_tag::dataptr, PyArrayIterObject_tag::index, parse_subindex(), PseudoIndex, PyArray_DATA, PyArray_ITER_GOTO1D, PyArray_ITER_NEXT, PyArray_ITER_RESET, RubberIndex, SingleIndex, and PyArrayIterObject_tag::size.

static PyObject* iter_coords_get ( PyArrayIterObject self) [static]

coordinates not kept track of --- need to generate from index

static PyObject* iter_copy ( PyArrayIterObject it,
PyObject *  args 
) [static]
static Py_ssize_t iter_length ( PyArrayIterObject self) [static]

References Bool.

static PyObject* iter_richcompare ( PyArrayIterObject self,
PyObject *  other,
int  cmp_op 
) [static]
NPY_NO_EXPORT PyObject* iter_subscript ( PyArrayIterObject self,
PyObject *  ind 
)
Always returns arrays

Tuples >1d not accepted --- i.e. no newaxis Could implement this with adjusted strides and dimensions in iterator Check for Boolean -- this is first becasue Bool is a subclass of Int

<

empty array
Check for Integer or Slice

<

Integer
convert to INTP array if Integer array scalar or List
Check for Boolean object
Check for integer array

static PyObject* iter_subscript_Bool ( PyArrayIterObject self,
PyArrayObject ind 
) [static]

Get size of return array
Set up loop
Loop over Boolean array

static PyObject* iter_subscript_int ( PyArrayIterObject self,
PyArrayObject ind 
) [static]
static void neighiter_dealloc ( PyArrayNeighborhoodIterObject iter) [static]
========================= Neighborhood iterator ======================
NPY_NO_EXPORT int parse_index ( PyArrayObject self,
PyObject *  op,
npy_intp dimensions,
npy_intp strides,
npy_intp offset_ptr 
)

this relies on the fact that n==1 for loop below

References parse_subindex(), PseudoIndex, RubberIndex, and SingleIndex.

NPY_NO_EXPORT npy_intp parse_subindex ( PyObject *  op,
npy_intp step_size,
npy_intp n_steps,
npy_intp  max 
)
NPY_NO_EXPORT int PyArray_Broadcast ( PyArrayMultiIterObject mit)
END of Array Iterator *
Adjust dimensionality and strides for index object iterators
--- i.e. broadcast

Discover the broadcast number of dimensions
Discover the broadcast shape in each dimension
This prepends 1 to shapes not already equal to nd
Reset the iterator dimensions and strides of each iterator object -- using 0 valued strides for broadcasting Need to check for overflow
If this dimension was added or shape of underlying array was 1

NPY_NO_EXPORT PyObject* PyArray_BroadcastToShape ( PyObject *  obj,
npy_intp dims,
int  nd 
)
Get Iterator broadcast to a particular shape
NPY_NO_EXPORT PyObject* PyArray_IterAllButAxis ( PyObject *  obj,
int *  inaxis 
)
Get Iterator that iterates over all but one axis (don't use this with
PyArray_ITER_GOTO1D). The axis will be over-written if negative with the axis having the smallest stride.

adjust so that will not iterate over axis
(won't fix factors so don't use PyArray_ITER_GOTO1D with this iterator)

NPY_NO_EXPORT PyObject* PyArray_IterNew ( PyObject *  obj)
Get Iterator.

it = PyObject_New(PyArrayIterObject, &PyArrayIter_Type);

Referenced by array_subscript_nice(), PyArray_SearchSorted(), and PyArray_ToFile().

NPY_NO_EXPORT PyObject* PyArray_MultiIterFromObjects ( PyObject **  mps,
int  n,
int  nadd,
  ... 
)
Get MultiIterator from array of Python objects and any additional <blockquote>
PyObject **mps -- array of PyObjects int n - number of PyObjects in the array int nadd - number of additional arrays to include in the iterator.

System Message: WARNING/2 (<string>, line 3); backlink Inline strong start-string without end-string.
Returns a multi-iterator object. </blockquote>
NPY_NO_EXPORT PyObject* PyArray_MultiIterNew ( int  n,
  ... 
)
Get MultiIterator,

fprintf(stderr, "multi new...");

NPY_NO_EXPORT PyObject* PyArray_NeighborhoodIterNew ( PyArrayIterObject x,
npy_intp bounds,
int  mode,
PyArrayObject fill 
)
fill and x->ao should have equivalent types
A Neighborhood Iterator object.

Compute the neighborhood size and copy the shape
limits keep track of valid ranges for the neighborhood: if a bound of the neighborhood is outside the array, then limits is the same as boundaries. On the contrary, if a bound is strictly inside the array, then limits correspond to the array range. For example, for an array [1, 2, 3], if bounds are [-1, 3], limits will be [-1, 3], but if bounds are [1, 2], then limits will be [0, 2].
This is used by neighborhood iterators stacked on top of this one
New reference in returned value of _set_constant if array object
XXX: we force x iterator to be non contiguous because we need coordinates... Modifying the iterator here is not great

NPY_NO_EXPORT int PyArray_RemoveSmallest ( PyArrayMultiIterObject multi)
Adjusts previously broadcasted iterators so that the axis with

the smallest sum of iterator strides is not iterated over. Returns dimension which is smallest in the range [0,multi->nd). A -1 is returned if multi->nd == 0.

don't use with PyArray_ITER_GOTO1D because factors are not adjusted

Find longest dimension

References PyArrayIterObject_tag::ao, PyArrayIterObject_tag::dataptr, PyArray_ITER_NEXT, and PyArray_ToScalar.

static int slice_coerce_index ( PyObject *  o,
npy_intp v 
) [static]
NPY_NO_EXPORT int slice_GetIndices ( PySliceObject *  r,
npy_intp  length,
npy_intp start,
npy_intp stop,
npy_intp step,
npy_intp slicelength 
)
This is basically PySlice_GetIndicesEx, but with our coercion of indices to integers (plus, that function is new in Python 2.3)

defstart = *step < 0 ? length - 1 : 0;

System Message: WARNING/2 (<string>, line 1); backlink Inline emphasis start-string without end-string.

Referenced by parse_subindex().


Variable Documentation

PyGetSetDef arraymultiter_getsetlist[] [static]
Initial value:
 {
    {"size",
        (getter)arraymultiter_size_get,
        NULL,
        NULL, NULL},
    {"index",
        (getter)arraymultiter_index_get,
        NULL,
        NULL, NULL},
    {"shape",
        (getter)arraymultiter_shape_get,
        NULL,
        NULL, NULL},
    {"iters",
        (getter)arraymultiter_iters_get,
        NULL,
        NULL, NULL},
    {NULL, NULL, NULL, NULL, NULL},
}
PyMemberDef arraymultiter_members[] [static]
Initial value:
 {
    {"numiter",
        T_INT,
        offsetof(PyArrayMultiIterObject, numiter),
        READONLY, NULL},
    {"nd",
        T_INT,
        offsetof(PyArrayMultiIterObject, nd),
        READONLY, NULL},
    {NULL, 0, 0, 0, NULL},
}
PyMethodDef arraymultiter_methods[] [static]
Initial value:
 {
    {"reset",
        (PyCFunction) arraymultiter_reset,
        METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL},      
}
PyMappingMethods iter_as_mapping [static]
Initial value:
 {






    (inquiry)iter_length,                   

    (binaryfunc)iter_subscript,             
    (objobjargproc)iter_ass_subscript,      
}
PyGetSetDef iter_getsets[] [static]
Initial value:
 {
    {"coords",
        (getter)iter_coords_get,
        NULL,
        NULL, NULL},
    {NULL, NULL, NULL, NULL, NULL},
}
PyMemberDef iter_members[] [static]
Initial value:
 {
    {"base",
        T_OBJECT,
        offsetof(PyArrayIterObject, ao),
        READONLY, NULL},
    {"index",
        T_INT,
        offsetof(PyArrayIterObject, index),
        READONLY, NULL},
    {NULL, 0, 0, 0, NULL},
}
PyMethodDef iter_methods[] [static]
Initial value:
 {
    
    {"__array__",
        (PyCFunction)iter_array,
        METH_VARARGS, NULL},
    {"copy",
        (PyCFunction)iter_copy,
        METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}           
}
NPY_NO_EXPORT PyTypeObject PyArrayIter_Type
NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type
NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type

Referenced by arraymultiter_index_get().