NUMPY_API * Sets the iterator to the specified multi-index, which must have the * correct number of entries for 'ndim'. It is only valid * when NPY_ITER_MULTI_INDEX was passed to the constructor. This operation * fails if the multi-index is out of bounds. * * Returns NPY_SUCCEED on success, NPY_FAIL on failure. */
| 439 | * Returns NPY_SUCCEED on success, NPY_FAIL on failure. |
| 440 | */ |
| 441 | NPY_NO_EXPORT int |
| 442 | NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp const *multi_index) |
| 443 | { |
| 444 | npy_uint32 itflags = NIT_ITFLAGS(iter); |
| 445 | int idim, ndim = NIT_NDIM(iter); |
| 446 | int nop = NIT_NOP(iter); |
| 447 | |
| 448 | npy_intp iterindex, factor; |
| 449 | NpyIter_AxisData *axisdata; |
| 450 | npy_intp sizeof_axisdata; |
| 451 | npy_int8 *perm; |
| 452 | |
| 453 | if (!(itflags&NPY_ITFLAG_HASMULTIINDEX)) { |
| 454 | PyErr_SetString(PyExc_ValueError, |
| 455 | "Cannot call GotoMultiIndex on an iterator without " |
| 456 | "requesting a multi-index in the constructor"); |
| 457 | return NPY_FAIL; |
| 458 | } |
| 459 | |
| 460 | if (itflags&NPY_ITFLAG_BUFFER) { |
| 461 | PyErr_SetString(PyExc_ValueError, |
| 462 | "Cannot call GotoMultiIndex on an iterator which " |
| 463 | "is buffered"); |
| 464 | return NPY_FAIL; |
| 465 | } |
| 466 | |
| 467 | if (itflags&NPY_ITFLAG_EXLOOP) { |
| 468 | PyErr_SetString(PyExc_ValueError, |
| 469 | "Cannot call GotoMultiIndex on an iterator which " |
| 470 | "has the flag EXTERNAL_LOOP"); |
| 471 | return NPY_FAIL; |
| 472 | } |
| 473 | |
| 474 | perm = NIT_PERM(iter); |
| 475 | axisdata = NIT_AXISDATA(iter); |
| 476 | sizeof_axisdata = NIT_AXISDATA_SIZEOF(itflags, ndim, nop); |
| 477 | |
| 478 | /* Compute the iterindex corresponding to the multi-index */ |
| 479 | iterindex = 0; |
| 480 | factor = 1; |
| 481 | for (idim = 0; idim < ndim; ++idim) { |
| 482 | npy_int8 p = perm[idim]; |
| 483 | npy_intp i, shape; |
| 484 | |
| 485 | shape = NAD_SHAPE(axisdata); |
| 486 | if (p < 0) { |
| 487 | /* If the perm entry is negative, reverse the index */ |
| 488 | i = shape - multi_index[ndim+p] - 1; |
| 489 | } |
| 490 | else { |
| 491 | i = multi_index[ndim-p-1]; |
| 492 | } |
| 493 | |
| 494 | /* Bounds-check this index */ |
| 495 | if (i >= 0 && i < shape) { |
| 496 | iterindex += factor * i; |
| 497 | factor *= shape; |
| 498 | } |
no test coverage detected