| 265 | */ |
| 266 | template <typename Tag, bool arg, typename type> |
| 267 | NPY_NO_EXPORT int |
| 268 | introselect_(type *v, npy_intp *tosort, npy_intp num, npy_intp kth, |
| 269 | npy_intp *pivots, npy_intp *npiv) |
| 270 | { |
| 271 | Idx<arg> idx(tosort); |
| 272 | Sortee<type, arg> sortee(v, tosort); |
| 273 | |
| 274 | npy_intp low = 0; |
| 275 | npy_intp high = num - 1; |
| 276 | int depth_limit; |
| 277 | |
| 278 | if (npiv == NULL) { |
| 279 | pivots = NULL; |
| 280 | } |
| 281 | |
| 282 | while (pivots != NULL && *npiv > 0) { |
| 283 | if (pivots[*npiv - 1] > kth) { |
| 284 | /* pivot larger than kth set it as upper bound */ |
| 285 | high = pivots[*npiv - 1] - 1; |
| 286 | break; |
| 287 | } |
| 288 | else if (pivots[*npiv - 1] == kth) { |
| 289 | /* kth was already found in a previous iteration -> done */ |
| 290 | return 0; |
| 291 | } |
| 292 | |
| 293 | low = pivots[*npiv - 1] + 1; |
| 294 | |
| 295 | /* pop from stack */ |
| 296 | *npiv -= 1; |
| 297 | } |
| 298 | |
| 299 | /* |
| 300 | * use a faster O(n*kth) algorithm for very small kth |
| 301 | * e.g. for interpolating percentile |
| 302 | */ |
| 303 | if (kth - low < 3) { |
| 304 | dumb_select_<Tag, arg>(v + (arg ? 0 : low), tosort + (arg ? low : 0), |
| 305 | high - low + 1, kth - low); |
| 306 | store_pivot(kth, kth, pivots, npiv); |
| 307 | return 0; |
| 308 | } |
| 309 | |
| 310 | else if (inexact<type>() && kth == num - 1) { |
| 311 | /* useful to check if NaN present via partition(d, (x, -1)) */ |
| 312 | npy_intp k; |
| 313 | npy_intp maxidx = low; |
| 314 | type maxval = v[idx(low)]; |
| 315 | for (k = low + 1; k < num; k++) { |
| 316 | if (!Tag::less(v[idx(k)], maxval)) { |
| 317 | maxidx = k; |
| 318 | maxval = v[idx(k)]; |
| 319 | } |
| 320 | } |
| 321 | std::swap(sortee(kth), sortee(maxidx)); |
| 322 | return 0; |
| 323 | } |
| 324 |
nothing calls this directly
no test coverage detected