Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r51672:d246547e90d8 Date: 2012-01-23 02:04 +0200 http://bitbucket.org/pypy/pypy/changeset/d246547e90d8/
Log: (mattip) merge numpypy-reshape-bug diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -174,15 +174,17 @@ # fits the new shape, using those steps. If there is a shape/step mismatch # (meaning that the realignment of elements crosses from one step into another) # return None so that the caller can raise an exception. -def calc_new_strides(new_shape, old_shape, old_strides): +def calc_new_strides(new_shape, old_shape, old_strides, order): + # Return the proper strides for new_shape, or None if the mapping crosses + # stepping boundaries + # Assumes that prod(old_shape) == prod(new_shape), len(old_shape) > 1, and # len(new_shape) > 0 steps = [] last_step = 1 oldI = 0 new_strides = [] - if old_strides[0] < old_strides[-1]: - #Start at old_shape[0], old_stides[0] + if order == 'F': for i in range(len(old_shape)): steps.append(old_strides[i] / last_step) last_step *= old_shape[i] @@ -199,12 +201,10 @@ n_old_elems_to_use *= old_shape[oldI] if n_new_elems_used == n_old_elems_to_use: oldI += 1 - if oldI >= len(old_shape): - continue - cur_step = steps[oldI] - n_old_elems_to_use *= old_shape[oldI] - else: - #Start at old_shape[-1], old_strides[-1] + if oldI < len(old_shape): + cur_step = steps[oldI] + n_old_elems_to_use *= old_shape[oldI] + elif order == 'C': for i in range(len(old_shape) - 1, -1, -1): steps.insert(0, old_strides[i] / last_step) last_step *= old_shape[i] @@ -223,10 +223,10 @@ n_old_elems_to_use *= old_shape[oldI] if n_new_elems_used == n_old_elems_to_use: oldI -= 1 - if oldI < -len(old_shape): - continue - cur_step = steps[oldI] - n_old_elems_to_use *= old_shape[oldI] + if oldI >= -len(old_shape): + cur_step = steps[oldI] + n_old_elems_to_use *= old_shape[oldI] + assert len(new_strides) == len(new_shape) return new_strides class BaseArray(Wrappable): @@ -631,8 +631,8 @@ concrete = self.get_concrete() new_shape = get_shape_from_iterable(space, concrete.size, w_shape) # Since we got to here, prod(new_shape) == self.size - new_strides = calc_new_strides(new_shape, - concrete.shape, concrete.strides) + new_strides = calc_new_strides(new_shape, concrete.shape, + concrete.strides, concrete.order) if new_strides: # We can create a view, strides somehow match up. ndims = len(new_shape) @@ -1221,7 +1221,8 @@ self.backstrides = backstrides self.shape = new_shape return - new_strides = calc_new_strides(new_shape, self.shape, self.strides) + new_strides = calc_new_strides(new_shape, self.shape, self.strides, + self.order) if new_strides is None: raise OperationError(space.w_AttributeError, space.wrap( "incompatible shape for a non-contiguous array")) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -154,13 +154,18 @@ def test_calc_new_strides(self): from pypy.module.micronumpy.interp_numarray import calc_new_strides - assert calc_new_strides([2, 4], [4, 2], [4, 2]) == [8, 2] - assert calc_new_strides([2, 4, 3], [8, 3], [1, 16]) == [1, 2, 16] - assert calc_new_strides([2, 3, 4], [8, 3], [1, 16]) is None - assert calc_new_strides([24], [2, 4, 3], [48, 6, 1]) is None - assert calc_new_strides([24], [2, 4, 3], [24, 6, 2]) == [2] - assert calc_new_strides([105, 1], [3, 5, 7], [35, 7, 1]) == [1, 1] - assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1]) == [105, 1] + assert calc_new_strides([2, 4], [4, 2], [4, 2], "C") == [8, 2] + assert calc_new_strides([2, 4, 3], [8, 3], [1, 16], 'F') == [1, 2, 16] + assert calc_new_strides([2, 3, 4], [8, 3], [1, 16], 'F') is None + assert calc_new_strides([24], [2, 4, 3], [48, 6, 1], 'C') is None + assert calc_new_strides([24], [2, 4, 3], [24, 6, 2], 'C') == [2] + assert calc_new_strides([105, 1], [3, 5, 7], [35, 7, 1],'C') == [1, 1] + assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1],'C') == [105, 1] + assert calc_new_strides([1, 105], [3, 5, 7], [35, 7, 1],'F') is None + assert calc_new_strides([1, 1, 1, 105, 1], [15, 7], [7, 1],'C') == \ + [105, 105, 105, 1, 1] + assert calc_new_strides([1, 1, 105, 1, 1], [7, 15], [1, 7],'F') == \ + [1, 1, 1, 105, 105] class AppTestNumArray(BaseNumpyAppTest): @@ -385,6 +390,8 @@ a.shape = () #numpy allows this a.shape = (1,) + a = array(range(6)).reshape(2,3).T + raises(AttributeError, 'a.shape = 6') def test_reshape(self): from _numpypy import array, zeros _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit