diff options
author | David Cournapeau <cournape@gmail.com> | 2009-08-07 13:21:34 +0000 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2009-08-07 13:21:34 +0000 |
commit | bad523b4582f5b38f66d3fd4ba883d6fbbbe8be2 (patch) | |
tree | b550133d589a3647631a50df220751ae12037d1c | |
parent | 5d180c4550ef3b348e9ee947bbe2f69fbd1ac5d4 (diff) | |
download | numpy-bad523b4582f5b38f66d3fd4ba883d6fbbbe8be2.tar.gz |
Circular iterator fixed.
-rw-r--r-- | numpy/core/include/numpy/_neighborhood_iterator_imp.h | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarray/iterators.c | 56 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 48 |
3 files changed, 67 insertions, 40 deletions
diff --git a/numpy/core/include/numpy/_neighborhood_iterator_imp.h b/numpy/core/include/numpy/_neighborhood_iterator_imp.h index b8679bc88..9eeb71eda 100644 --- a/numpy/core/include/numpy/_neighborhood_iterator_imp.h +++ b/numpy/core/include/numpy/_neighborhood_iterator_imp.h @@ -371,7 +371,8 @@ PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter) iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates); break; case NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING: - _PyArrayNeighborhoodIter_SetPtrCircular(iter); + //_PyArrayNeighborhoodIter_SetPtrCircular(iter); + iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates); break; } diff --git a/numpy/core/src/multiarray/iterators.c b/numpy/core/src/multiarray/iterators.c index 4e42064cf..a44c3f387 100644 --- a/numpy/core/src/multiarray/iterators.c +++ b/numpy/core/src/multiarray/iterators.c @@ -1852,47 +1852,30 @@ __npy_pos_remainder(npy_intp i, npy_intp n) #undef _NPY_IS_EVEN #define _INF_SET_PTR_MIRROR(c) \ - printf("bounds: %ld - %ld\n", p->bounds[c][0], p->bounds[c][1]); \ - bd = coordinates[c] + p->coordinates[c]; \ - bd -= p->bounds[c][0]; \ - printf("bd: %ld - max %ld\n", bd, p->bounds[c][1] - p->bounds[c][0]); \ - truepos = __npy_pos_remainder(bd, niter->dimensions[c] - p->bounds[c][0]); \ - printf("truepos: %ld \n", truepos); \ - _coordinates[c] = (truepos + p->bounds[c][0]); \ - printf("_cordinates: %ld \n", _coordinates[c]); \ + lb = p->bounds[c][0]; \ + bd = coordinates[c] + p->coordinates[c] - lb; \ + _coordinates[c] = lb + __npy_pos_remainder(bd, p->bounds[c][1] + 1 - lb); /* set the dataptr from its current coordinates */ static char* get_ptr_mirror(PyArrayIterObject* _iter, npy_intp *coordinates) { int i; - npy_intp bd, _coordinates[NPY_MAXDIMS]; - npy_intp truepos; + npy_intp bd, _coordinates[NPY_MAXDIMS], lb; PyArrayNeighborhoodIterObject *niter = (PyArrayNeighborhoodIterObject*)_iter; PyArrayIterObject *p = niter->_internal_iter; - //printf("%s\n", __func__); for(i = 0; i < niter->nd; ++i) { - // _INF_SET_PTR_MIRROR(i) - // printf("bounds: %ld - %ld\n", p->bounds[i][0], p->bounds[i][1]); - bd = coordinates[i] + p->coordinates[i]; - bd -= p->bounds[i][0]; - // printf("bd: %ld - max %ld\n", bd, p->bounds[i][1] - p->bounds[i][0]); - truepos = __npy_pos_remainder(bd, p->bounds[i][1] + 1 - p->bounds[i][0]); - // printf("truepos: %ld \n", truepos); - _coordinates[i] = (truepos + p->bounds[i][0]); - // printf("_cordinates: %ld \n", _coordinates[i]); - } - - // printf("%s: coordinates is %ld | %ld -> %ld\n", __func__, coordinates[0], p->coordinates[0], _coordinates[0]); + _INF_SET_PTR_MIRROR(i) + } + return p->translate(p, _coordinates); } #undef _INF_SET_PTR_MIRROR -#if 0 /* compute l such as i = k * n + l, 0 <= l < |k| */ static inline npy_intp -_npy_euclidean_division(npy_intp i, npy_intp n) +__npy_euclidean_division(npy_intp i, npy_intp n) { npy_intp l; @@ -1902,29 +1885,26 @@ _npy_euclidean_division(npy_intp i, npy_intp n) } return l; } -#endif #define _INF_SET_PTR_CIRCULAR(c) \ - bd = coordinates[c] + niter->_internal_iter->coordinates[c]; \ - truepos = _npy_euclidean_division(bd, niter->dimensions[c]); \ - offset = (truepos - niter->_internal_iter->coordinates[c]) * niter->strides[c]; \ - ret += offset; + lb = p->bounds[c][0]; \ + bd = coordinates[c] + p->coordinates[c] - lb; \ + _coordinates[c] = lb + _npy_euclidean_division(bd, p->bounds[c][1] + 1 - lb); static char* -get_coordinates_circular(PyArrayIterObject* _iter, npy_intp *coordinates) +get_ptr_circular(PyArrayIterObject* _iter, npy_intp *coordinates) { int i; - npy_intp offset, bd, truepos; - char *ret; + //npy_intp offset, bd, truepos; + npy_intp bd, _coordinates[NPY_MAXDIMS], lb; PyArrayNeighborhoodIterObject *niter = (PyArrayNeighborhoodIterObject*)_iter; - - ret = niter->_internal_iter->dataptr; + PyArrayIterObject *p = niter->_internal_iter; for(i = 0; i < niter->nd; ++i) { _INF_SET_PTR_CIRCULAR(i) } - return ret; + return p->translate(p, _coordinates); } #undef _INF_SET_PTR_CIRCULAR @@ -1990,13 +1970,11 @@ PyArray_NeighborhoodIterNew(PyArrayIterObject *x, intp *bounds, ret->constant = NULL; ret->translate = &get_ptr_mirror; break; -#if 0 case NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING: ret->mode = mode; ret->constant = NULL; - ret->translate = get_coordinates_circular; + ret->translate = &get_ptr_circular; break; -#endif default: PyErr_SetString(PyExc_ValueError, "Unsupported padding mode"); goto clean_x; diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 0f9d6629f..a45012771 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -1306,5 +1306,53 @@ class TestStackedNeighborhoodIter(TestCase): [-2, 2], NEIGH_MODE['mirror']) assert_array_equal(l, r) + # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and + # circular padding + def test_simple_circular(self): + dt = np.float64 + # Stacking zero on top of mirror + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 3, 1], dtype=dt), + np.array([3, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 1], dtype=dt), + np.array([3, 1, 0], dtype=dt)] + l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['circular'], + [-1, 1], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([3, 0, 0], dtype=dt), + np.array([0, 0, 1], dtype=dt), + np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt)] + l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'], + [-2, 0], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 2nd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt), + np.array([3, 0, 0], dtype=dt), + np.array([0, 0, 1], dtype=dt)] + l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'], + [0, 2], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 3rd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([3, 0, 0, 1, 2], dtype=dt), + np.array([0, 0, 1, 2, 3], dtype=dt), + np.array([0, 1, 2, 3, 0], dtype=dt), + np.array([1, 2, 3, 0, 0], dtype=dt), + np.array([2, 3, 0, 0, 1], dtype=dt)] + l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'], + [-2, 2], NEIGH_MODE['circular']) + assert_array_equal(l, r) + if __name__ == "__main__": run_module_suite() |