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 "npy_pycompat.h"
#include "arrayobject.h"
#include "iterators.h"
#include "ctors.h"
#include "common.h"

Defines

#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API   NPY_API_VERSION
#define _MULTIARRAYMODULE
#define NEWAXIS_INDEX   -1
#define ELLIPSIS_INDEX   -2
#define SINGLE_INDEX   -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

static int coerce_index (PyObject *o, npy_intp *v)
NPY_NO_EXPORT npy_intp parse_index_entry (PyObject *op, npy_intp *step_size, npy_intp *n_steps, npy_intp max, int axis, int check_index)
NPY_NO_EXPORT int parse_index (PyArrayObject *self, PyObject *op, npy_intp *out_dimensions, npy_intp *out_strides, npy_intp *out_offset, int check_index)
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 PyArrayObjectiter_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 PyArrayObjectiter_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;
#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]);
#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 _NPY_IS_EVEN (   x)    ((x) % 2 == 0)
#define ELLIPSIS_INDEX   -2

Referenced by parse_index(), and parse_index_entry().

#define NEWAXIS_INDEX   -1

Referenced by parse_index(), and parse_index_entry().

#define NPY_NO_DEPRECATED_API   NPY_API_VERSION
#define SINGLE_INDEX   -3

Referenced by parse_index(), and parse_index_entry().


Function Documentation

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
static PyObject* arraymultiter_new ( PyTypeObject *  NPY_UNUSEDsubtype,
PyObject *  args,
PyObject *  kwds 
) [static]
If obj is a multi-iterator, all its arrays will be added to the new multi-iterator.
If not, will try to convert it to a single array
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]
static int coerce_index ( PyObject *  o,
npy_intp v 
) [static]
Tries to convert 'o' into an npy_intp interpreted as an index. Returns 1 if it was successful, 0 otherwise. Does not set an exception.

References PyArray_PyIntAsIntp().

Referenced by parse_index_entry().

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
static PyArrayObject* iter_array ( PyArrayIterObject it,
PyObject *  NPY_UNUSEDop 
) [static]
Any argument ignored
Two options:
  1. underlying array is contiguous -- return 1-d wrapper around it

  2. underlying array is not contiguous -- make new 1-d contiguous array with updateifcopy flag set

    System Message: ERROR/3 (<string>, line 6)
    Unexpected indentation.

    <blockquote>

    to copy back to the old array </blockquote>

If underlying array is readonly, then we make the output array readonly
and updateifcopy does not apply.
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
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]
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 because 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 PyArrayObject* iter_subscript_Bool ( PyArrayIterObject self,
PyArrayObject ind 
) [static]
Get size of return array
Set up loop
Loop over Boolean array

References PyArray_ITER_NEXT.

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 out_dimensions,
npy_intp out_strides,
npy_intp out_offset,
int  check_index 
)
Parses an index that has no fancy indexing. Populates out_dimensions, out_strides, and out_offset.
this relies on the fact that n==1 for loop below

References ELLIPSIS_INDEX, NEWAXIS_INDEX, parse_index_entry(), PyArray_DIMS, PyArray_NDIM, PyArray_STRIDES, and SINGLE_INDEX.

NPY_NO_EXPORT npy_intp parse_index_entry ( PyObject *  op,
npy_intp step_size,
npy_intp n_steps,
npy_intp  max,
int  axis,
int  check_index 
)
This function converts one element of the indexing tuple into a step size and a number of steps, returning the starting index. Non-slices are signalled in 'n_steps', as NEWAXIS_INDEX, ELLIPSIS_INDEX, or SINGLE_INDEX.

References check_and_adjust_index(), coerce_index(), ELLIPSIS_INDEX, NEWAXIS_INDEX, NpySlice_GetIndicesEx, and SINGLE_INDEX.

Referenced by parse_index().

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

Referenced by PyUFunc_FromFuncAndDataAndSignature().

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)

Referenced by array_setfield().

NPY_NO_EXPORT PyObject* PyArray_IterNew ( PyObject *  obj)
Get Iterator.
it = PyObject_New(PyArrayIterObject, &PyArrayIter_Type);

References PyArray_DIMS, PyArray_malloc, PyArray_NDIM, and PyArrayIter_Type.

Referenced by array_imag_get().

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
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, PyArrayIterObject_tag::index, PyArray_ITER_NEXT, PyArray_ToScalar, and PyArrayIterObject_tag::size.


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},
    {"ndim",
        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:
 {
    (lenfunc)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}           
}

Referenced by PyArray_IterNew().