def _apply(self, input): device = backend.get_device(input) with device: coord = backend.to_device(self.coord, device) return interp.interpolate(input, coord, kernel=self.kernel, width=self.width, param=self.param)
def _apply(self, input): device = backend.get_device(input) coord = backend.to_device(self.coord, device) kernel = backend.to_device(self.kernel, device) with device: return interp.interpolate(input, self.width, kernel, coord)
def test_interpolate_cpu_gpu(self): for ndim in [1, 2, 3]: for dtype in [np.float32, np.complex64]: with self.subTest(ndim=ndim, dtype=dtype): shape = [2, 20] + [1] * (ndim - 1) coord = np.random.random([10, ndim]) input = np.random.random(shape).astype(dtype=dtype) output_cpu = interp.interpolate(input, coord, kernel="kaiser_bessel") output_gpu = interp.interpolate( cp.array(input), cp.array(coord), kernel="kaiser_bessel").get() np.testing.assert_allclose(output_cpu, output_gpu, atol=1e-5)
def nufft(input, coord, oversamp=1.25, width=4): """Non-uniform Fast Fourier Transform. Args: input (array): input signal domain array of shape (..., n_{ndim - 1}, ..., n_1, n_0), where ndim is specified by coord.shape[-1]. The nufft is applied on the last ndim axes, and looped over the remaining axes. coord (array): Fourier domain coordinate array of shape (..., ndim). ndim determines the number of dimensions to apply the nufft. coord[..., i] should be scaled to have its range between -n_i // 2, and n_i // 2. oversamp (float): oversampling factor. width (float): interpolation kernel full-width in terms of oversampled grid. n (int): number of sampling points of the interpolation kernel. Returns: array: Fourier domain data of shape input.shape[:-ndim] + coord.shape[:-1]. References: Fessler, J. A., & Sutton, B. P. (2003). Nonuniform fast Fourier transforms using min-max interpolation IEEE Transactions on Signal Processing, 51(2), 560-574. Beatty, P. J., Nishimura, D. G., & Pauly, J. M. (2005). Rapid gridding reconstruction with a minimal oversampling ratio. IEEE transactions on medical imaging, 24(6), 799-808. """ ndim = coord.shape[-1] beta = np.pi * (((width / oversamp) * (oversamp - 0.5))**2 - 0.8)**0.5 os_shape = _get_oversamp_shape(input.shape, ndim, oversamp) output = input.copy() # Apodize _apodize(output, ndim, oversamp, width, beta) # Zero-pad output /= util.prod(input.shape[-ndim:])**0.5 output = util.resize(output, os_shape) # FFT output = fft(output, axes=range(-ndim, 0), norm=None) # Interpolate coord = _scale_coord(coord, input.shape, oversamp) output = interp.interpolate(output, coord, kernel='kaiser_bessel', width=width, param=beta) output /= width**ndim return output
def test_interpolate(self): batch = 2 for ndim in [1, 2, 3]: shape = [3] + [1] * (ndim - 1) width = 2.0 kernel = np.array([1.0, 0.5]) coord = np.array([[0.1] + [0] * (ndim - 1), [1.1] + [0] * (ndim - 1), [2.1] + [0] * (ndim - 1)]) input = np.array([[0, 1.0, 0]] * batch).reshape([batch] + shape) output = interp.interpolate(input, width, kernel, coord) output_expected = np.array([[0.1, 0.9, 0]] * batch) np.testing.assert_allclose(output, output_expected)
def test_interpolate_cuda(self): batch = 2 for ndim in [1, 2, 3]: for dtype in [np.float, np.complex64, np.complex]: shape = [3] + [1] * (ndim - 1) width = 2.0 kernel = cp.array([1.0, 0.5]) coord = cp.array([[0.1] + [0] * (ndim - 1), [1.1] + [0] * (ndim - 1), [2.1] + [0] * (ndim - 1)]) input = cp.array([[0, 1.0, 0]] * batch, dtype=dtype).reshape([batch] + shape) output = interp.interpolate(input, width, kernel, coord) output_expected = cp.array([[0.1, 0.9, 0]] * batch, dtype=dtype) cp.testing.assert_allclose(output, output_expected, atol=1e-7)
def test_interpolate_spline(self): xps = [np] if config.cupy_enabled: xps.append(cp) batch = 2 for xp in xps: for ndim in [1, 2, 3]: for dtype in [np.float32, np.complex64]: with self.subTest(ndim=ndim, xp=xp, dtype=dtype): shape = [3] + [1] * (ndim - 1) coord = xp.array([[0.1] + [0] * (ndim - 1), [1.1] + [0] * (ndim - 1), [2.1] + [0] * (ndim - 1)]) input = xp.array([[0, 1.0, 0]] * batch, dtype=dtype) input = input.reshape([batch] + shape) output = interp.interpolate(input, coord) output_expected = xp.array([[0.1, 0.9, 0]] * batch) xp.testing.assert_allclose(output, output_expected, atol=1e-7)
def test_interpolate(self): xps = [np] if config.cupy_enabled: xps.append(cp) batch = 2 for xp in xps: for ndim in [1, 2, 3]: with self.subTest(ndim=ndim, xp=xp): shape = [3] + [1] * (ndim - 1) width = 2.0 kernel = xp.array([1.0, 0.5]) coord = xp.array([[0.1] + [0] * (ndim - 1), [1.1] + [0] * (ndim - 1), [2.1] + [0] * (ndim - 1)]) input = xp.array([[0, 1.0, 0]] * batch).reshape([batch] + shape) output = interp.interpolate(input, width, kernel, coord) output_expected = xp.array([[0.1, 0.9, 0]] * batch) xp.testing.assert_allclose(output, output_expected, atol=1e-7)