* attempt to reshape an array without copying data * * The requested newdims are not checked, but must be compatible with * the size of self, which must be non-zero. Other than that this * function should correctly handle all reshapes, including axes of * length 1. Zero strides should work but are untested. * * If a copy is needed, returns 0 * If no copy is needed, returns 1 and fills news
| 368 | * stride of the next-fastest index. |
| 369 | */ |
| 370 | static int |
| 371 | _attempt_nocopy_reshape(PyArrayObject *self, int newnd, const npy_intp *newdims, |
| 372 | npy_intp *newstrides, int is_f_order) |
| 373 | { |
| 374 | int oldnd; |
| 375 | npy_intp olddims[NPY_MAXDIMS]; |
| 376 | npy_intp oldstrides[NPY_MAXDIMS]; |
| 377 | npy_intp last_stride; |
| 378 | int oi, oj, ok, ni, nj, nk; |
| 379 | |
| 380 | oldnd = 0; |
| 381 | /* |
| 382 | * Remove axes with dimension 1 from the old array. They have no effect |
| 383 | * but would need special cases since their strides do not matter. |
| 384 | */ |
| 385 | for (oi = 0; oi < PyArray_NDIM(self); oi++) { |
| 386 | if (PyArray_DIMS(self)[oi]!= 1) { |
| 387 | olddims[oldnd] = PyArray_DIMS(self)[oi]; |
| 388 | oldstrides[oldnd] = PyArray_STRIDES(self)[oi]; |
| 389 | oldnd++; |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | /* oi to oj and ni to nj give the axis ranges currently worked with */ |
| 394 | oi = 0; |
| 395 | oj = 1; |
| 396 | ni = 0; |
| 397 | nj = 1; |
| 398 | while (ni < newnd && oi < oldnd) { |
| 399 | npy_intp np = newdims[ni]; |
| 400 | npy_intp op = olddims[oi]; |
| 401 | |
| 402 | while (np != op) { |
| 403 | if (np < op) { |
| 404 | /* Misses trailing 1s, these are handled later */ |
| 405 | np *= newdims[nj++]; |
| 406 | } else { |
| 407 | op *= olddims[oj++]; |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | /* Check whether the original axes can be combined */ |
| 412 | for (ok = oi; ok < oj - 1; ok++) { |
| 413 | if (is_f_order) { |
| 414 | if (oldstrides[ok+1] != olddims[ok]*oldstrides[ok]) { |
| 415 | /* not contiguous enough */ |
| 416 | return 0; |
| 417 | } |
| 418 | } |
| 419 | else { |
| 420 | /* C order */ |
| 421 | if (oldstrides[ok] != olddims[ok+1]*oldstrides[ok+1]) { |
| 422 | /* not contiguous enough */ |
| 423 | return 0; |
| 424 | } |
| 425 | } |
| 426 | } |
| 427 |
no test coverage detected