Exemplo n.º 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 :class:`.TensorProductSpace` class.

        """
        N = self.N

        if fast is True:
            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(N + 1, dtype=u.dtype)
            Np = N if not N % 2 == 0 else N + 1
            k1 = np.fft.fftfreq(Np, 1. / Np).astype(int)
            convolve.convolve_real_1D(u, v, uv, k1)

        return uv
Exemplo n.º 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 :class:`.TensorProductSpace` class.

        """
        N = self.N

        if fast is True:
            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(N+1, dtype=u.dtype)
            Np = N if not N % 2 == 0 else N+1
            k1 = np.fft.fftfreq(Np, 1./Np).astype(int)
            convolve.convolve_real_1D(u, v, uv, k1)

            #u1 = np.hstack((u, np.conj(u[1:][::-1])))
            #if N % 2 == 0:
                #u1[N//2:N//2+2] *= 0.5
            #v1 = np.hstack((v, np.conj(v[1:][::-1])))
            #if N % 2 == 0:
                #v1[N//2:N//2+2] *= 0.5

            #for m in range(N):
                #vc = np.roll(v1, -(m+1))
                #s = u1*vc[::-1]
                #ki = k1 + np.roll(k1, -(m+1))[::-1]
                #z0 = np.argwhere(ki == m)
                #z1 = np.argwhere(ki == m-N)
                #uv[m] = np.sum(s[z0])
                #uv[m-N] = np.sum(s[z1])

            #for m in k1:
                #for n in k1:
                    #p = m + n
                    #if p >= 0:
                        #if N % 2 == 0:
                            #if abs(m) == N//2:
                                #um = u[abs(m)]*0.5
                            #elif m >= 0:
                                #um = u[m]
                            #else:
                                #um = np.conj(u[abs(m)])
                            #if abs(n) == N//2:
                                #vn = v[abs(n)]*0.5
                            #elif n >= 0:
                                #vn = v[n]
                            #else:
                                #vn = np.conj(v[abs(n)])
                        #else:
                            #if m >= 0:
                                #um = u[m]
                            #elif m < 0:
                                #um = np.conj(u[abs(m)])
                            #if n >= 0:
                                #vn = v[n]
                            #elif n < 0:
                                #vn = np.conj(v[abs(n)])
                        #uv[p] += um*vn
        return uv