* fill and x->ao should have equivalent types */ NUMPY_API * A Neighborhood Iterator object. */
| 1701 | * A Neighborhood Iterator object. |
| 1702 | */ |
| 1703 | NPY_NO_EXPORT PyObject* |
| 1704 | PyArray_NeighborhoodIterNew(PyArrayIterObject *x, const npy_intp *bounds, |
| 1705 | int mode, PyArrayObject* fill) |
| 1706 | { |
| 1707 | int i; |
| 1708 | PyArrayNeighborhoodIterObject *ret; |
| 1709 | |
| 1710 | ret = PyArray_malloc(sizeof(*ret)); |
| 1711 | if (ret == NULL) { |
| 1712 | return NULL; |
| 1713 | } |
| 1714 | PyObject_Init((PyObject *)ret, &PyArrayNeighborhoodIter_Type); |
| 1715 | |
| 1716 | Py_INCREF(x->ao); /* PyArray_RawIterBaseInit steals a reference */ |
| 1717 | PyArray_RawIterBaseInit((PyArrayIterObject*)ret, x->ao); |
| 1718 | Py_INCREF(x); |
| 1719 | ret->_internal_iter = x; |
| 1720 | |
| 1721 | ret->nd = PyArray_NDIM(x->ao); |
| 1722 | |
| 1723 | for (i = 0; i < ret->nd; ++i) { |
| 1724 | ret->dimensions[i] = PyArray_DIMS(x->ao)[i]; |
| 1725 | } |
| 1726 | |
| 1727 | /* Compute the neighborhood size and copy the shape */ |
| 1728 | ret->size = 1; |
| 1729 | for (i = 0; i < ret->nd; ++i) { |
| 1730 | ret->bounds[i][0] = bounds[2 * i]; |
| 1731 | ret->bounds[i][1] = bounds[2 * i + 1]; |
| 1732 | ret->size *= (ret->bounds[i][1] - ret->bounds[i][0]) + 1; |
| 1733 | |
| 1734 | /* limits keep track of valid ranges for the neighborhood: if a bound |
| 1735 | * of the neighborhood is outside the array, then limits is the same as |
| 1736 | * boundaries. On the contrary, if a bound is strictly inside the |
| 1737 | * array, then limits correspond to the array range. For example, for |
| 1738 | * an array [1, 2, 3], if bounds are [-1, 3], limits will be [-1, 3], |
| 1739 | * but if bounds are [1, 2], then limits will be [0, 2]. |
| 1740 | * |
| 1741 | * This is used by neighborhood iterators stacked on top of this one */ |
| 1742 | ret->limits[i][0] = ret->bounds[i][0] < 0 ? ret->bounds[i][0] : 0; |
| 1743 | ret->limits[i][1] = ret->bounds[i][1] >= ret->dimensions[i] - 1 ? |
| 1744 | ret->bounds[i][1] : |
| 1745 | ret->dimensions[i] - 1; |
| 1746 | ret->limits_sizes[i] = (ret->limits[i][1] - ret->limits[i][0]) + 1; |
| 1747 | } |
| 1748 | |
| 1749 | switch (mode) { |
| 1750 | case NPY_NEIGHBORHOOD_ITER_ZERO_PADDING: |
| 1751 | ret->constant = PyArray_Zero(x->ao); |
| 1752 | ret->mode = mode; |
| 1753 | ret->translate = &get_ptr_constant; |
| 1754 | break; |
| 1755 | case NPY_NEIGHBORHOOD_ITER_ONE_PADDING: |
| 1756 | ret->constant = PyArray_One(x->ao); |
| 1757 | ret->mode = mode; |
| 1758 | ret->translate = &get_ptr_constant; |
| 1759 | break; |
| 1760 | case NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING: |
nothing calls this directly
no test coverage detected