Esempio n. 1
0
 def interpolate_to_points(self, ff, x, y, fix_r=False):
     key = self.get_interpolation_key(x, y, fix_r)
     p = self.registered_partitions[key]
     # get the category numbers
     c1n, c2n, c3n = p.get_Ns()
     # initialize output vector
     output = np.empty(x.size)
     # interpolate appropriate portion with grid (polynomial, for now...)
     if c1n > 0:
         zone1 = p.zone1
         funch = np.fft.fft2(ff.get_smoothed_grid_value())
         out = np.zeros(p.zone1_N, dtype=complex)
         diagnostic = finufft.nufft2d2(p.x_transf, p.y_transf, funch, out, isign=1, eps=1e-14, modeord=1)
         out.real/np.prod(funch.shape)
         output[zone1] = out.real/np.prod(funch.shape)
     if c2n > 0:
         for ind in range(self.N):
             ebdy = self[ind]
             z2l = p.zone2l[ind]
             z2transfr = p.zone2_transfr[ind]
             z2t = p.zone2t[ind]
             fr = ff[ind]
             output[z2l] = ebdy.interpolate_radial_to_points(fr, z2transfr, z2t)
     # fill in those that are exterior with nan
     if c3n > 0:
         for z3 in p.zone3l:
             output[z3] = np.nan
     return output
Esempio n. 2
0
 def interpolate_to_points(self, ff, x, y, fix_r=False, dzl=None, gil=None):
     key = self.get_interpolation_key(x, y, fix_r, dzl, gil)
     p = self.registered_partitions[key]
     # get the category numbers
     c1n, c2n, c3n = p.get_Ns()
     # initialize output vector
     output = np.empty(x.size)
     # interpolate appropriate portion with grid (polynomial, for now...)
     if c1n > 0:
         if False:
             zone1 = p.zone1
             f = ff.get_grid_value()
             grid = self.grid
             lbds = [self.grid.x_bounds[0], self.grid.y_bounds[0]]
             ubds = [self.grid.x_bounds[1], self.grid.y_bounds[1]]
             hs = [self.grid.xh, self.grid.yh]
             interp = fast_interp.interp2d(lbds,
                                           ubds,
                                           hs,
                                           f,
                                           k=7,
                                           p=[True, True])
             output[zone1] = interp(x[zone1], y[zone1])
         else:
             # HERE
             zone1 = p.zone1
             funch = np.fft.fft2(ff.get_smoothed_grid_value())
             out = np.zeros(p.zone1_N, dtype=complex)
             if old_nufft:
                 diagnostic = finufftpy.nufft2d2(p.x_transf,
                                                 p.y_transf,
                                                 out,
                                                 1,
                                                 1e-14,
                                                 funch,
                                                 modeord=1)
             else:
                 diagnostic = finufft.nufft2d2(p.x_transf,
                                               p.y_transf,
                                               funch,
                                               out,
                                               isign=1,
                                               eps=1e-14,
                                               modeord=1)
             out.real / np.prod(funch.shape)
             output[zone1] = out.real / np.prod(funch.shape)
     if c2n > 0:
         for ind in range(self.N):
             ebdy = self[ind]
             z2l = p.zone2l[ind]
             z2transfr = p.zone2_transfr[ind]
             z2t = p.zone2t[ind]
             fr = ff[ind]
             output[z2l] = ebdy.interpolate_radial_to_points(
                 fr, z2transfr, z2t)
     # fill in those that are exterior with nan
     if c3n > 0:
         for z3 in p.zone3l:
             output[z3] = np.nan
     return output
