def _call(self, x, out): """Implement ``self(x, out)``.""" with writable_array(out) as out_arr: resize_array(x.asarray(), op.domain.shape, offset=op.offset, pad_mode=op.pad_mode, pad_const=0, direction='adjoint', out=out_arr)
def test_resize_array_adj(resize_setup, odl_floating_dtype): dtype = odl_floating_dtype pad_mode, pad_const, newshp, offset, array, _ = resize_setup if pad_const != 0: # Not well-defined return array = np.array(array, dtype=dtype) if is_real_dtype(dtype): other_arr = np.random.uniform(-10, 10, size=newshp) else: other_arr = (np.random.uniform(-10, 10, size=newshp) + 1j * np.random.uniform(-10, 10, size=newshp)) resized = resize_array(array, newshp, offset, pad_mode, pad_const, direction='forward') resized_adj = resize_array(other_arr, array.shape, offset, pad_mode, pad_const, direction='adjoint') assert (np.vdot(resized.ravel(), other_arr.ravel()) == pytest.approx(np.vdot( array.ravel(), resized_adj.ravel()), rel=dtype_tol(dtype)))
def _call(self, x, out): """Implement ``self(x, out)``.""" with writable_array(out) as out_arr: resize_array(x.asarray(), self.range.shape, offset=self.offset, pad_mode=self.pad_mode, pad_const=self.pad_const, direction='forward', out=out_arr)
def test_resize_array_fwd(resize_setup, scalar_dtype): pad_mode, pad_const, newshp, offset, array_in, true_out = resize_setup array_in = np.array(array_in, dtype=scalar_dtype) true_out = np.array(true_out, dtype=scalar_dtype) resized = resize_array(array_in, newshp, offset, pad_mode, pad_const, direction='forward') out = np.empty(newshp, dtype=scalar_dtype) resize_array(array_in, newshp, offset, pad_mode, pad_const, direction='forward', out=out) assert np.array_equal(resized, true_out) assert np.array_equal(out, true_out)
def _call(self, x, out): """Implement ``self(x, out)``.""" # TODO: simplify once context manager is available out[:] = resize_array( x.asarray(), self.range.shape, offset=self.offset, pad_mode=self.pad_mode, pad_const=0, direction='adjoint', out=out.asarray())
def _call(self, x, out): """Implement ``self(x, out)``.""" # TODO: simplify once context manager is available out[:] = resize_array(x.asarray(), self.range.shape, offset=self.offset, pad_mode=self.pad_mode, pad_const=0, direction='adjoint', out=out.asarray())
def test_resize_array_corner_cases(odl_scalar_dtype, padding): # Test extreme cases of resizing that are still valid for several # `pad_mode`s dtype = odl_scalar_dtype pad_mode, pad_const = padding # Test array arr = np.arange(12, dtype=dtype).reshape((3, 4)) # Resize to and from 0 total size squashed_arr = resize_array(arr, (3, 0), pad_mode=pad_mode) assert squashed_arr.size == 0 squashed_arr = resize_array(arr, (0, 0), pad_mode=pad_mode) assert squashed_arr.size == 0 if pad_mode == 'constant': # Blowing up from size 0 only works with constant padding true_blownup_arr = np.empty_like(arr) true_blownup_arr.fill(pad_const) blownup_arr = resize_array(np.ones((3, 0), dtype=dtype), (3, 4), pad_mode=pad_mode, pad_const=pad_const) assert np.array_equal(blownup_arr, true_blownup_arr) blownup_arr = resize_array(np.ones((0, 0), dtype=dtype), (3, 4), pad_mode=pad_mode, pad_const=pad_const) assert np.array_equal(blownup_arr, true_blownup_arr) # Resize from 0 axes to 0 axes zero_axes_arr = resize_array(np.array(0, dtype=dtype), (), pad_mode=pad_mode) assert zero_axes_arr == np.array(0, dtype=dtype) if pad_mode == 'periodic': # Resize with periodic padding, using all values from the original # array on both sides max_per_shape = (9, 12) res_arr = resize_array(arr, max_per_shape, pad_mode='periodic', offset=arr.shape) assert np.array_equal(res_arr, np.tile(arr, (3, 3))) elif pad_mode == 'symmetric': # Symmetric padding, maximum number is one less compared to periodic # padding since the boundary value is not repeated arr = np.arange(6).reshape((2, 3)) max_sym_shape = (4, 7) res_arr = resize_array(arr, max_sym_shape, pad_mode='symmetric', offset=[1, 2]) true_arr = np.array([[5, 4, 3, 4, 5, 4, 3], [2, 1, 0, 1, 2, 1, 0], [5, 4, 3, 4, 5, 4, 3], [2, 1, 0, 1, 2, 1, 0]]) assert np.array_equal(res_arr, true_arr)
def test_resize_array_adj(resize_setup, floating_dtype): pad_mode, pad_const, newshp, offset, array, _ = resize_setup if pad_const != 0: # Not well-defined return array = np.array(array, dtype=floating_dtype) if is_real_dtype(floating_dtype): other_arr = np.random.uniform(-10, 10, size=newshp) else: other_arr = (np.random.uniform(-10, 10, size=newshp) + 1j * np.random.uniform(-10, 10, size=newshp)) resized = resize_array(array, newshp, offset, pad_mode, pad_const, direction='forward') resized_adj = resize_array(other_arr, array.shape, offset, pad_mode, pad_const, direction='adjoint') assert almost_equal(np.vdot(resized.ravel(), other_arr.ravel()), np.vdot(array.ravel(), resized_adj.ravel()))
def test_resize_array_corner_cases(scalar_dtype, padding): # Test extreme cases of resizing that are still valid for several # `pad_mode`s pad_mode, pad_const = padding # Test array arr = np.arange(12, dtype=scalar_dtype).reshape((3, 4)) # Resize to and from 0 total size squashed_arr = resize_array(arr, (3, 0), pad_mode=pad_mode) assert squashed_arr.size == 0 squashed_arr = resize_array(arr, (0, 0), pad_mode=pad_mode) assert squashed_arr.size == 0 if pad_mode == 'constant': # Blowing up from size 0 only works with constant padding true_blownup_arr = np.empty_like(arr) true_blownup_arr.fill(pad_const) blownup_arr = resize_array(np.ones((3, 0), dtype=scalar_dtype), (3, 4), pad_mode=pad_mode, pad_const=pad_const) assert np.array_equal(blownup_arr, true_blownup_arr) blownup_arr = resize_array(np.ones((0, 0), dtype=scalar_dtype), (3, 4), pad_mode=pad_mode, pad_const=pad_const) assert np.array_equal(blownup_arr, true_blownup_arr) # Resize from 0 axes to 0 axes zero_axes_arr = resize_array(np.array(0, dtype=scalar_dtype), (), pad_mode=pad_mode) assert zero_axes_arr == np.array(0, dtype=scalar_dtype) if pad_mode == 'periodic': # Resize with periodic padding, using all values from the original # array on both sides max_per_shape = (9, 12) res_arr = resize_array(arr, max_per_shape, pad_mode='periodic', offset=arr.shape) assert np.array_equal(res_arr, np.tile(arr, (3, 3))) elif pad_mode == 'symmetric': # Symmetric padding, maximum number is one less compared to periodic # padding since the boundary value is not repeated arr = np.arange(6).reshape((2, 3)) max_sym_shape = (4, 7) res_arr = resize_array(arr, max_sym_shape, pad_mode='symmetric', offset=[1, 2]) true_arr = np.array( [[5, 4, 3, 4, 5, 4, 3], [2, 1, 0, 1, 2, 1, 0], [5, 4, 3, 4, 5, 4, 3], [2, 1, 0, 1, 2, 1, 0]]) assert np.array_equal(res_arr, true_arr)
def test_resize_array_raise(): arr_1d = np.arange(6) arr_2d = np.arange(6).reshape((2, 3)) # Shape not a sequence with pytest.raises(TypeError): resize_array(arr_1d, 19) # out given, but not an ndarray with pytest.raises(TypeError): resize_array(arr_1d, (10,), out=[]) # out has wrong shape with pytest.raises(ValueError): out = np.empty((4, 5)) resize_array(arr_2d, (5, 5), out=out) # Input and output arrays differ in dimensionality with pytest.raises(ValueError): out = np.empty((4, 5)) resize_array(arr_1d, (4, 5)) with pytest.raises(ValueError): out = np.empty((4, 5)) resize_array(arr_1d, (4, 5), out=out) # invalid pad mode with pytest.raises(ValueError): resize_array(arr_1d, (10,), pad_mode='madeup_mode') # padding constant cannot be cast to output data type with pytest.raises(ValueError): resize_array(arr_1d, (10,), pad_const=1.0) # arr_1d has dtype int with pytest.raises(ValueError): arr_1d_float = arr_1d.astype(float) resize_array(arr_1d_float, (10,), pad_const=1.0j) # Too few entries for order 0 or 1 padding modes empty_arr = np.ones((3, 0)) with pytest.raises(ValueError): resize_array(empty_arr, (3, 1), pad_mode='order0') small_arr = np.ones((3, 1)) with pytest.raises(ValueError): resize_array(small_arr, (3, 3), pad_mode='order1') # Too large padding sizes for symmetric small_arr = np.ones((3, 1)) with pytest.raises(ValueError): resize_array(small_arr, (3, 2), pad_mode='symmetric') with pytest.raises(ValueError): resize_array(small_arr, (6, 1), pad_mode='symmetric') with pytest.raises(ValueError): resize_array(small_arr, (4, 3), offset=(0, 1), pad_mode='symmetric') # Too large padding sizes for periodic small_arr = np.ones((3, 1)) with pytest.raises(ValueError): resize_array(small_arr, (3, 3), pad_mode='periodic') with pytest.raises(ValueError): resize_array(small_arr, (7, 1), pad_mode='periodic') with pytest.raises(ValueError): resize_array(small_arr, (3, 4), offset=(0, 1), pad_mode='periodic')