示例#1
0
 def test_shape_argument(self):
     small_x = [[1, 2, 3], [4, 5, 6]]
     large_x1 = [[1, 2, 3, 0], [4, 5, 6, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
     y = fftn(small_x, shape=(4, 4))
     assert_array_almost_equal(y, fftn(large_x1))
     y = fftn(small_x, shape=(3, 4))
     assert_array_almost_equal(y, fftn(large_x1[:-1]))
示例#2
0
 def test_definition(self):
     x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
     y = fftn(x)
     assert_array_almost_equal(y, direct_dftn(x))
     x = random((20, 26))
     assert_array_almost_equal(fftn(x), direct_dftn(x))
     x = random((5, 4, 3, 20))
     assert_array_almost_equal(fftn(x), direct_dftn(x))
示例#3
0
    def test_definition(self):
        x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        y = fftn(np.array(x, np.float32))
        if not y.dtype == np.complex64:
            raise ValueError("double precision output with single precision")

        y_r = np.array(fftn(x), np.complex64)
        assert_array_almost_equal_nulp(y, y_r)
示例#4
0
    def test_shape_axes_argument2(self):
        # Change shape of the last axis
        x = numpy.random.random((10, 5, 3, 7))
        y = fftn(x, axes=(-1, ), shape=(8, ))
        assert_array_almost_equal(y, fft(x, axis=-1, n=8))

        # Change shape of an arbitrary axis which is not the last one
        x = numpy.random.random((10, 5, 3, 7))
        y = fftn(x, axes=(-2, ), shape=(8, ))
        assert_array_almost_equal(y, fft(x, axis=-2, n=8))

        # Change shape of axes: cf #244, where shape and axes were mixed up
        x = numpy.random.random((4, 4, 2))
        y = fftn(x, axes=(-3, -2), shape=(8, 8))
        assert_array_almost_equal(y, numpy.fft.fftn(x, axes=(-3, -2),
                                                    s=(8, 8)))
示例#5
0
 def test_shape_axes_argument(self):
     small_x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
     large_x1 = array([[1, 2, 3, 0], [4, 5, 6, 0], [7, 8, 9, 0],
                       [0, 0, 0, 0]])
     # Disable tests with shape and axes of different lengths
     # y = fftn(small_x,shape=(4,4),axes=(-1,))
     # for i in range(4):
     #    assert_array_almost_equal (y[i],fft(large_x1[i]))
     # y = fftn(small_x,shape=(4,4),axes=(-2,))
     # for i in range(4):
     #    assert_array_almost_equal (y[:,i],fft(large_x1[:,i]))
     y = fftn(small_x, shape=(4, 4), axes=(-2, -1))
     assert_array_almost_equal(y, fftn(large_x1))
     y = fftn(small_x, shape=(4, 4), axes=(-1, -2))
     assert_array_almost_equal(
         y, swapaxes(fftn(swapaxes(large_x1, -1, -2)), -1, -2))
示例#6
0
    def test_float16_input(self):
        for size in SMALL_COMPOSITE_SIZES + SMALL_PRIME_SIZES:
            np.random.seed(1234)
            x = np.random.rand(size, size) + 1j * np.random.rand(size, size)
            y1 = fftn(x.real.astype(np.float16))
            y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)

            assert_equal(y1.dtype, np.complex64)
            assert_array_almost_equal_nulp(y1, y2, 5e5)

        for size in LARGE_COMPOSITE_SIZES + LARGE_PRIME_SIZES:
            np.random.seed(1234)
            x = np.random.rand(size, 3) + 1j * np.random.rand(size, 3)
            y1 = fftn(x.real.astype(np.float16))
            y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)

            assert_equal(y1.dtype, np.complex64)
            assert_array_almost_equal_nulp(y1, y2, 2e6)