Esempio n. 3
0
 def interpolate_radial_to_points(self, fr, transf_r, t):
     """
     Interpolate the radial function fr defined on this annulus to points
     with coordinates (r, t) given by transf_r, t
     """
     self.interpolation_hold[:self.M, :] = fr
     self.interpolation_hold[self.M:, :] = fr[::-1]
     funch = np.fft.fft2(
         self.interpolation_hold) * self.interpolation_modifier
     funch[self.M] = 0.0
     out = np.empty(t.size, dtype=complex)
     if old_nufft:
         diagnostic = finufftpy.nufft2d2(transf_r,
                                         t,
                                         out,
                                         1,
                                         1e-14,
                                         funch,
                                         modeord=1)
     else:
         diagnostic = finufft.nufft2d2(transf_r,
                                       t,
                                       funch,
                                       out,
                                       isign=1,
                                       eps=1e-14,
                                       modeord=1)
     vals = out.real / np.prod(funch.shape)
     return vals
Esempio n. 4
0
 def nufft_interpolate_grid_to_interface(self, f):
     """
     Call through interpolate_grid_to_interface
     """
     funch = np.fft.fft2(f)
     out = np.zeros(self.interfaces_x_transf.size, dtype=complex)
     diagnostic = finufft.nufft2d2(self.interfaces_x_transf, self.interfaces_y_transf, funch, out, isign=1, eps=1e-14, modeord=1)
     return out.real/np.prod(funch.shape)
Esempio n. 5
0
def test_nufft2d2(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)

    c = finufft.nufft2d2(x, y, f, eps=tol, iflag=iflag)
    c0 = interface.dirft2d2(x, y, f, iflag=iflag)
    assert np.all(np.abs((c - c0) / c0) < 1e-6)
Esempio n. 6
0
def nuifft2(field, fx, fy, 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)
    result = finufft.nufft2d2(fx.flatten(),
                              fy.flatten(),
                              image,
                              eps=eps,
                              isign=sign)
    result = result.reshape(field.shape)
    if np.__name__ == 'cupy':
        result = np.asarray(result)
    return result
Esempio n. 7
0
    def interpolate_radial_to_points(self, fr, transf_r, t):
        """
        Interpolate the radial function fr defined on this annulus to points
        with coordinates (r, t) given by transf_r, t
        """

        # should i define a 2D NUFFT Interpolater using the plan functions?
        # this might be useful if this is interpolated over and over again...
        # will think about

        self.interpolation_hold[:self.M,:] = fr
        self.interpolation_hold[self.M:,:] = fr[::-1]
        funch = np.fft.fft2(self.interpolation_hold)*self.interpolation_modifier
        funch[self.M] = 0.0
        out = np.empty(t.size, dtype=complex)
        diagnostic = finufft.nufft2d2(transf_r, t, funch, out, isign=1, eps=1e-14, modeord=1)
        vals = out.real/np.prod(funch.shape)
        return vals
