def convolve(self, u, v, uv=None, fast=True): """Convolution of u and v. Parameters ---------- u : array v : array uv : array, optional fast : bool, optional Whether to use fast transforms in computing convolution Note ---- Note that this method is only valid for 1D data, and that for multidimensional arrays one should use corresponding method in the TensorProductSpace class. """ assert len(u.shape) == 1 N = self.N if fast: if uv is None: uv = self.forward.output_array.copy() assert self.padding_factor > 1.0, "padding factor must be > 3/2+1/N to perform convolution without aliasing" u2 = self.backward.output_array.copy() u3 = self.backward.output_array.copy() u2 = self.backward(u, u2) u3 = self.backward(v, u3) uv = self.forward(u2 * u3, uv) else: if uv is None: uv = np.zeros(2 * N, dtype=u.dtype) Np = N if not N % 2 == 0 else N + 1 k = np.fft.fftfreq(Np, 1. / Np).astype(int) convolve.convolve_1D(u, v, uv, k) return uv
def convolve(self, u, v, uv=None, fast=True): """Convolution of u and v. Parameters ---------- u : array v : array uv : array, optional fast : bool, optional Whether to use fast transforms in computing convolution Note ---- Note that this method is only valid for 1D data, and that for multidimensional arrays one should use corresponding method in the TensorProductSpace class. """ assert len(u.shape) == 1 N = self.N if fast: if uv is None: uv = self.forward.output_array.copy() assert self.padding_factor > 1.0, "padding factor must be > 3/2+1/N to perform convolution without aliasing" u2 = self.backward.output_array.copy() u3 = self.backward.output_array.copy() u2 = self.backward(u, u2) u3 = self.backward(v, u3) uv = self.forward(u2*u3, uv) else: if uv is None: uv = np.zeros(2*N, dtype=u.dtype) Np = N if not N % 2 == 0 else N+1 k = np.fft.fftfreq(Np, 1./Np).astype(int) convolve.convolve_1D(u, v, uv, k) #if N % 2 == 0: #u = np.hstack((u[:N//2], u[N//2], u[N//2:])) #u[N//2:N//2+2] *= 0.5 #v = np.hstack((v[:N//2], v[N//2], v[N//2:])) #v[N//2:N//2+2] *= 0.5 #for m in range(Np): #vc = np.roll(v, -(m+1)) #s = u*vc[::-1] #ki = k + np.roll(k, -(m+1))[::-1] #z0 = np.argwhere(ki == m) #z1 = np.argwhere(ki == m-Np) #uv[m] = np.sum(s[z0]) #uv[m-Np] = np.sum(s[z1]) #for m in k: #for n in k: #p = m + n #if N % 2 == 0: #if abs(m) == N//2: #um = u[m]*0.5 #else: #um = u[m] #if abs(n) == N//2: #vn = v[n]*0.5 #else: #vn = v[n] #else: #um = u[m] #vn = v[n] #uv[p] += um*vn return uv