@@ -355,10 +355,14 @@ _attempt_nocopy_reshape(PyArrayObject *self, int newnd, npy_intp* newdims,
355
355
int oldnd ;
356
356
npy_intp olddims [NPY_MAXDIMS ];
357
357
npy_intp oldstrides [NPY_MAXDIMS ];
358
- npy_intp np , op ;
358
+ npy_intp np , op , last_stride ;
359
359
int oi , oj , ok , ni , nj , nk ;
360
360
361
361
oldnd = 0 ;
362
+ /*
363
+ * Remove axes with dimension 1 from the old array. They have no effect
364
+ * but would need special cases since their strides do not matter.
365
+ */
362
366
for (oi = 0 ; oi < PyArray_NDIM (self ); oi ++ ) {
363
367
if (PyArray_DIMS (self )[oi ]!= 1 ) {
364
368
olddims [oldnd ] = PyArray_DIMS (self )[oi ];
@@ -390,27 +394,31 @@ _attempt_nocopy_reshape(PyArrayObject *self, int newnd, npy_intp* newdims,
390
394
/* different total sizes; no hope */
391
395
return 0 ;
392
396
}
393
- /* the current code does not handle 0-sized arrays, so give up */
397
+
394
398
if (np == 0 ) {
399
+ /* the current code does not handle 0-sized arrays, so give up */
395
400
return 0 ;
396
401
}
397
402
403
+ /* oi to oj and ni to nj give the axis ranges currently worked with */
398
404
oi = 0 ;
399
405
oj = 1 ;
400
406
ni = 0 ;
401
407
nj = 1 ;
402
- while (ni < newnd && oi < oldnd ) {
408
+ while (ni < newnd && oi < oldnd ) {
403
409
np = newdims [ni ];
404
410
op = olddims [oi ];
405
411
406
412
while (np != op ) {
407
413
if (np < op ) {
414
+ /* Misses trailing 1s, these are handled later */
408
415
np *= newdims [nj ++ ];
409
416
} else {
410
417
op *= olddims [oj ++ ];
411
418
}
412
419
}
413
420
421
+ /* Check whether the original axes can be combined */
414
422
for (ok = oi ; ok < oj - 1 ; ok ++ ) {
415
423
if (is_f_order ) {
416
424
if (oldstrides [ok + 1 ] != olddims [ok ]* oldstrides [ok ]) {
@@ -427,6 +435,7 @@ _attempt_nocopy_reshape(PyArrayObject *self, int newnd, npy_intp* newdims,
427
435
}
428
436
}
429
437
438
+ /* Calculate new strides for all axes currently worked with */
430
439
if (is_f_order ) {
431
440
newstrides [ni ] = oldstrides [oi ];
432
441
for (nk = ni + 1 ; nk < nj ; nk ++ ) {
@@ -444,6 +453,22 @@ _attempt_nocopy_reshape(PyArrayObject *self, int newnd, npy_intp* newdims,
444
453
oi = oj ++ ;
445
454
}
446
455
456
+ /*
457
+ * Set strides corresponding to trailing 1s of the new shape.
458
+ */
459
+ if (ni >= 1 ) {
460
+ last_stride = newstrides [ni - 1 ];
461
+ }
462
+ else {
463
+ last_stride = PyArray_ITEMSIZE (self );
464
+ }
465
+ if (is_f_order ) {
466
+ last_stride *= newdims [ni - 1 ];
467
+ }
468
+ for (nk = ni ; nk < newnd ; nk ++ ) {
469
+ newstrides [nk ] = last_stride ;
470
+ }
471
+
447
472
/*
448
473
fprintf(stderr, "success: _attempt_nocopy_reshape (");
449
474
for (oi=0; oi<oldnd; oi++)
0 commit comments