def test_convolve_adjoint_input_full(self): mode = 'full' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for device in devices: xp = device.xp with device: for dtype in [np.float32, np.float64, np.complex64, np.complex128]: y = xp.ones([1, 5], dtype=dtype) W = xp.ones([1, 3], dtype=dtype) x = backend.to_device(conv.convolve_adjoint_input(W, y, mode=mode), backend.cpu_device) npt.assert_allclose(x, [[3, 3, 3]], atol=1e-5) y = xp.ones([1, 4], dtype=dtype) W = xp.ones([1, 2], dtype=dtype) x = backend.to_device(conv.convolve_adjoint_input(W, y, mode=mode), backend.cpu_device) npt.assert_allclose(x, [[2, 2, 2]], atol=1e-5) y = xp.ones([2, 1, 5], dtype=dtype) W = xp.ones([2, 1, 3], dtype=dtype) x = backend.to_device(conv.convolve_adjoint_input(W, y, mode=mode, output_multi_channel=True), backend.cpu_device) npt.assert_allclose(x, [[6, 6, 6]], atol=1e-5)
def test_convolve_valid(self): mode = 'valid' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for D in [1, 2, 3]: for device in devices: xp = device.xp with device: for dtype in dtypes: with self.subTest(D=D, dtype=dtype, device=device): data = util.dirac([3] + [1] * (D - 1), device=device, dtype=dtype) filt = xp.ones([3] + [1] * (D - 1), dtype=dtype) output = backend.to_device(conv.convolve( data, filt, mode=mode)) npt.assert_allclose( output, np.ones([1] * D), atol=1e-5) data = util.dirac([3] + [1] * (D - 1), device=device, dtype=dtype) filt = xp.ones([2] + [1] * (D - 1), dtype=dtype) output = backend.to_device(conv.convolve( data, filt, mode=mode)) npt.assert_allclose( output, np.ones([2] + [1] * (D - 1)), atol=1e-5) data = util.dirac([1, 3] + [1] * (D - 1), device=device, dtype=dtype) filt = xp.ones([2, 1, 3] + [1] * (D - 1), dtype=dtype) output = backend.to_device( conv.convolve(data, filt, mode=mode, multi_channel=True), backend.cpu_device) npt.assert_allclose( output, np.ones([2, 1] + [1] * (D - 1)), atol=1e-5) data = util.dirac([1, 3] + [1] * (D - 1), device=device, dtype=dtype) filt = xp.ones([2, 1, 3] + [1] * (D - 1), dtype=dtype) strides = [2] + [1] * (D - 1) output = backend.to_device( conv.convolve(data, filt, mode=mode, strides=strides, multi_channel=True), backend.cpu_device) npt.assert_allclose( output, np.ones([2, 1] + [1] * (D - 1)), atol=1e-5)
def test_convolve_full(self): mode = 'full' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for device in devices: xp = device.xp with device: for dtype in [np.float32, np.float64, np.complex64, np.complex128]: x = util.dirac([1, 3], device=device, dtype=dtype) W = xp.ones([1, 3], dtype=dtype) y = backend.to_device(conv.convolve(x, W, mode=mode), backend.cpu_device) npt.assert_allclose(y, [[0, 1, 1, 1, 0]], atol=1e-5) x = util.dirac([1, 3], device=device, dtype=dtype) W = xp.ones([1, 2], dtype=dtype) y = backend.to_device(conv.convolve(x, W, mode=mode), backend.cpu_device) npt.assert_allclose(y, [[0, 1, 1, 0]], atol=1e-5) x = util.dirac([1, 3], device=device, dtype=dtype) W = xp.ones([2, 1, 3], dtype=dtype) y = backend.to_device(conv.convolve(x, W, mode=mode, output_multi_channel=True), backend.cpu_device) npt.assert_allclose(y, [[[0, 1, 1, 1, 0]], [[0, 1, 1, 1, 0]]], atol=1e-5)
def test_convolve_adjoint_filter_valid(self): mode = 'valid' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) ndim = 2 for device in devices: xp = device.xp with device: for dtype in [np.float32, np.float64, np.complex64, np.complex128]: x = xp.ones([1, 3], dtype=dtype) y = xp.ones([1, 1], dtype=dtype) W = backend.to_device(conv.convolve_adjoint_filter(x, y, ndim, mode=mode), backend.cpu_device) npt.assert_allclose(W, [[1, 1, 1]], atol=1e-5) x = xp.ones([1, 3], dtype=dtype) y = xp.ones([1, 2], dtype=dtype) W = backend.to_device(conv.convolve_adjoint_filter(x, y, ndim, mode=mode), backend.cpu_device) npt.assert_allclose(W, [[2, 2]], atol=1e-5) x = xp.ones([1, 1, 3], dtype=dtype) y = xp.ones([2, 1, 1], dtype=dtype) W = backend.to_device(conv.convolve_adjoint_filter(x, y, ndim, mode=mode, output_multi_channel=True), backend.cpu_device) npt.assert_allclose(W, [[[1, 1, 1]], [[1, 1, 1]]], atol=1e-5)
def test_convolve_filter_adjoint_full(self): mode = 'full' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for device in devices: xp = device.xp with device: for dtype in dtypes: with self.subTest(dtype=dtype, device=device): data = xp.ones([1, 3], dtype=dtype) output = xp.ones([1, 5], dtype=dtype) filt_shape = [1, 3] filt = backend.to_device( conv.convolve_filter_adjoint(output, data, filt_shape, mode=mode)) npt.assert_allclose(filt, [[3, 3, 3]], atol=1e-5) data = xp.ones([1, 3], dtype=dtype) output = xp.ones([1, 4], dtype=dtype) filt_shape = [1, 2] filt = backend.to_device( conv.convolve_filter_adjoint(output, data, filt_shape, mode=mode)) npt.assert_allclose(filt, [[3, 3]], atol=1e-5) data = xp.ones([1, 1, 3], dtype=dtype) output = xp.ones([2, 1, 5], dtype=dtype) filt_shape = [2, 1, 1, 3] filt = backend.to_device( conv.convolve_filter_adjoint(output, data, filt_shape, mode=mode, multi_channel=True), backend.cpu_device) npt.assert_allclose(filt, [[[[3, 3, 3]]], [[[3, 3, 3]]]], atol=1e-5) data = xp.ones([1, 1, 3], dtype=dtype) output = xp.ones([2, 1, 3], dtype=dtype) filt_shape = [2, 1, 1, 3] strides = [1, 2] filt = backend.to_device( conv.convolve_filter_adjoint(output, data, filt_shape, mode=mode, strides=strides, multi_channel=True), backend.cpu_device) npt.assert_allclose(filt, [[[[2, 1, 2]]], [[[2, 1, 2]]]], atol=1e-5)
def randn(shape, scale=1, dtype=np.float, device=backend.cpu_device): """Create random Gaussian array. Args: shape (tuple of ints): Output shape. scale (float): Standard deviation. dtype (Dtype): Output data-type. device (Device): Output device. Returns: array: Random Gaussian array. """ device = backend.Device(device) xp = device.xp with device: if np.issubdtype(dtype, np.complexfloating): real_dtype = np.array([], dtype=dtype).real.dtype real_shape = tuple(shape) + (2, ) output = xp.random.normal(size=real_shape, scale=scale / 2**0.5) output = output.astype(real_dtype) output = output.view(dtype=dtype).reshape(shape) return output else: return xp.random.normal(size=shape, scale=scale).astype(dtype)
def check_linop_unitary(A, dtype=np.float, device=backend.cpu_device): device = backend.Device(device) x = util.randn(A.ishape, dtype=dtype, device=device) xp = device.xp with device: xp.testing.assert_allclose(A.H * A * x, x, atol=1e-5, rtol=1e-5)
def check_linop_normal(self, A, device=backend.cpu_device, dtype=np.float): device = backend.Device(device) x = util.randn(A.ishape, dtype=dtype, device=device) xp = device.xp with device: lhs = A.H * A * x rhs = A.N * x xp.testing.assert_allclose(lhs, rhs, atol=1e-2, rtol=1e-3)
def test_convolve_data_adjoint_valid(self): mode = 'valid' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for device in devices: xp = device.xp with device: for dtype in dtypes: with self.subTest(dtype=dtype, device=device): output = xp.ones([1, 1], dtype=dtype) filt = xp.ones([1, 3], dtype=dtype) data_shape = [1, 3] data = backend.to_device( conv.convolve_data_adjoint(output, filt, data_shape, mode=mode)) npt.assert_allclose(data, [[1, 1, 1]], atol=1e-5) output = xp.ones([1, 2], dtype=dtype) filt = xp.ones([1, 2], dtype=dtype) data_shape = [1, 3] data = backend.to_device( conv.convolve_data_adjoint(output, filt, data_shape, mode=mode)) npt.assert_allclose(data, [[1, 2, 1]], atol=1e-5) output = xp.ones([2, 1, 1], dtype=dtype) filt = xp.ones([2, 1, 1, 3], dtype=dtype) data_shape = [1, 1, 3] data = backend.to_device( conv.convolve_data_adjoint(output, filt, data_shape, mode=mode, multi_channel=True), backend.cpu_device) npt.assert_allclose(data, [[[2, 2, 2]]], atol=1e-5) output = xp.ones([2, 1, 1], dtype=dtype) filt = xp.ones([2, 1, 1, 3], dtype=dtype) data_shape = [1, 1, 4] strides = [1, 2] data = backend.to_device( conv.convolve_data_adjoint(output, filt, data_shape, mode=mode, strides=strides, multi_channel=True), backend.cpu_device) npt.assert_allclose(data, [[[2, 2, 2, 0]]], atol=1e-5)
def check_linop_unitary(self, A, devices=devices, dtypes=dtypes): for device in devices: for dtype in dtypes: with self.subTest(A=A, dtype=dtype, device=device): device = backend.Device(device) x = util.randn(A.ishape, dtype=dtype, device=device) xp = device.xp with device: xp.testing.assert_allclose(A.H * A * x, x, atol=1e-5, rtol=1e-5)
def check_linop_adjoint(A, dtype=np.float, device=backend.cpu_device): device = backend.Device(device) x = util.randn(A.ishape, dtype=dtype, device=device) y = util.randn(A.oshape, dtype=dtype, device=device) xp = device.xp with device: lhs = xp.vdot(A * x, y) rhs = xp.vdot(x, A.H * y) xp.testing.assert_allclose(lhs, rhs, atol=1e-5, rtol=1e-5)
def check_linop_linear(self, A, device=backend.cpu_device, dtype=np.float): device = backend.Device(device) a = util.randn([1], dtype=dtype, device=device) x = util.randn(A.ishape, dtype=dtype, device=device) y = util.randn(A.ishape, dtype=dtype, device=device) xp = device.xp with device: xp.testing.assert_allclose(A(a * x + y), a * A(x) + A(y), atol=1e-5, rtol=1e-5)
def test_convolve_full(self): mode = 'full' devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) dtypes = [np.float32, np.float64, np.complex64, np.complex128] for device in devices: xp = device.xp with device: for dtype in dtypes: with self.subTest(dtype=dtype, device=device): data = util.dirac([1, 3], device=device, dtype=dtype) filt = xp.ones([1, 3], dtype=dtype) output = backend.to_device( conv.convolve(data, filt, mode=mode)) npt.assert_allclose(output, [[0, 1, 1, 1, 0]], atol=1e-5) data = util.dirac([1, 3], device=device, dtype=dtype) filt = xp.ones([1, 2], dtype=dtype) output = backend.to_device( conv.convolve(data, filt, mode=mode)) npt.assert_allclose(output, [[0, 1, 1, 0]], atol=1e-5) data = util.dirac([1, 1, 3], device=device, dtype=dtype) filt = xp.ones([2, 1, 1, 3], dtype=dtype) output = backend.to_device( conv.convolve(data, filt, mode=mode, multi_channel=True), backend.cpu_device) npt.assert_allclose( output, [[[0, 1, 1, 1, 0]], [[0, 1, 1, 1, 0]]], atol=1e-5) data = util.dirac([1, 1, 3], device=device, dtype=dtype) filt = xp.ones([2, 1, 1, 3], dtype=dtype) strides = [1, 2] output = backend.to_device( conv.convolve(data, filt, mode=mode, strides=strides, multi_channel=True)) npt.assert_allclose(output, [[[0, 1, 0]], [[0, 1, 0]]], atol=1e-5)
def check_linop_linear(self, A, devices=devices, dtypes=dtypes): for device in devices: for dtype in dtypes: with self.subTest(A=A, dtype=dtype, device=device): device = backend.Device(device) a = util.randn([1], dtype=dtype, device=device) x = util.randn(A.ishape, dtype=dtype, device=device) y = util.randn(A.ishape, dtype=dtype, device=device) xp = device.xp with device: xp.testing.assert_allclose(A(a * x + y), a * A(x) + A(y), atol=1e-5, rtol=1e-5)
def check_linop_adjoint(self, A, devices=devices, dtypes=dtypes): for device in devices: for dtype in dtypes: with self.subTest(A=A, dtype=dtype, device=device): device = backend.Device(device) x = util.randn(A.ishape, dtype=dtype, device=device) y = util.randn(A.oshape, dtype=dtype, device=device) xp = device.xp with device: lhs = xp.vdot(A * x, y) rhs = xp.vdot(x, A.H * y) xp.testing.assert_allclose(lhs, rhs, atol=1e-5, rtol=1e-5)
def dirac(shape, dtype=np.float, device=backend.cpu_device): """Create Dirac delta. Args: shape (tuple of ints): Output shape. dtype (Dtype): Output data-type. device (Device): Output device. Returns: array: Dirac delta array. """ device = backend.Device(device) xp = device.xp with device: return resize(xp.ones([1], dtype=dtype), shape)
def test_ConvolveFilter(self): devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) for device in devices: for mode in ['full', 'valid']: W_shape = [2, 3] x = util.randn([3, 4], device=device) A = linop.ConvolveFilter(W_shape, x, mode=mode) check_linop_linear(A, device=device) check_linop_adjoint(A, device=device) check_linop_pickleable(A) W_shape = [4, 2, 3] x = util.randn([4, 3, 4], device=device) A = linop.ConvolveFilter(W_shape, x, mode=mode, input_multi_channel=True) check_linop_linear(A, device=device) check_linop_adjoint(A, device=device) check_linop_pickleable(A) W_shape = [4, 2, 3] x = util.randn([3, 4], device=device) A = linop.ConvolveFilter(W_shape, x, mode=mode, output_multi_channel=True) check_linop_linear(A, device=device) check_linop_adjoint(A, device=device) check_linop_pickleable(A) W_shape = [4, 2, 2, 3] x = util.randn([2, 3, 4], device=device) A = linop.ConvolveFilter(W_shape, x, mode=mode, input_multi_channel=True, output_multi_channel=True) check_linop_linear(A, device=device) check_linop_adjoint(A, device=device) check_linop_pickleable(A)
def _get_kaiser_bessel_kernel(n, width, beta, dtype, device): """Precompute Kaiser Bessel kernel. Precomputes Kaiser-Bessel kernel with n points. Args: n (int): number of sampling points. width (float): kernel width. beta (float): kaiser bessel parameter. dtype (dtype): output data type. device (Device): output device. Returns: array: Kaiser-Bessel kernel table. """ device = backend.Device(device) xp = device.xp with device: x = xp.arange(n, dtype=dtype) / n kernel = 1 / width * xp.i0(beta * (1 - x**2)**0.5).astype(dtype) return kernel
def hanning(shape, dtype=np.float, device=backend.cpu_device): """Create multi-dimensional hanning window. Args: shape (tuple of ints): Output shape. dtype (Dtype): Output data-type. device (Device): Output device. Returns: array: hanning filter. """ device = backend.Device(device) xp = device.xp shape = _normalize_shape(shape) with device: window = xp.ones(shape, dtype=dtype) for n, i in enumerate(shape[::-1]): x = xp.arange(i, dtype=dtype) w = 0.5 - 0.5 * xp.cos(2 * np.pi * x / max(1, (i - (i % 2)))) window *= w.reshape([i] + [1] * n) return window
def triang(shape, dtype=np.float, device=backend.cpu_device): """Create multi-dimensional triangular window. Args: shape (tuple of ints): Output shape. dtype (Dtype): Output data-type. device (Device): Output device. Returns: array: triangular filter. """ device = backend.Device(device) xp = device.xp shape = _normalize_shape(shape) with device: window = xp.ones(shape, dtype=dtype) for n, i in enumerate(shape[::-1]): x = xp.arange(i, dtype=dtype) w = 1 - xp.abs(x - i // 2 + ((i + 1) % 2) / 2) / ((i + 1) // 2) window *= w.reshape([i] + [1] * n) return window
def test_device(self): device = backend.Device(-1) pickle.dumps(device)
import unittest import numpy as np import numpy.testing as npt from sigpy import backend, config, linop, pytorch if config.pytorch_enabled: import torch if __name__ == '__main__': unittest.main() devices = [backend.cpu_device] if config.cupy_enabled: devices.append(backend.Device(0)) class TestPytorch(unittest.TestCase): def test_to_pytorch(self): for dtype in [np.float32, np.float64]: for device in devices: with self.subTest(device=device, dtype=dtype): xp = device.xp array = xp.array([1, 2, 3], dtype=dtype) tensor = pytorch.to_pytorch(array) tensor[0] = 0 xp.testing.assert_allclose(array, [0, 2, 3]) def test_to_pytorch_complex(self): for dtype in [np.complex64, np.complex128]: for device in devices: