Example #1
0
    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
Example #2
0
    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