示例#7
0
def fftconvolve(in1, in2, mode="full"):
    """Convolve two N-dimensional arrays using FFT.

    Convolve `in1` and `in2` using the fast Fourier transform method, with
    the output size determined by the `mode` argument.

    This is generally much faster than `convolve` for large arrays (n > ~500),
    but can be slower when only a few output values are needed, and can only
    output float arrays (int or object array inputs will be cast to float).

    As of v0.19, `convolve` automatically chooses this method or the direct
    method based on an estimation of which is faster.

    Parameters
    ----------
    in1 : array_like
        First input.
    in2 : array_like
        Second input. Should have the same number of dimensions as `in1`.
        If operating in 'valid' mode, either `in1` or `in2` must be
        at least as large as the other in every dimension.
    mode : str {'full', 'valid', 'same'}, optional
        A string indicating the size of the output:

        ``full``
           The output is the full discrete linear convolution
           of the inputs. (Default)
        ``valid``
           The output consists only of those elements that do not
           rely on the zero-padding.
        ``same``
           The output is the same size as `in1`, centered
           with respect to the 'full' output.

    Returns
    -------
    out : array
        An N-dimensional array containing a subset of the discrete linear
        convolution of `in1` with `in2`.

    Examples
    --------
    Autocorrelation of white noise is an impulse.

    >>> from scipy import signal
    >>> sig = np.random.randn(1000)
    >>> autocorr = signal.fftconvolve(sig, sig[::-1], mode='full')

    >>> import matplotlib.pyplot as plt
    >>> fig, (ax_orig, ax_mag) = plt.subplots(2, 1)
    >>> ax_orig.plot(sig)
    >>> ax_orig.set_title('White noise')
    >>> ax_mag.plot(np.arange(-len(sig)+1,len(sig)), autocorr)
    >>> ax_mag.set_title('Autocorrelation')
    >>> fig.tight_layout()
    >>> fig.show()

    Gaussian blur implemented using FFT convolution.  Notice the dark borders
    around the image, due to the zero-padding beyond its boundaries.
    The `convolve2d` function allows for other types of image boundaries,
    but is far slower.

    >>> from scipy import misc
    >>> face = misc.face(gray=True)
    >>> kernel = np.outer(signal.gaussian(70, 8), signal.gaussian(70, 8))
    >>> blurred = signal.fftconvolve(face, kernel, mode='same')

    >>> fig, (ax_orig, ax_kernel, ax_blurred) = plt.subplots(3, 1,
    ...                                                      figsize=(6, 15))
    >>> ax_orig.imshow(face, cmap='gray')
    >>> ax_orig.set_title('Original')
    >>> ax_orig.set_axis_off()
    >>> ax_kernel.imshow(kernel, cmap='gray')
    >>> ax_kernel.set_title('Gaussian kernel')
    >>> ax_kernel.set_axis_off()
    >>> ax_blurred.imshow(blurred, cmap='gray')
    >>> ax_blurred.set_title('Blurred')
    >>> ax_blurred.set_axis_off()
    >>> fig.show()

    """
    in1 = asarray(in1)
    in2 = asarray(in2)

    if in1.ndim == in2.ndim == 0:  # scalar inputs
        return in1 * in2
    elif not in1.ndim == in2.ndim:
        raise ValueError("in1 and in2 should have the same dimensionality")
    elif in1.size == 0 or in2.size == 0:  # empty arrays
        return array([])

    s1 = array(in1.shape)
    s2 = array(in2.shape)
    complex_result = (np.issubdtype(in1.dtype, np.complexfloating)
                      or np.issubdtype(in2.dtype, np.complexfloating))
    shape = s1 + s2 - 1

    # Check that input sizes are compatible with 'valid' mode
    if _inputs_swap_needed(mode, s1, s2):
        # Convolution is commutative; order doesn't have any effect on output
        in1, s1, in2, s2 = in2, s2, in1, s1

    # Speed up FFT by padding to optimal size for FFTPACK
    fshape = [fftpack.helper.next_fast_len(int(d)) for d in shape]
    fslice = tuple([slice(0, int(sz)) for sz in shape])
    # Pre-1.9 NumPy FFT routines are not threadsafe.  For older NumPys, make
    # sure we only call rfftn/irfftn from one thread at a time.
    if not complex_result and (_rfft_mt_safe or _rfft_lock.acquire(False)):
        try:
            sp1 = np.fft.rfftn(in1, fshape)
            sp2 = np.fft.rfftn(in2, fshape)
            ret = (np.fft.irfftn(sp1 * sp2, fshape)[fslice].copy())
        finally:
            if not _rfft_mt_safe:
                _rfft_lock.release()
    else:
        # If we're here, it's either because we need a complex result, or we
        # failed to acquire _rfft_lock (meaning rfftn isn't threadsafe and
        # is already in use by another thread).  In either case, use the
        # (threadsafe but slower) SciPy complex-FFT routines instead.
        sp1 = fftpack.fftn(in1, fshape)
        sp2 = fftpack.fftn(in2, fshape)
        ret = fftpack.ifftn(sp1 * sp2)[fslice].copy()
        if not complex_result:
            ret = ret.real

    if mode == "full":
        return ret
    elif mode == "same":
        return _centered(ret, s1)
    elif mode == "valid":
        return _centered(ret, s1 - s2 + 1)
    else:
        raise ValueError("Acceptable mode flags are 'valid',"
                         " 'same', or 'full'.")