Esempio n. 8
0
def nufft2(field, fx, fy, size=None, sign=1, eps=10**(-12)):
    """
    A definition to take 2D 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
                  Size.
    sign        : float
                  Sign of the exponential used in NUFFT kernel.
    eps         : float
                  Accuracy of NUFFT.

    Returns
    ----------
    result      : ndarray
                  Inverse 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)
    result = finufft.nufft2d2(fx.flatten(),
                              fy.flatten(),
                              image,
                              eps=eps,
                              isign=sign)
    if type(size) == type(None):
        result = result.reshape(field.shape)
    else:
        result = result.reshape(size)
    if np.__name__ == 'cupy':
        result = np.asarray(result)
    return result
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)
Esempio n. 10
0
 def __init__(self,
              gf,
              fs,
              ifs,
              h,
              spread_width,
              kernel_kwargs=None,
              funcgen_tol=1e-10,
              inline_core=True):
     """
     Backend class for re-usable 'ewald' sum grid evaluation
         for reusability, the grid must have the same h
         and the ewald sum must use the same spread width
     gf: numba callable greens function, gf(r)
     fs: Fourier symbol for operator, fs(kx, ky)
     ifs: Inverse Fourier symbol for operator, ifs(kx, ky)
     h: grid spacing
     spread_width: width to do spreading on
         for Laplace, 15 gives ~7 digits
                      20 gives ~10 digits
             can't seem to do much better than that, right now
     kernel_kwargs: dict of arguments to be passed to gf, fs, ifs, tsgf functions
     funcgen_tol: tolerance for function generator representation of
         functions used in interior spread funciton.  can't seem to beat
         ~10 digits overall now, so no real reason to do more than that
     inline_core: whether to inline the function generator functions into
         the compiled ewald functions
         (inlining may speed things up but slows compilation time,
         sometimes dramatically)
     """
     self.kernel_kwargs = {} if kernel_kwargs is None else kernel_kwargs
     self.gf = lambda r: gf(r, **self.kernel_kwargs)
     self.fourier_symbol = lambda kx, ky: fs(kx, ky, **self.kernel_kwargs)
     self.inverse_fourier_symbol = lambda kx, ky: ifs(
         kx, ky, **self.kernel_kwargs)
     self.h = h
     self.spread_width = spread_width
     self.funcgen_tol = funcgen_tol
     self.inline_core = inline_core
     # construct mollifier
     self.mollifier = SlepianMollifier(2 * self.spread_width)
     self.ssw = self.spread_width * self.h
     # screened greens function
     _excisor_gf = lambda d: excisor(d, 0.0, self.ssw, self.mollifier
                                     ) * self.gf(d)
     try:
         self.ex_funcgen = FunctionGenerator(_excisor_gf,
                                             0.0,
                                             self.ssw,
                                             tol=self.funcgen_tol,
                                             inline_core=self.inline_core)
         self.excisor_gf = self.ex_funcgen.get_base_function(check=False)
     except:
         raise Exception(
             'Failed constructing FunctionGenerator function for mollifier')
     # construct differential operator applied to residual of screened greens function
     _sn = 4 * self.spread_width
     _sgv = np.linspace(0, 4 * self.ssw, _sn, endpoint=False)
     _sgx, _sgy = np.meshgrid(_sgv, _sgv, indexing='ij')
     _skv = np.fft.fftfreq(_sn, self.h / (2 * np.pi))
     _skx, _sky = np.meshgrid(_skv, _skv, indexing='ij')
     _slap = self.fourier_symbol(_skx, _sky)
     pt = np.array([[2 * self.ssw], [2 * self.ssw]])
     targ = np.row_stack([_sgx.ravel(), _sgy.ravel()])
     u = gf_apply(self.gf, pt[0], pt[1], targ[0], targ[1], np.array([
         1.0,
     ])).reshape(_sn, _sn)
     u[_sn // 2, _sn // 2] = 0.0
     dist = np.hypot(_sgx - 2 * self.ssw, _sgy - 2 * self.ssw)
     dec1 = excisor(dist, 0.0, self.ssw, self.mollifier)
     dec2 = excisor(dist, self.ssw, 2 * self.ssw, self.mollifier)
     uf = u * (1 - dec1) * dec2
     self.do_ufd = ifft2(fft2(uf) * _slap).real
     # get an interpolater for this
     _ax = np.linspace(np.pi, 1.5 * np.pi, 1000)
     _ay = np.repeat(np.pi, _ax.size)
     _ar = np.linspace(0, self.ssw, _ax.size)
     _fh = fft2(self.do_ufd) / (_sn * _sn)
     out = finufft.nufft2d2(_ax, _ay, _fh, isign=1, eps=1e-15, modeord=1)
     self._do_ufd_interpolater = sp.interpolate.InterpolatedUnivariateSpline(
         _ar, out.real, k=5, bbox=[0, self.ssw], ext=1)
     try:
         self.do_ufd_funcgen = FunctionGenerator(
             self._do_ufd_interpolater,
             0.0,
             self.ssw,
             tol=self.funcgen_tol,
             inline_core=self.inline_core)
         self.do_ufd_interpolater = self.do_ufd_funcgen.get_base_function(
             check=False)
     except:
         raise Exception(
             'Failed constructing FunctionGenerator function for laplacian of greens function times mollifier'
         )