def test_type1_rdft(self): """Is the NUFFT type 1 RDFT correct?""" f_dir1 = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1)[:, :int(self.N[1] / 2) + 1] * self.N.prod() f_nufft1 = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1)[:, :int(self.N[1] / 2) + 1] * self.N.prod() self.assertTrue(_error(self.fr_numpy.reshape(-1), f_dir1.reshape(-1)) < self.eps, "NUFFT direct RDFT (1) vs. NumPy RFFT: error too large") self.assertTrue(_error(self.fr_numpy.reshape(-1), f_nufft1.reshape(-1)) < self.eps, "NUFFT RFFT (1) vs. NumPy RFFT: error too large")
def test_type1_rdft(self): """Is the NUFFT type 1 RDFT correct?""" f_dir1 = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1)[:, :int(self.N[1] / 2) + 1] * self.N.prod() f_nufft1 = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1)[:, :int(self.N[1] / 2) + 1] * self.N.prod() self.assertTrue( _error(self.fr_numpy.reshape(-1), f_dir1.reshape(-1)) < self.eps, "NUFFT direct RDFT (1) vs. NumPy RFFT: error too large") self.assertTrue( _error(self.fr_numpy.reshape(-1), f_nufft1.reshape(-1)) < self.eps, "NUFFT RFFT (1) vs. NumPy RFFT: error too large")
def test_type1_idft(self): """Is the NUFFT type 1 IDFT correct?""" c_dir = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.f_numpy.reshape(-1), self.N[0], self.N[1], iflag=1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) c_nufft = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.f_numpy.reshape(-1), self.N[0], self.N[1], iflag=1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue(_error(self.c_numpy.reshape(-1), c_dir.reshape(-1)) < self.eps, "NUFFT direct IDFT (1) vs. NumPy IFFT: error too large") self.assertTrue(_error(self.c_numpy.reshape(-1), c_nufft.reshape(-1)) < self.eps, "NUFFT IFFT (1) vs. NumPy IFFT: error too large")
def test_type1_idft(self): """Is the NUFFT type 1 IDFT correct?""" c_dir = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.f_numpy.reshape(-1), self.N[0], self.N[1], iflag=1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) c_nufft = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.f_numpy.reshape(-1), self.N[0], self.N[1], iflag=1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue( _error(self.c_numpy.reshape(-1), c_dir.reshape(-1)) < self.eps, "NUFFT direct IDFT (1) vs. NumPy IFFT: error too large") self.assertTrue( _error(self.c_numpy.reshape(-1), c_nufft.reshape(-1)) < self.eps, "NUFFT IFFT (1) vs. NumPy IFFT: error too large")
def _type_1_odd(self, eps=1e-10): p2 = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0] + 1, self.N[1] + 1, direct=True) p1 = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0] + 1, self.N[1] + 1, eps=eps) self.assertTrue(_error(p1, p2) < eps, "Type 1: Discrepancy between direct and fft function")
def _type_1_odd(self, eps=1e-10): p2 = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0] + 1, self.N[1] + 1, direct=True) p1 = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0] + 1, self.N[1] + 1, eps=eps) self.assertTrue( _error(p1, p2) < eps, "Type 1: Discrepancy between direct and fft function")
def test_type1_irdft(self): """Is the NUFFT type 1 IRDFT correct?""" # Trick to make it think it is seeing a full FFT K = np.meshgrid(-self.kx, -self.ky[int(self.N[1] / 2) + 1:], indexing='ij') f = np.concatenate((self.fr_numpy, np.conj(self.fr_numpy[K[0], K[1]])), axis=1) c_dir = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), f.reshape(-1), self.N[0], self.N[1], iflag=1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) c_nufft = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), f.reshape(-1), self.N[0], self.N[1], iflag=1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue(_error(self.cr_numpy.reshape(-1), c_dir.reshape(-1)) < self.eps, "NUFFT direct IRDFT (1) vs. NumPy IRFFT: error too large") self.assertTrue(_error(self.cr_numpy.reshape(-1), c_nufft.reshape(-1)) < self.eps, "NUFFT IRFFT (1) vs. NumPy IRFFT: error too large")
def test_type1_irdft(self): """Is the NUFFT type 1 IRDFT correct?""" # Trick to make it think it is seeing a full FFT K = np.meshgrid(-self.kx, -self.ky[int(self.N[1] / 2) + 1:], indexing='ij') f = np.concatenate((self.fr_numpy, np.conj(self.fr_numpy[K[0], K[1]])), axis=1) c_dir = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), f.reshape(-1), self.N[0], self.N[1], iflag=1, direct=True), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) c_nufft = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), f.reshape(-1), self.N[0], self.N[1], iflag=1, direct=False), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue( _error(self.cr_numpy.reshape(-1), c_dir.reshape(-1)) < self.eps, "NUFFT direct IRDFT (1) vs. NumPy IRFFT: error too large") self.assertTrue( _error(self.cr_numpy.reshape(-1), c_nufft.reshape(-1)) < self.eps, "NUFFT IRFFT (1) vs. NumPy IRFFT: error too large")
def _type_1_2_roundtrip(self, eps=1e-10): p = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, eps=eps) c2 = nufft2d2(self.X[0].reshape(-1), self.X[1].reshape(-1), p, iflag=1, direct=True) self.assertTrue(_error(self.c.reshape(-1), c2) < eps, "Type 1 and 2: roundtrip error.")
def _type_1_2_roundtrip(self, eps=1e-10): p = nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], iflag=-1, eps=eps) c2 = nufft2d2(self.X[0].reshape(-1), self.X[1].reshape(-1), p, iflag=1, direct=True) self.assertTrue( _error(self.c.reshape(-1), c2) < eps, "Type 1 and 2: roundtrip error.")
def _type_1_and_3(self, eps=1e-10): p2 = nufft2d3(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.st_grid[0].reshape(-1), self.st_grid[1].reshape(-1), eps=eps) p1 = np.roll( np.roll( nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], eps=eps), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue( _error(p1.reshape(-1), p2) < eps, "Type 1 and 3 and not close")
def _type_1_and_3(self, eps=1e-10): p2 = nufft2d3(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.st_grid[0].reshape(-1), self.st_grid[1].reshape(-1), eps=eps) p1 = np.roll(np.roll(nufft2d1(self.X[0].reshape(-1), self.X[1].reshape(-1), self.c.reshape(-1), self.N[0], self.N[1], eps=eps), -int(self.N[0] / 2), 0), -int(self.N[1] / 2), 1) self.assertTrue(_error(p1.reshape(-1), p2) < eps, "Type 1 and 3 and not close")