* Reduceat performs a reduce over an axis using the indices as a guide * * op.reduceat(array,indices) computes * op.reduce(array[indices[i]:indices[i+1]] * for i=0..end with an implicit indices[i+1]=len(array) * assumed when i=end-1 * * if indices[i+1] <= indices[i]+1 * then the result is array[indices[i]] for that value * * op.accumulate(array) is the same as * op.reduceat(array,indic
| 3484 | * TODO: Reduceat duplicates too much code from accumulate! |
| 3485 | */ |
| 3486 | static PyObject * |
| 3487 | PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind, |
| 3488 | PyArrayObject *out, int axis, PyArray_DTypeMeta *signature[3]) |
| 3489 | { |
| 3490 | PyArrayObject *op[3]; |
| 3491 | int op_axes_arrays[3][NPY_MAXDIMS]; |
| 3492 | int *op_axes[3] = {op_axes_arrays[0], op_axes_arrays[1], |
| 3493 | op_axes_arrays[2]}; |
| 3494 | npy_uint32 op_flags[3]; |
| 3495 | int idim, ndim; |
| 3496 | int needs_api, need_outer_iterator = 0; |
| 3497 | |
| 3498 | int res = 0; |
| 3499 | |
| 3500 | NpyIter *iter = NULL; |
| 3501 | |
| 3502 | PyArrayMethod_StridedLoop *strided_loop; |
| 3503 | NpyAuxData *auxdata = NULL; |
| 3504 | |
| 3505 | /* The reduceat indices - ind must be validated outside this call */ |
| 3506 | npy_intp *reduceat_ind; |
| 3507 | npy_intp i, ind_size, red_axis_size; |
| 3508 | |
| 3509 | const char *ufunc_name = ufunc_get_name_cstr(ufunc); |
| 3510 | char *opname = "reduceat"; |
| 3511 | |
| 3512 | /* These parameters come from extobj= or from a TLS global */ |
| 3513 | int buffersize = 0, errormask = 0; |
| 3514 | |
| 3515 | NPY_BEGIN_THREADS_DEF; |
| 3516 | |
| 3517 | reduceat_ind = (npy_intp *)PyArray_DATA(ind); |
| 3518 | ind_size = PyArray_DIM(ind, 0); |
| 3519 | red_axis_size = PyArray_DIM(arr, axis); |
| 3520 | |
| 3521 | /* Check for out-of-bounds values in indices array */ |
| 3522 | for (i = 0; i < ind_size; ++i) { |
| 3523 | if (reduceat_ind[i] < 0 || reduceat_ind[i] >= red_axis_size) { |
| 3524 | PyErr_Format(PyExc_IndexError, |
| 3525 | "index %" NPY_INTP_FMT " out-of-bounds in %s.%s [0, %" NPY_INTP_FMT ")", |
| 3526 | reduceat_ind[i], ufunc_name, opname, red_axis_size); |
| 3527 | return NULL; |
| 3528 | } |
| 3529 | } |
| 3530 | |
| 3531 | NPY_UF_DBG_PRINT2("\nEvaluating ufunc %s.%s\n", ufunc_name, opname); |
| 3532 | |
| 3533 | #if 0 |
| 3534 | printf("Doing %s.%s on array with dtype : ", ufunc_name, opname); |
| 3535 | PyObject_Print((PyObject *)PyArray_DESCR(arr), stdout, 0); |
| 3536 | printf("\n"); |
| 3537 | printf("Index size is %d\n", (int)ind_size); |
| 3538 | #endif |
| 3539 | |
| 3540 | if (_get_bufsize_errmask(NULL, opname, &buffersize, &errormask) < 0) { |
| 3541 | return NULL; |
| 3542 | } |
| 3543 |
no test coverage detected