def nufft2(field, fx, fy, size=None, sign=1, eps=10**(-12)): """ """ if np.__name__ == 'cupy': fx = np.asnumpy(fx).astype(np.float64) fy = np.asnumpy(fy).astype(np.float64) image = np.asnumpy(np.copy(field)).astype(np.complex128) else: image = np.copy(field).astype(np.complex128) if type(size) == type(None): result = finufft.nufft2d1(fx.flatten(), fy.flatten(), image.flatten(), image.shape, eps=eps, isign=sign) else: result = finufft.nufft2d1(fx.flatten(), fy.flatten(), image.flatten(), (size[0], size[1]), eps=eps, isign=sign) if np.__name__ == 'cupy': result = np.asarray(result) return result
def nuifft2(field, fx, fy, size=None, sign=1, eps=10**(-12)): """ A definition to take 2D Adjoint Non-Uniform Fast Fourier Transform (NUFFT). Parameters ---------- field : ndarray Input field. fx : ndarray Frequencies along x axis. fy : ndarray Frequencies along y axis. size : list or ndarray Shape of the NUFFT calculated for an input field. sign : float Sign of the exponential used in NUFFT kernel. eps : float Accuracy of NUFFT. Returns ---------- result : ndarray NUFFT of the input field. """ if np.__name__ == 'cupy': fx = np.asnumpy(fx).astype(np.float64) fy = np.asnumpy(fy).astype(np.float64) image = np.asnumpy(np.copy(field)).astype(np.complex128) else: image = np.copy(field).astype(np.complex128) if type(size) == type(None): result = finufft.nufft2d1(fx.flatten(), fy.flatten(), image.flatten(), image.shape, eps=eps, isign=sign) else: result = finufft.nufft2d1(fx.flatten(), fy.flatten(), image.flatten(), (size[0], size[1]), eps=eps, isign=sign) if np.__name__ == 'cupy': result = np.asarray(result) return result
def test_nufft2d1(seed=42, iflag=1): np.random.seed(seed) ms = 100 mt = 89 n = int(1e3) tol = 1.0e-9 x = np.random.uniform(-np.pi, np.pi, n) y = np.random.uniform(-np.pi, np.pi, n) c = np.random.uniform(-1.0, 1.0, n) + 1.0j * np.random.uniform(-1.0, 1.0, n) f = finufft.nufft2d1(x, y, c, ms, mt, eps=tol, iflag=iflag) f0 = interface.dirft2d1(x, y, c, ms, mt, iflag=iflag) assert np.all(np.abs((f - f0) / f0) < 1e-6)
def with_finufft(uvw, freq, ms, wgt, nxdirty, nydirty, xpixsize, ypixsize, mask, epsilon): u = np.outer(uvw[:, 0], freq) * (xpixsize / SPEEDOFLIGHT) * 2 * np.pi v = np.outer(uvw[:, 1], freq) * (ypixsize / SPEEDOFLIGHT) * 2 * np.pi if wgt is not None: ms = ms * wgt if mask is not None: ms = ms * mask eps = epsilon / 10 # Apparently finufft measures epsilon differently # Plan on the fly res0 = finufft.nufft2d1(u.ravel(), v.ravel(), ms.ravel(), (nxdirty, nydirty), eps=eps).real # Plan beforehand plan = finufft.Plan(1, (nxdirty, nydirty), eps=eps) plan.setpts(u.ravel(), v.ravel()) res1 = plan.execute(ms.ravel()).real np.testing.assert_allclose(res0, res1) return res0
# ahb updated for v2.0 interface, and complex c. Bug seems to have been fixed :) import numpy as np from finufft import nufft2d1 c = np.complex128(np.random.rand(2)) omega = np.arange(4).reshape((2, 2)) / 3 * np.pi x0 = omega[:, 0] y0 = omega[:, 1] f0 = np.zeros((4, 4), order='F', dtype=np.complex128) nufft2d1(x0, y0, c, f0.shape, out=f0, eps=1e-14) x1 = x0.copy() y1 = y0.copy() f1 = np.zeros((4, 4), order='F', dtype=np.complex128) nufft2d1(x1, y1, c, f1.shape, out=f1, eps=1e-14) print('difference: %e' % np.linalg.norm(f0 - f1))
def accuracy_speed_tests(num_nonuniform_points, num_uniform_points, eps): nj, nk = int(num_nonuniform_points), int(num_nonuniform_points) iflag = 1 num_samples = int( np.minimum(5, num_uniform_points * 0.5 + 1) ) # number of outputs used for estimating accuracy; is small for speed print( 'Accuracy and speed tests for %d nonuniform points and eps=%g (error estimates use %d samples per run)' % (num_nonuniform_points, eps, num_samples)) # for doing the error estimates Xest = np.zeros(num_samples, dtype=np.complex128) Xtrue = np.zeros(num_samples, dtype=np.complex128) ###### 1-d cases ........................................................ ms = int(num_uniform_points) xj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.random.rand(nj) + 1j * np.random.rand(nj) fk = np.zeros([ms], dtype=np.complex128) timer = time.time() ret = finufft.nufft1d1(xj, cj, ms, fk, eps, iflag) elapsed = time.time() - timer k = np.arange(-np.floor(ms / 2), np.floor((ms - 1) / 2 + 1)) for ii in np.arange(0, num_samples): Xest[ii] = np.sum(cj * np.exp(1j * k[ii] * xj)) Xtrue[ii] = fk[ii] print_report('finufft1d1', elapsed, Xest, Xtrue, nj) xj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.zeros([nj], dtype=np.complex128) fk = np.random.rand(ms) + 1j * np.random.rand(ms) timer = time.time() ret = finufft.nufft1d2(xj, fk, cj, eps, iflag) elapsed = time.time() - timer k = np.arange(-np.floor(ms / 2), np.floor((ms - 1) / 2 + 1)) for ii in np.arange(0, num_samples): Xest[ii] = np.sum(fk * np.exp(1j * k * xj[ii])) Xtrue[ii] = cj[ii] print_report('finufft1d2', elapsed, Xest, Xtrue, nj) x = np.random.rand(nj) * 2 * math.pi - math.pi c = np.random.rand(nj) + 1j * np.random.rand(nj) s = np.random.rand(nk) * 2 * math.pi - math.pi f = np.zeros([nk], dtype=np.complex128) timer = time.time() ret = finufft.nufft1d3(x, c, s, f, eps, iflag) elapsed = time.time() - timer for ii in np.arange(0, num_samples): Xest[ii] = np.sum(c * np.exp(1j * s[ii] * x)) Xtrue[ii] = f[ii] print_report('finufft1d3', elapsed, Xest, Xtrue, nj + nk) ###### 2-d cases .................................................... ms = int(np.ceil(np.sqrt(num_uniform_points))) mt = ms xj = np.random.rand(nj) * 2 * math.pi - math.pi yj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.random.rand(nj) + 1j * np.random.rand(nj) fk = np.zeros([ms, mt], dtype=np.complex128) timer = time.time() ret = finufft.nufft2d1(xj, yj, cj, (ms, mt), fk, eps, iflag) elapsed = time.time() - timer Ks, Kt = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1), -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1)] for ii in np.arange(0, num_samples): Xest[ii] = np.sum( cj * np.exp(1j * (Ks.ravel()[ii] * xj + Kt.ravel()[ii] * yj))) Xtrue[ii] = fk.ravel()[ii] print_report('finufft2d1', elapsed, Xest, Xtrue, nj) ## 2d1many: ndata = 8 # how many vectors to do cj = np.array(np.random.rand(ndata, nj) + 1j * np.random.rand(ndata, nj)) fk = np.zeros([ndata, ms, mt], dtype=np.complex128) timer = time.time() ret = finufft.nufft2d1(xj, yj, cj, ms, fk, eps, iflag) elapsed = time.time() - timer dtest = ndata - 1 # which of the ndata to test (in 0,..,ndata-1) for ii in np.arange(0, num_samples): Xest[ii] = np.sum( cj[dtest, :] * np.exp(1j * (Ks.ravel()[ii] * xj + Kt.ravel()[ii] * yj)) ) # note fortran-ravel-order needed throughout - mess. Xtrue[ii] = fk.ravel()[ ii + dtest * ms * mt] # hack the offset in fk array - has to be better way print_report('finufft2d1many', elapsed, Xest, Xtrue, ndata * nj) # 2d2 xj = np.random.rand(nj) * 2 * math.pi - math.pi yj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.zeros([nj], dtype=np.complex128) fk = np.random.rand(ms, mt) + 1j * np.random.rand(ms, mt) timer = time.time() ret = finufft.nufft2d2(xj, yj, fk, cj, eps, iflag) elapsed = time.time() - timer Ks, Kt = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1), -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1)] for ii in np.arange(0, num_samples): Xest[ii] = np.sum(fk * np.exp(1j * (Ks * xj[ii] + Kt * yj[ii]))) Xtrue[ii] = cj[ii] print_report('finufft2d2', elapsed, Xest, Xtrue, nj) # 2d2many (using same ndata and dtest as 2d1many; see above) cj = np.zeros([ndata, nj], dtype=np.complex128) fk = np.array( np.random.rand(ndata, ms, mt) + 1j * np.random.rand(ndata, ms, mt)) timer = time.time() ret = finufft.nufft2d2(xj, yj, fk, cj, eps, iflag) elapsed = time.time() - timer for ii in np.arange(0, num_samples): Xest[ii] = np.sum(fk[dtest, :, :] * np.exp(1j * (Ks * xj[ii] + Kt * yj[ii]))) Xtrue[ii] = cj[dtest, ii] print_report('finufft2d2many', elapsed, Xest, Xtrue, ndata * nj) # 2d3 x = np.random.rand(nj) * 2 * math.pi - math.pi y = np.random.rand(nj) * 2 * math.pi - math.pi c = np.random.rand(nj) + 1j * np.random.rand(nj) s = np.random.rand(nk) * 2 * math.pi - math.pi t = np.random.rand(nk) * 2 * math.pi - math.pi f = np.zeros([nk], dtype=np.complex128) timer = time.time() ret = finufft.nufft2d3(x, y, c, s, t, f, eps, iflag) elapsed = time.time() - timer for ii in np.arange(0, num_samples): Xest[ii] = np.sum(c * np.exp(1j * (s[ii] * x + t[ii] * y))) Xtrue[ii] = f[ii] print_report('finufft2d3', elapsed, Xest, Xtrue, nj + nk) ###### 3-d cases ............................................................ ms = int(np.ceil(num_uniform_points**(1.0 / 3))) mt = ms mu = ms xj = np.random.rand(nj) * 2 * math.pi - math.pi yj = np.random.rand(nj) * 2 * math.pi - math.pi zj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.random.rand(nj) + 1j * np.random.rand(nj) fk = np.zeros([ms, mt, mu], dtype=np.complex128) timer = time.time() ret = finufft.nufft3d1(xj, yj, zj, cj, fk.shape, fk, eps, iflag) elapsed = time.time() - timer Ks, Kt, Ku = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1), -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1), -np.floor(mu / 2):np.floor((mu - 1) / 2 + 1)] for ii in np.arange(0, num_samples): Xest[ii] = np.sum(cj * np.exp( 1j * (Ks.ravel()[ii] * xj + Kt.ravel()[ii] * yj + Ku.ravel()[ii] * zj))) Xtrue[ii] = fk.ravel()[ii] print_report('finufft3d1', elapsed, Xest, Xtrue, nj) xj = np.random.rand(nj) * 2 * math.pi - math.pi yj = np.random.rand(nj) * 2 * math.pi - math.pi zj = np.random.rand(nj) * 2 * math.pi - math.pi cj = np.zeros([nj], dtype=np.complex128) fk = np.random.rand(ms, mt, mu) + 1j * np.random.rand(ms, mt, mu) timer = time.time() ret = finufft.nufft3d2(xj, yj, zj, fk, cj, eps, iflag) elapsed = time.time() - timer Ks, Kt, Ku = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1), -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1), -np.floor(mu / 2):np.floor((mu - 1) / 2 + 1)] for ii in np.arange(0, num_samples): Xest[ii] = np.sum( fk * np.exp(1j * (Ks * xj[ii] + Kt * yj[ii] + Ku * zj[ii]))) Xtrue[ii] = cj[ii] print_report('finufft3d2', elapsed, Xest, Xtrue, nj) x = np.random.rand(nj) * 2 * math.pi - math.pi y = np.random.rand(nj) * 2 * math.pi - math.pi z = np.random.rand(nj) * 2 * math.pi - math.pi c = np.random.rand(nj) + 1j * np.random.rand(nj) s = np.random.rand(nk) * 2 * math.pi - math.pi t = np.random.rand(nk) * 2 * math.pi - math.pi u = np.random.rand(nk) * 2 * math.pi - math.pi f = np.zeros([nk], dtype=np.complex128) timer = time.time() ret = finufft.nufft3d3(x, y, z, c, s, t, u, f, eps, iflag) elapsed = time.time() - timer for ii in np.arange(0, num_samples): Xest[ii] = np.sum(c * np.exp(1j * (s[ii] * x + t[ii] * y + u[ii] * z))) Xtrue[ii] = f[ii] print_report('finufft3d3', elapsed, Xest, Xtrue, nj + nk)
import time np.random.seed(42) # number of nonuniform points M = 100000 # the nonuniform points in the square [0,2pi)^2 x = 2 * np.pi * np.random.uniform(size=M) y = 2 * np.pi * np.random.uniform(size=M) # their complex strengths c = (np.random.standard_normal(size=M) + 1J * np.random.standard_normal(size=M)) # desired number of Fourier modes (in x,y directions respectively) N1 = 1000 N2 = 2000 # calculate the transform t0 = time.time() f = finufft.nufft2d1(x, y, c, (N1, N2), eps=1e-9) print("finufft2d1 done in {0:.2g} s.".format(time.time() - t0)) k1 = 376 # do a math check, for a single output mode index (k1,k2) k2 = -1000 assert ((k1 >= -N1 / 2.) & (k1 < N1 / 2.)) # float division easier here assert ((k2 >= -N2 / 2.) & (k2 < N2 / 2.)) ftest = sum(c * np.exp(1.j * (k1 * x + k2 * y))) err = np.abs(f[k1 + N1 // 2, k2 + N2 // 2] - ftest) / np.max(np.abs(f)) print("Error relative to max: {0:.2e}".format(err))
import numpy as np from finufft import nufft2d1 c = np.arange(2) omega = np.arange(4).reshape((2, 2)) / 3 * np.pi x0 = omega[:, 0] y0 = omega[:, 1] f0 = np.zeros((4, 4), order='F', dtype=np.complex128) nufft2d1(x0, y0, c, 1, 1e-15, f0.shape[0], f0.shape[1], f0) x1 = x0.copy() y1 = y0.copy() f1 = np.zeros((4, 4), order='F', dtype=np.complex128) nufft2d1(x1, y1, c, 1, 1e-15, f1.shape[0], f1.shape[1], f1) print('difference: %e' % np.linalg.norm(f0 - f1))