示例#8
0
 def test_random_complex(self):
     for size in [1, 2, 51, 32, 64, 92]:
         x = random([size, size]) + 1j * random([size, size])
         assert_array_almost_equal_nulp(ifftn(fftn(x)), x, self.maxnlp)
         assert_array_almost_equal_nulp(fftn(ifftn(x)), x, self.maxnlp)
示例#9
0
    def test_axes_argument(self):
        # plane == ji_plane, x== kji_space
        plane1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        plane2 = [[10, 11, 12], [13, 14, 15], [16, 17, 18]]
        plane3 = [[19, 20, 21], [22, 23, 24], [25, 26, 27]]
        ki_plane1 = [[1, 2, 3], [10, 11, 12], [19, 20, 21]]
        ki_plane2 = [[4, 5, 6], [13, 14, 15], [22, 23, 24]]
        ki_plane3 = [[7, 8, 9], [16, 17, 18], [25, 26, 27]]
        jk_plane1 = [[1, 10, 19], [4, 13, 22], [7, 16, 25]]
        jk_plane2 = [[2, 11, 20], [5, 14, 23], [8, 17, 26]]
        jk_plane3 = [[3, 12, 21], [6, 15, 24], [9, 18, 27]]
        kj_plane1 = [[1, 4, 7], [10, 13, 16], [19, 22, 25]]
        kj_plane2 = [[2, 5, 8], [11, 14, 17], [20, 23, 26]]
        kj_plane3 = [[3, 6, 9], [12, 15, 18], [21, 24, 27]]
        ij_plane1 = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
        ij_plane2 = [[10, 13, 16], [11, 14, 17], [12, 15, 18]]
        ij_plane3 = [[19, 22, 25], [20, 23, 26], [21, 24, 27]]
        ik_plane1 = [[1, 10, 19], [2, 11, 20], [3, 12, 21]]
        ik_plane2 = [[4, 13, 22], [5, 14, 23], [6, 15, 24]]
        ik_plane3 = [[7, 16, 25], [8, 17, 26], [9, 18, 27]]
        ijk_space = [jk_plane1, jk_plane2, jk_plane3]
        ikj_space = [kj_plane1, kj_plane2, kj_plane3]
        jik_space = [ik_plane1, ik_plane2, ik_plane3]
        jki_space = [ki_plane1, ki_plane2, ki_plane3]
        kij_space = [ij_plane1, ij_plane2, ij_plane3]
        x = array([plane1, plane2, plane3])

        assert_array_almost_equal(fftn(x),
                                  fftn(x, axes=(-3, -2, -1)))  # kji_space
        assert_array_almost_equal(fftn(x), fftn(x, axes=(0, 1, 2)))
        assert_array_almost_equal(fftn(x, axes=(0, 2)), fftn(x, axes=(0, -1)))
        y = fftn(x, axes=(2, 1, 0))  # ijk_space
        assert_array_almost_equal(swapaxes(y, -1, -3), fftn(ijk_space))
        y = fftn(x, axes=(2, 0, 1))  # ikj_space
        assert_array_almost_equal(swapaxes(swapaxes(y, -1, -3), -1, -2),
                                  fftn(ikj_space))
        y = fftn(x, axes=(1, 2, 0))  # jik_space
        assert_array_almost_equal(swapaxes(swapaxes(y, -1, -3), -3, -2),
                                  fftn(jik_space))
        y = fftn(x, axes=(1, 0, 2))  # jki_space
        assert_array_almost_equal(swapaxes(y, -2, -3), fftn(jki_space))
        y = fftn(x, axes=(0, 2, 1))  # kij_space
        assert_array_almost_equal(swapaxes(y, -2, -1), fftn(kij_space))

        y = fftn(x, axes=(-2, -1))  # ji_plane
        assert_array_almost_equal(fftn(plane1), y[0])
        assert_array_almost_equal(fftn(plane2), y[1])
        assert_array_almost_equal(fftn(plane3), y[2])
        y = fftn(x, axes=(1, 2))  # ji_plane
        assert_array_almost_equal(fftn(plane1), y[0])
        assert_array_almost_equal(fftn(plane2), y[1])
        assert_array_almost_equal(fftn(plane3), y[2])
        y = fftn(x, axes=(-3, -2))  # kj_plane
        assert_array_almost_equal(fftn(x[:, :, 0]), y[:, :, 0])
        assert_array_almost_equal(fftn(x[:, :, 1]), y[:, :, 1])
        assert_array_almost_equal(fftn(x[:, :, 2]), y[:, :, 2])
        y = fftn(x, axes=(-3, -1))  # ki_plane
        assert_array_almost_equal(fftn(x[:, 0, :]), y[:, 0, :])
        assert_array_almost_equal(fftn(x[:, 1, :]), y[:, 1, :])
        assert_array_almost_equal(fftn(x[:, 2, :]), y[:, 2, :])
        y = fftn(x, axes=(-1, -2))  # ij_plane
        assert_array_almost_equal(fftn(ij_plane1), swapaxes(y[0], -2, -1))
        assert_array_almost_equal(fftn(ij_plane2), swapaxes(y[1], -2, -1))
        assert_array_almost_equal(fftn(ij_plane3), swapaxes(y[2], -2, -1))
        y = fftn(x, axes=(-1, -3))  # ik_plane
        assert_array_almost_equal(fftn(ik_plane1),
                                  swapaxes(y[:, 0, :], -1, -2))
        assert_array_almost_equal(fftn(ik_plane2),
                                  swapaxes(y[:, 1, :], -1, -2))
        assert_array_almost_equal(fftn(ik_plane3),
                                  swapaxes(y[:, 2, :], -1, -2))
        y = fftn(x, axes=(-2, -3))  # jk_plane
        assert_array_almost_equal(fftn(jk_plane1),
                                  swapaxes(y[:, :, 0], -1, -2))
        assert_array_almost_equal(fftn(jk_plane2),
                                  swapaxes(y[:, :, 1], -1, -2))
        assert_array_almost_equal(fftn(jk_plane3),
                                  swapaxes(y[:, :, 2], -1, -2))

        y = fftn(x, axes=(-1, ))  # i_line
        for i in range(3):
            for j in range(3):
                assert_array_almost_equal(fft(x[i, j, :]), y[i, j, :])
        y = fftn(x, axes=(-2, ))  # j_line
        for i in range(3):
            for j in range(3):
                assert_array_almost_equal(fft(x[i, :, j]), y[i, :, j])
        y = fftn(x, axes=(0, ))  # k_line
        for i in range(3):
            for j in range(3):
                assert_array_almost_equal(fft(x[:, i, j]), y[:, i, j])

        y = fftn(x, axes=())  # point
        assert_array_almost_equal(y, x)
示例#10
0
 def test_definition_float16(self):
     x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
     y = fftn(np.array(x, np.float16))
     assert_equal(y.dtype, np.complex64)
     y_r = np.array(fftn(x), np.complex64)
     assert_array_almost_equal_nulp(y, y_r)