コード例 #1
0
    def test_flags(self):
        '''Test to see if the flags are correct
        '''
        fft = FFTW(self.input_array, self.output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE',))

        fft = FFTW(self.input_array, self.output_array,
                flags=('FFTW_DESTROY_INPUT', 'FFTW_UNALIGNED'))
        self.assertEqual(fft.flags, ('FFTW_DESTROY_INPUT', 'FFTW_UNALIGNED'))

        # Test an implicit flag
        _input_array = empty_aligned(256, dtype='complex64', n=16)
        _output_array = empty_aligned(256, dtype='complex64', n=16)

        # These are guaranteed to be misaligned (due to dtype size == 8)
        input_array = _input_array[:-1]
        output_array = _output_array[:-1]
        u_input_array = _input_array[1:]
        u_output_array = _output_array[1:]

        fft = FFTW(input_array, u_output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))

        fft = FFTW(u_input_array, output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))

        fft = FFTW(u_input_array, u_output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))
コード例 #2
0
    def create_test_arrays(self, input_shape, output_shape, axes=None):

        a = self.input_dtype(numpy.random.randn(*input_shape)
                +1j*numpy.random.randn(*input_shape))

        b = self.output_dtype(numpy.random.randn(*output_shape))

        # We fill a by doing the forward FFT from b.
        # This means that the relevant bits that should be purely
        # real will be (for example the zero freq component).
        # This is easier than writing a complicate system to work it out.
        try:
            if axes == None:
                fft = FFTW(b,a,direction='FFTW_FORWARD')
            else:
                fft = FFTW(b,a,direction='FFTW_FORWARD', axes=axes)

            b[:] = self.output_dtype(numpy.random.randn(*output_shape))

            fft.execute()

            scaling = numpy.prod(numpy.array(a.shape))
            a = self.input_dtype(a/scaling)

        except ValueError:
            # In this case, we assume that it was meant to error,
            # so we can return what we want.
            pass

        b = self.output_dtype(numpy.random.randn(*output_shape))

        return a, b
コード例 #3
0
    def test_planning_time_limit(self):
        in_shape = self.input_shapes['1d']
        out_shape = self.output_shapes['1d']

        axes = (0, )
        a, b = self.create_test_arrays(in_shape, out_shape)

        # run this a few times
        runs = 10
        t1 = time.time()
        for n in range(runs):
            forget_wisdom()
            fft = FFTW(a, b, axes=axes)

        unlimited_time = (time.time() - t1) / runs

        time_limit = (unlimited_time) / 8

        # Now do it again but with an upper limit on the time
        t1 = time.time()
        for n in range(runs):
            forget_wisdom()
            fft = FFTW(a, b, axes=axes, planning_timelimit=time_limit)

        limited_time = (time.time() - t1) / runs

        import sys
        if sys.platform == 'win32':
            # Give a 4x margin on windows. The timers are low
            # precision and FFTW seems to take longer anyway
            self.assertTrue(limited_time < time_limit * 4)
        else:
            # Otherwise have a 2x margin
            self.assertTrue(limited_time < time_limit * 2)
コード例 #4
0
    def test_call_with_normalisation_precision(self):
        '''The normalisation should use a double precision scaling.
        '''
        # Should be the case for double inputs...
        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)

        self.fft()
        ifft = FFTW(self.output_array, _input_array, direction='FFTW_BACKWARD')

        ref_output = ifft(normalise_idft=False).copy() / numpy.float64(ifft.N)
        test_output = ifft(normalise_idft=True).copy()

        self.assertTrue(numpy.alltrue(ref_output == test_output))

        # ... and single inputs.
        _input_array = empty_aligned((256, 512), dtype='complex64', n=16)

        ifft = FFTW(numpy.array(self.output_array, _input_array.dtype),
                    _input_array,
                    direction='FFTW_BACKWARD')

        ref_output = ifft(normalise_idft=False).copy() / numpy.float64(ifft.N)
        test_output = ifft(normalise_idft=True).copy()

        self.assertTrue(numpy.alltrue(ref_output == test_output))
コード例 #5
0
    def setUp(self):

        self.input_array = empty_aligned((256, 512), dtype='complex128', n=16)
        self.output_array = empty_aligned((256, 512), dtype='complex128', n=16)

        self.fft = FFTW(self.input_array, self.output_array)

        self.output_array[:] = (numpy.random.randn(*self.output_array.shape)
                + 1j*numpy.random.randn(*self.output_array.shape))
コード例 #6
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_unaligned(self):
        '''Make sure the right thing happens with unaligned data.
        '''
        input_array = (numpy.random.randn(*self.input_array.shape) +
                       1j * numpy.random.randn(*self.input_array.shape))

        output_array = self.fft(
            input_array=byte_align(input_array.copy(), n=16)).copy()

        input_array = byte_align(input_array, n=16)
        output_array = byte_align(output_array, n=16)

        # Offset by one from 16 byte aligned to guarantee it's not
        # 16 byte aligned
        a = byte_align(input_array.copy(), n=16)
        a__ = empty_aligned(numpy.prod(a.shape) * a.itemsize + 1,
                            dtype='int8',
                            n=16)

        a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
        a_[:] = a

        # Create a different second array the same way
        b = byte_align(output_array.copy(), n=16)
        b__ = empty_aligned(numpy.prod(b.shape) * a.itemsize + 1,
                            dtype='int8',
                            n=16)

        b_ = b__[1:].view(dtype=b.dtype).reshape(*b.shape)
        b_[:] = a

        # Set up for the first array
        fft = FFTW(input_array, output_array)
        a_[:] = a
        output_array = fft().copy()

        # Check a_ is not aligned...
        self.assertRaisesRegex(ValueError, 'Invalid input alignment',
                               self.fft.update_arrays, *(a_, output_array))

        # and b_ too
        self.assertRaisesRegex(ValueError, 'Invalid output alignment',
                               self.fft.update_arrays, *(input_array, b_))

        # But it should still work with the a_
        fft(a_)

        # However, trying to update the output will raise an error
        self.assertRaisesRegex(ValueError, 'Invalid output alignment',
                               self.fft.update_arrays, *(input_array, b_))

        # Same with SIMD off
        fft = FFTW(input_array, output_array, flags=('FFTW_UNALIGNED', ))
        fft(a_)
        self.assertRaisesRegex(ValueError, 'Invalid output alignment',
                               self.fft.update_arrays, *(input_array, b_))
コード例 #7
0
    def test_default_args(self):
        in_shape = self.input_shapes['2d']
        out_shape = self.output_shapes['2d']

        a, b = self.create_test_arrays(in_shape, out_shape)

        fft = FFTW(a, b)
        fft.execute()
        ref_b = self.reference_fftn(a, axes=(-1, ))
        self.assertTrue(numpy.allclose(b, ref_b, rtol=1e-2, atol=1e-3))
コード例 #8
0
    def test_aligned_flag(self):
        '''Test to see if the aligned flag is correct
        '''
        fft = FFTW(self.input_array, self.output_array)
        self.assertTrue(fft.simd_aligned)

        fft = FFTW(self.input_array, self.output_array,
                flags=('FFTW_UNALIGNED',))

        self.assertFalse(fft.simd_aligned)
コード例 #9
0
 def test_default_args(self):
     in_shape = self.input_shapes['2d']
     out_shape = self.output_shapes['2d']
     
     a, b = self.create_test_arrays(in_shape, out_shape)
     
     fft = FFTW(a,b)
     fft.execute()
     ref_b = self.reference_fftn(a, axes=(-1,))
     self.assertTrue(numpy.allclose(b, ref_b, rtol=1e-2, atol=1e-3))
コード例 #10
0
    def test_invalid_axes(self):
        in_shape = self.input_shapes['2d']
        out_shape = self.output_shapes['2d']

        axes = (-3, )
        a, b = self.create_test_arrays(in_shape, out_shape)

        with self.assertRaisesRegex(IndexError, 'Invalid axes'):
            FFTW(a, b, axes, direction=self.direction)

        axes = (10, )
        with self.assertRaisesRegex(IndexError, 'Invalid axes'):
            FFTW(a, b, axes, direction=self.direction)
コード例 #11
0
ファイル: test_pyfftw_wisdom.py プロジェクト: zronaghi/pyFFTW
    def generate_wisdom(self):
        for each_dtype in (numpy.complex128, numpy.complex64,
                numpy.clongdouble):

            a = empty_aligned((1,1024), each_dtype, n=16)
            b = empty_aligned(a.shape, dtype=a.dtype, n=16)
            fft = FFTW(a,b)
コード例 #12
0
    def test_call_with_ortho_on(self):
        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)

        ifft = FFTW(self.output_array, _input_array, direction='FFTW_BACKWARD')

        self.fft(ortho=True, normalise_idft=False)

        # ortho case preserves the norm in forward direction
        self.assertTrue(
            numpy.allclose(numpy.linalg.norm(self.input_array),
                           numpy.linalg.norm(self.output_array)))

        ifft(ortho=True, normalise_idft=False)

        # ortho case preserves the norm in backward direction
        self.assertTrue(
            numpy.allclose(numpy.linalg.norm(_input_array),
                           numpy.linalg.norm(self.output_array)))

        self.assertTrue(numpy.allclose(self.input_array, _input_array))

        # cant select both ortho and normalise_idft
        self.assertRaisesRegex(ValueError,
                               'Invalid options',
                               self.fft,
                               normalise_idft=True,
                               ortho=True)
        # cant specify orth=True with default normalise_idft=True
        self.assertRaisesRegex(ValueError,
                               'Invalid options',
                               self.fft,
                               ortho=True)
コード例 #13
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_normalisation_on(self):
        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)

        ifft = FFTW(self.output_array, _input_array, direction='FFTW_BACKWARD')

        self.fft(normalise_idft=True)  # Shouldn't make any difference
        ifft(normalise_idft=True)

        self.assertTrue(numpy.allclose(self.input_array, _input_array))
コード例 #14
0
    def test_direction_property(self):
        '''Test to see if the direction property returns the correct thing
        '''
        self.assertEqual(self.fft.direction, 'FFTW_FORWARD')

        new_fft = FFTW(self.input_array, self.output_array,
                direction='FFTW_BACKWARD')

        self.assertEqual(new_fft.direction, 'FFTW_BACKWARD')
コード例 #15
0
    def test_normalise_idft_property(self):
        '''normalise_idft property defaults to True
        '''
        self.assertEqual(self.fft.normalise_idft, True)

        newfft = FFTW(self.input_array,
                      self.output_array,
                      normalise_idft=False)
        self.assertEqual(newfft.normalise_idft, False)
コード例 #16
0
    def test_wrong_direction_fail(self):
        in_shape = self.input_shapes['2d']
        out_shape = self.output_shapes['2d']

        axes=(-1,)
        a, b = self.create_test_arrays(in_shape, out_shape)

        with self.assertRaisesRegex(ValueError, 'Invalid direction'):
            FFTW(a, b, direction='FFTW_BACKWARD')
コード例 #17
0
ファイル: test_pyfftw_call.py プロジェクト: grlee77/pyFFTW
    def setUp(self):

        self.input_array = empty_aligned((256, 512), dtype='complex128', n=16)
        self.output_array = empty_aligned((256, 512), dtype='complex128', n=16)

        self.fft = FFTW(self.input_array, self.output_array)

        self.input_array[:] = (numpy.random.randn(*self.input_array.shape)
                + 1j*numpy.random.randn(*self.input_array.shape))
コード例 #18
0
    def test_extra_dimension_fail(self):
        in_shape = self.input_shapes['2d']
        _out_shape = self.output_shapes['2d']
        out_shape = (2, _out_shape[0], _out_shape[1])

        axes = (1, )
        a, b = self.create_test_arrays(in_shape, out_shape)

        with self.assertRaisesRegex(ValueError, 'Invalid shapes'):
            FFTW(a, b, direction=self.direction)
コード例 #19
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_normalisation_default(self):
        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)

        ifft = FFTW(self.output_array, _input_array, direction='FFTW_BACKWARD')

        self.fft()
        ifft()

        # Scaling is performed by default
        self.assertTrue(numpy.allclose(self.input_array, _input_array))
コード例 #20
0
    def test_axes_property(self):
        '''Test to see if the axes property returns the correct thing
        '''
        self.assertEqual(self.fft.axes, (1,))

        new_fft = FFTW(self.input_array, self.output_array, axes=(-1, -2))
        self.assertEqual(new_fft.axes, (1, 0))

        new_fft = FFTW(self.input_array, self.output_array, axes=(-2, -1))
        self.assertEqual(new_fft.axes, (0, 1))

        new_fft = FFTW(self.input_array, self.output_array, axes=(1, 0))
        self.assertEqual(new_fft.axes, (1, 0))

        new_fft = FFTW(self.input_array, self.output_array, axes=(1,))
        self.assertEqual(new_fft.axes, (1,))

        new_fft = FFTW(self.input_array, self.output_array, axes=(0,))
        self.assertEqual(new_fft.axes, (0,))
コード例 #21
0
    def test_ortho_property(self):
        '''ortho property defaults to False
        '''
        self.assertEqual(self.fft.ortho, False)

        newfft = FFTW(self.input_array,
                      self.output_array,
                      ortho=True,
                      normalise_idft=False)
        self.assertEqual(newfft.ortho, True)
コード例 #22
0
    def test_call_with_ortho_off(self):
        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)

        ifft = FFTW(self.output_array, _input_array, direction='FFTW_BACKWARD')

        self.fft(ortho=False)
        ifft(ortho=False)

        # Scaling by normalise_idft is performed by default
        self.assertTrue(numpy.allclose(self.input_array, _input_array))
コード例 #23
0
    def test_missized_nonfft_axes_fail(self):
        in_shape = self.input_shapes['3d']
        _out_shape = self.output_shapes['3d']
        out_shape = (_out_shape[0], _out_shape[1] + 1, _out_shape[2])

        axes = (2, )
        a, b = self.create_test_arrays(in_shape, out_shape)

        with self.assertRaisesRegex(ValueError, 'Invalid shapes'):
            FFTW(a, b, direction=self.direction)
コード例 #24
0
    def test_default_args(self):
        in_shape = self.input_shapes['2d']
        out_shape = self.output_shapes['2d']

        a, b = self.create_test_arrays(in_shape, out_shape)

        # default args should fail for backwards transforms
        # (as the default is FFTW_FORWARD)
        with self.assertRaisesRegex(ValueError, 'Invalid direction'):
            FFTW(a, b)
コード例 #25
0
    def test_output_dtype(self):
        '''Test to see if the output_dtype property returns the correct thing
        '''
        self.assertEqual(self.fft.output_dtype, self.output_array.dtype)

        new_input_array = numpy.complex64(self.input_array)
        new_output_array = numpy.complex64(self.output_array)

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.output_dtype, new_output_array.dtype)
コード例 #26
0
    def test_output_strides(self):
        '''Test to see if the output_shape property returns the correct thing
        '''
        self.assertEqual(self.fft.output_shape, self.output_array.shape)

        new_input_array = self.output_array[::2, ::4]
        new_output_array = self.output_array[::2, ::4]

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.output_shape, new_output_array.shape)
コード例 #27
0
    def setUp(self):

        self.input_array = n_byte_align_empty((256, 512), 16, 
                dtype='complex128')
        self.output_array = n_byte_align_empty((256, 512), 16,
                dtype='complex128')

        self.fft = FFTW(self.input_array, self.output_array)

        self.output_array[:] = (numpy.random.randn(*self.output_array.shape) 
                + 1j*numpy.random.randn(*self.output_array.shape))
コード例 #28
0
    def create_test_arrays(self, input_shape, output_shape, axes=None):

        a = self.input_dtype(
            numpy.random.randn(*input_shape) +
            1j * numpy.random.randn(*input_shape))

        b = self.output_dtype(numpy.random.randn(*output_shape))

        # We fill a by doing the forward FFT from b.
        # This means that the relevant bits that should be purely
        # real will be (for example the zero freq component).
        # This is easier than writing a complicate system to work it out.
        try:
            if axes == None:
                fft = FFTW(b, a, direction='FFTW_FORWARD')
            else:
                fft = FFTW(b, a, direction='FFTW_FORWARD', axes=axes)

            b[:] = self.output_dtype(numpy.random.randn(*output_shape))

            fft.execute()

            scaling = numpy.prod(numpy.array(a.shape))
            a = self.input_dtype(a / scaling)

        except ValueError:
            # In this case, we assume that it was meant to error,
            # so we can return what we want.
            pass

        b = self.output_dtype(numpy.random.randn(*output_shape))

        return a, b
コード例 #29
0
ファイル: test_pyfftw_partial.py プロジェクト: zuroh/pyFFTW
 def test_failure(self):
     for dtype, npdtype in zip(
         ['32', '64', 'ld'], [np.complex64, np.complex128, np.clongdouble]):
         if dtype == 'ld' and np.dtype(np.clongdouble) == np.dtype(
                 np.complex128):
             # skip this test on systems where clongdouble is complex128
             continue
         if dtype not in _supported_types:
             a = empty_aligned((1, 1024), npdtype, n=16)
             b = empty_aligned(a.shape, dtype=a.dtype, n=16)
             msg = "Rebuild pyFFTW with support for %s precision!" % _all_types_human_readable[
                 dtype]
             with self.assertRaisesRegex(NotImplementedError, msg):
                 FFTW(a, b)
コード例 #30
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_copy_with_missized_array_error(self):
        '''Force an input copy with a missized array.
        '''
        shape = list(self.input_array.shape + (2, ))
        shape[0] += 1

        input_array = byte_align(numpy.random.randn(*shape) +
                                 1j * numpy.random.randn(*shape),
                                 n=16)

        fft = FFTW(self.input_array, self.output_array)

        self.assertRaisesRegex(ValueError, 'Invalid input shape', self.fft,
                               **{'input_array': input_array[:, :, 0]})
コード例 #31
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_auto_input_alignment(self):
        '''Test the class call with a keyword input update.
        '''
        input_array = (numpy.random.randn(*self.input_array.shape) +
                       1j * numpy.random.randn(*self.input_array.shape))

        output_array = self.fft(
            input_array=byte_align(input_array.copy(), n=16)).copy()

        # Offset by one from 16 byte aligned to guarantee it's not
        # 16 byte aligned
        a = input_array
        a__ = empty_aligned(numpy.prod(a.shape) * a.itemsize + 1,
                            dtype='int8',
                            n=16)

        a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
        a_[:] = a

        # Just confirm that a usual update will fail
        self.assertRaisesRegex(ValueError, 'Invalid input alignment',
                               self.fft.update_arrays,
                               *(a_, self.output_array))

        self.fft(a_, self.output_array)

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

        # now try with a single byte offset and SIMD off
        ar, ai = numpy.float32(numpy.random.randn(2, 257))
        a = ar[1:] + 1j * ai[1:]

        b = a.copy()

        a_size = len(a.ravel()) * a.itemsize

        update_array = numpy.frombuffer(numpy.zeros(a_size + 1,
                                                    dtype='int8')[1:].data,
                                        dtype=a.dtype).reshape(a.shape)

        fft = FFTW(a, b, flags=('FFTW_UNALIGNED', ))
        # Confirm that a usual update will fail (it's not on the
        # byte boundary)
        self.assertRaisesRegex(ValueError, 'Invalid input alignment',
                               fft.update_arrays, *(update_array, b))

        fft(update_array, b)
コード例 #32
0
def psd(buf_in, buf_out):
    """
    Perform discrete fourier transforms using the FFTW library and use it to
    get the power spectral density. FFTW optimizes
    the fft algorithm based on the size of the arrays, with SIMD parallelized
    commands. This optimization requires initialization, so this is a factory
    function that returns a numba gufunc that performs the FFT. FFTW works on
    fixed memory buffers, so you must tell it what memory to use ahead of time.
    When using this with ProcessingChain, to ensure the correct buffers are used
    call ProcessingChain.get_variable('var_name') to give it the internal memory
    buffer directly (with raw_to_dsp, you can just give it the name and it will
    automatically happen!). The possible dtypes for the input/outputs are:
    - complex64 (size n) -> float32/float (size n) 
    - complex128 (size n) -> float64/double (size n)
    - complex256/clongdouble (size n) -> float128/longdouble (size n)
    - float32/float (size n) -> float32/float (size n/2+1)
    - float64/double (size n) -> float64/double (size n/2+1)
    - float128/longdouble (size n) -> float128/longdouble (size n/2+1)
    """

    # build intermediate array for the dft, which will be abs'd to get the PSD
    buf_dft = np.ndarray(
        buf_out.shape, np.dtype('complex' + str(buf_out.dtype.itemsize * 16)))
    try:
        dft_fun = FFTW(buf_in, buf_dft, axes=(-1, ), direction='FFTW_FORWARD')
    except ValueError:
        raise ValueError("""Incompatible array types/shapes. Allowed:
        - complex64 (size n) -> float32/float (size n) 
        - complex128 (size n) -> float64/double (size n)
        - complex256/clongdouble (size n) -> float128/longdouble (size n)
        - float32/float (size n) -> float32/float (size n/2+1)
        - float64/double (size n) -> float64/double (size n/2+1)
        - float128/longdouble (size n) -> float128/longdouble (size n/2+1)""")

    typesig = 'void(' + str(buf_in.dtype) + '[:, :], ' + str(
        buf_out.dtype) + '[:, :])'
    sizesig = '(m, n)->(m, n)' if buf_in.shape == buf_out.shape else '(m, n),(m, l)'

    @guvectorize([typesig], sizesig, forceobj=True)
    def psd(wf_in, psd_out):
        dft_fun(wf_in, buf_dft)
        np.abs(buf_dft, psd_out)

    return psd
コード例 #33
0
def inv_dft(buf_in, buf_out):
    """
    Perform inverse discrete fourier transforms using FFTW. FFTW optimizes
    the fft algorithm based on the size of the arrays, with SIMD parallelized
    commands. This optimization requires initialization, so this is a factory
    function that returns a numba gufunc that performs the FFT. FFTW works on
    fixed memory buffers, so you must tell it what memory to use ahead of time.
    When using this with ProcessingChain, to ensure the correct buffers are used
    call ProcessingChain.get_variable('var_name') to give it the internal memory
    buffer directly (with raw_to_dsp, you can just give it the name and it will
    automatically happen!). The possible dtypes for the input/outputs are:
    - complex64 (size n/2+1) -> float32/float (size n) 
    - complex128 (size n/2+1) -> float64/double (size n)
    - complex256/clongdouble (size n/2+1) -> float128/longdouble (size n)
    - complex64 (size n) -> complex64 (size n)
    - complex128 (size n) -> complex128 (size n)
    - complex256/clongdouble (size n) -> complex256/clongdouble (size n)
    """

    try:
        idft_fun = FFTW(buf_in,
                        buf_out,
                        axes=(-1, ),
                        direction='FFTW_BACKWARD')
    except ValueError:
        raise ValueError("""Incompatible array types/shapes. Allowed:
        - complex64 (size n/2+1) -> float32/float (size n) 
        - complex128 (size n/2+1) -> float64/double (size n)
        - complex256/clongdouble (size n/2+1) -> float128/longdouble (size n)
        - complex64 (size n) -> complex64 (size n)
        - complex128 (size n) -> complex128 (size n)
        - complex256/clongdouble (size n) -> complex256/clongdouble (size n)"""
                         )

    typesig = 'void(' + str(buf_in.dtype) + '[:, :], ' + str(
        buf_out.dtype) + '[:, :])'
    sizesig = '(m, n)->(m, n)' if buf_in.shape == buf_out.shape else '(m, n),(m, l)'

    @guvectorize([typesig], sizesig, forceobj=True)
    def inv_dft(wf_in, dft_out):
        idft_fun(wf_in, dft_out)

    return inv_dft
コード例 #34
0
ファイル: test_pyfftw_call.py プロジェクト: zpincus/pyFFTW
    def test_call_with_different_striding(self):
        '''Test the input update with different strides to internal array.
        '''
        shape = self.input_array.shape + (2, )

        input_array = byte_align(numpy.random.randn(*shape) +
                                 1j * numpy.random.randn(*shape),
                                 n=16)

        fft = FFTW(input_array[:, :, 0], self.output_array)

        test_output_array = fft().copy()

        new_input_array = byte_align(input_array[:, :, 0].copy(), n=16)

        new_output = fft(new_input_array).copy()

        # Test the test!
        self.assertTrue(
            new_input_array.strides != input_array[:, :, 0].strides)

        self.assertTrue(numpy.alltrue(test_output_array == new_output))
コード例 #35
0
ファイル: test_pyfftw_call.py プロジェクト: rajath/pyFFTW
class FFTWCallTest(unittest.TestCase):
    def __init__(self, *args, **kwargs):

        super(FFTWCallTest, self).__init__(*args, **kwargs)

        if not hasattr(self, "assertRaisesRegex"):
            self.assertRaisesRegex = self.assertRaisesRegexp

    def setUp(self):

        self.input_array = empty_aligned((256, 512), dtype="complex128", n=16)
        self.output_array = empty_aligned((256, 512), dtype="complex128", n=16)

        self.fft = FFTW(self.input_array, self.output_array)

        self.input_array[:] = numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(
            *self.input_array.shape
        )

    def test_call(self):
        """Test a call to an instance of the class.
        """

        self.input_array[:] = numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(
            *self.input_array.shape
        )

        output_array = self.fft()

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

    def test_call_with_positional_input_update(self):
        """Test the class call with a positional input update.
        """

        input_array = byte_align(
            (numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)), n=16
        )

        output_array = self.fft(byte_align(input_array.copy(), n=16)).copy()

        self.fft.update_arrays(input_array, self.output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

    def test_call_with_keyword_input_update(self):
        """Test the class call with a keyword input update.
        """
        input_array = byte_align(
            numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape), n=16
        )

        output_array = self.fft(input_array=byte_align(input_array.copy(), n=16)).copy()

        self.fft.update_arrays(input_array, self.output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

    def test_call_with_keyword_output_update(self):
        """Test the class call with a keyword output update.
        """
        output_array = byte_align(
            (numpy.random.randn(*self.output_array.shape) + 1j * numpy.random.randn(*self.output_array.shape)), n=16
        )

        returned_output_array = self.fft(output_array=byte_align(output_array.copy(), n=16)).copy()

        self.fft.update_arrays(self.input_array, output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(returned_output_array == output_array))

    def test_call_with_positional_updates(self):
        """Test the class call with a positional array updates.
        """

        input_array = byte_align(
            (numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)), n=16
        )

        output_array = byte_align(
            (numpy.random.randn(*self.output_array.shape) + 1j * numpy.random.randn(*self.output_array.shape)), n=16
        )

        returned_output_array = self.fft(
            byte_align(input_array.copy(), n=16), byte_align(output_array.copy(), n=16)
        ).copy()

        self.fft.update_arrays(input_array, output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(returned_output_array == output_array))

    def test_call_with_keyword_updates(self):
        """Test the class call with a positional output update.
        """

        input_array = byte_align(
            (numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)), n=16
        )

        output_array = byte_align(
            (numpy.random.randn(*self.output_array.shape) + 1j * numpy.random.randn(*self.output_array.shape)), n=16
        )

        returned_output_array = self.fft(
            output_array=byte_align(output_array.copy(), n=16), input_array=byte_align(input_array.copy(), n=16)
        ).copy()

        self.fft.update_arrays(input_array, output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(returned_output_array == output_array))

    def test_call_with_different_input_dtype(self):
        """Test the class call with an array with a different input dtype
        """
        input_array = byte_align(
            numpy.complex64(
                numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)
            ),
            n=16,
        )

        output_array = self.fft(byte_align(input_array.copy(), n=16)).copy()

        _input_array = byte_align(numpy.asarray(input_array, dtype=self.input_array.dtype), n=16)

        self.assertTrue(_input_array.dtype != input_array.dtype)

        self.fft.update_arrays(_input_array, self.output_array)
        self.fft.execute()

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

    def test_call_with_list_input(self):
        """Test the class call with a list rather than an array
        """

        output_array = self.fft().copy()

        test_output_array = self.fft(self.input_array.tolist()).copy()

        self.assertTrue(numpy.alltrue(output_array == test_output_array))

    def test_call_with_invalid_update(self):
        """Test the class call with an invalid update.
        """

        new_shape = self.input_array.shape + (2,)
        invalid_array = numpy.random.randn(*new_shape) + 1j * numpy.random.randn(*new_shape)

        self.assertRaises(ValueError, self.fft, *(), **{"output_array": invalid_array})

        self.assertRaises(ValueError, self.fft, *(), **{"input_array": invalid_array})

    def test_call_with_auto_input_alignment(self):
        """Test the class call with a keyword input update.
        """
        input_array = numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)

        output_array = self.fft(input_array=byte_align(input_array.copy(), n=16)).copy()

        # Offset by one from 16 byte aligned to guarantee it's not
        # 16 byte aligned
        a = input_array
        a__ = empty_aligned(numpy.prod(a.shape) * a.itemsize + 1, dtype="int8", n=16)

        a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
        a_[:] = a

        # Just confirm that a usual update will fail
        self.assertRaisesRegex(ValueError, "Invalid input alignment", self.fft.update_arrays, *(a_, self.output_array))

        self.fft(a_, self.output_array)

        self.assertTrue(numpy.alltrue(output_array == self.output_array))

        # now try with a single byte offset and SIMD off
        ar, ai = numpy.float32(numpy.random.randn(2, 257))
        a = ar[1:] + 1j * ai[1:]

        b = a.copy()

        a_size = len(a.ravel()) * a.itemsize

        update_array = numpy.frombuffer(numpy.zeros(a_size + 1, dtype="int8")[1:].data, dtype=a.dtype).reshape(a.shape)

        fft = FFTW(a, b, flags=("FFTW_UNALIGNED",))
        # Confirm that a usual update will fail (it's not on the
        # byte boundary)
        self.assertRaisesRegex(ValueError, "Invalid input alignment", fft.update_arrays, *(update_array, b))

        fft(update_array, b)

    def test_call_with_invalid_output_striding(self):
        """Test the class call with an invalid strided output update.
        """
        # Add an extra dimension to bugger up the striding
        new_shape = self.output_array.shape + (2,)
        output_array = byte_align(numpy.random.randn(*new_shape) + 1j * numpy.random.randn(*new_shape), n=16)

        self.assertRaisesRegex(
            ValueError, "Invalid output striding", self.fft, **{"output_array": output_array[:, :, 1]}
        )

    def test_call_with_different_striding(self):
        """Test the input update with different strides to internal array.
        """
        shape = self.input_array.shape + (2,)

        input_array = byte_align(numpy.random.randn(*shape) + 1j * numpy.random.randn(*shape), n=16)

        fft = FFTW(input_array[:, :, 0], self.output_array)

        test_output_array = fft().copy()

        new_input_array = byte_align(input_array[:, :, 0].copy(), n=16)

        new_output = fft(new_input_array).copy()

        # Test the test!
        self.assertTrue(new_input_array.strides != input_array[:, :, 0].strides)

        self.assertTrue(numpy.alltrue(test_output_array == new_output))

    def test_call_with_copy_with_missized_array_error(self):
        """Force an input copy with a missized array.
        """
        shape = list(self.input_array.shape + (2,))
        shape[0] += 1

        input_array = byte_align(numpy.random.randn(*shape) + 1j * numpy.random.randn(*shape), n=16)

        fft = FFTW(self.input_array, self.output_array)

        self.assertRaisesRegex(ValueError, "Invalid input shape", self.fft, **{"input_array": input_array[:, :, 0]})

    def test_call_with_unaligned(self):
        """Make sure the right thing happens with unaligned data.
        """
        input_array = numpy.random.randn(*self.input_array.shape) + 1j * numpy.random.randn(*self.input_array.shape)

        output_array = self.fft(input_array=byte_align(input_array.copy(), n=16)).copy()

        input_array = byte_align(input_array, n=16)
        output_array = byte_align(output_array, n=16)

        # Offset by one from 16 byte aligned to guarantee it's not
        # 16 byte aligned
        a = byte_align(input_array.copy(), n=16)
        a__ = empty_aligned(numpy.prod(a.shape) * a.itemsize + 1, dtype="int8", n=16)

        a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
        a_[:] = a

        # Create a different second array the same way
        b = byte_align(output_array.copy(), n=16)
        b__ = empty_aligned(numpy.prod(b.shape) * a.itemsize + 1, dtype="int8", n=16)

        b_ = b__[1:].view(dtype=b.dtype).reshape(*b.shape)
        b_[:] = a

        # Set up for the first array
        fft = FFTW(input_array, output_array)
        a_[:] = a
        output_array = fft().copy()

        # Check a_ is not aligned...
        self.assertRaisesRegex(ValueError, "Invalid input alignment", self.fft.update_arrays, *(a_, output_array))

        # and b_ too
        self.assertRaisesRegex(ValueError, "Invalid output alignment", self.fft.update_arrays, *(input_array, b_))

        # But it should still work with the a_
        fft(a_)

        # However, trying to update the output will raise an error
        self.assertRaisesRegex(ValueError, "Invalid output alignment", self.fft.update_arrays, *(input_array, b_))

        # Same with SIMD off
        fft = FFTW(input_array, output_array, flags=("FFTW_UNALIGNED",))
        fft(a_)
        self.assertRaisesRegex(ValueError, "Invalid output alignment", self.fft.update_arrays, *(input_array, b_))

    def test_call_with_normalisation_on(self):
        _input_array = empty_aligned((256, 512), dtype="complex128", n=16)

        ifft = FFTW(self.output_array, _input_array, direction="FFTW_BACKWARD")

        self.fft(normalise_idft=True)  # Shouldn't make any difference
        ifft(normalise_idft=True)

        self.assertTrue(numpy.allclose(self.input_array, _input_array))

    def test_call_with_normalisation_off(self):
        _input_array = empty_aligned((256, 512), dtype="complex128", n=16)

        ifft = FFTW(self.output_array, _input_array, direction="FFTW_BACKWARD")

        self.fft(normalise_idft=True)  # Shouldn't make any difference
        ifft(normalise_idft=False)

        _input_array /= ifft.N

        self.assertTrue(numpy.allclose(self.input_array, _input_array))

    def test_call_with_normalisation_default(self):
        _input_array = empty_aligned((256, 512), dtype="complex128", n=16)

        ifft = FFTW(self.output_array, _input_array, direction="FFTW_BACKWARD")

        self.fft()
        ifft()

        # Scaling is performed by default
        self.assertTrue(numpy.allclose(self.input_array, _input_array))

    def test_call_with_normalisation_precision(self):
        """The normalisation should use a double precision scaling.
        """
        # Should be the case for double inputs...
        _input_array = empty_aligned((256, 512), dtype="complex128", n=16)

        ifft = FFTW(self.output_array, _input_array, direction="FFTW_BACKWARD")

        ref_output = ifft(normalise_idft=False).copy() / numpy.float64(ifft.N)
        test_output = ifft(normalise_idft=True).copy()

        self.assertTrue(numpy.alltrue(ref_output == test_output))

        # ... and single inputs.
        _input_array = empty_aligned((256, 512), dtype="complex64", n=16)

        ifft = FFTW(numpy.array(self.output_array, _input_array.dtype), _input_array, direction="FFTW_BACKWARD")

        ref_output = ifft(normalise_idft=False).copy() / numpy.float64(ifft.N)
        test_output = ifft(normalise_idft=True).copy()

        self.assertTrue(numpy.alltrue(ref_output == test_output))
コード例 #36
0
    def test_differing_aligned_arrays_update(self):
        '''Test to see if the alignment code is working as expected
        '''

        # Start by creating arrays that are only on various byte 
        # alignments (4, 16 and 32)
        _input_array = n_byte_align_empty(
                len(self.input_array.ravel())*2+5,
                32, dtype='float32')
        _output_array = n_byte_align_empty(
                len(self.output_array.ravel())*2+5,
                32, dtype='float32')

        _input_array[:] = 0
        _output_array[:] = 0

        input_array_4 = (
                numpy.frombuffer(_input_array[1:-4].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_4 = (
                numpy.frombuffer(_output_array[1:-4].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_array_16 = (
                numpy.frombuffer(_input_array[4:-1].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_16 = (
                numpy.frombuffer(_output_array[4:-1].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_array_32 = (
                numpy.frombuffer(_input_array[:-5].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_32 = (
                numpy.frombuffer(_output_array[:-5].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_arrays = {4: input_array_4,
                16: input_array_16,
                32: input_array_32}

        output_arrays = {4: output_array_4,
                16: output_array_16,
                32: output_array_32}

        alignments = (4, 16, 32)

        # Test the arrays are aligned on 4 bytes...
        self.assertTrue(is_n_byte_aligned(input_arrays[4], 4))
        self.assertTrue(is_n_byte_aligned(output_arrays[4], 4))

        # ...and on 16...
        self.assertFalse(is_n_byte_aligned(input_arrays[4], 16))
        self.assertFalse(is_n_byte_aligned(output_arrays[4], 16))
        self.assertTrue(is_n_byte_aligned(input_arrays[16], 16))
        self.assertTrue(is_n_byte_aligned(output_arrays[16], 16))

        # ...and on 32...
        self.assertFalse(is_n_byte_aligned(input_arrays[16], 32))
        self.assertFalse(is_n_byte_aligned(output_arrays[16], 32))
        self.assertTrue(is_n_byte_aligned(input_arrays[32], 32))
        self.assertTrue(is_n_byte_aligned(output_arrays[32], 32))

        if len(pyfftw.pyfftw._valid_simd_alignments) > 0:
            max_align = pyfftw.pyfftw._valid_simd_alignments[0]
        else:
            max_align = simd_alignment

        for in_align in alignments:
            for out_align in alignments:
                expected_align = min(in_align, out_align, max_align)
                fft = FFTW(input_arrays[in_align], output_arrays[out_align])

                self.assertTrue(fft.input_alignment == expected_align)
                self.assertTrue(fft.output_alignment == expected_align)

                for update_align in alignments:

                    if update_align < expected_align:
                        # This should fail (not aligned properly)
                        self.assertRaisesRegex(ValueError,
                                'Invalid input alignment',
                                fft.update_arrays,
                                input_arrays[update_align],
                                output_arrays[out_align])

                        self.assertRaisesRegex(ValueError,
                                'Invalid output alignment',
                                fft.update_arrays,
                                input_arrays[in_align],
                                output_arrays[update_align])

                    else:
                        # This should work (and not segfault!)
                        fft.update_arrays(input_arrays[update_align], 
                                output_arrays[out_align])
                        fft.update_arrays(input_arrays[in_align], 
                                output_arrays[update_align])
                        fft.execute()
コード例 #37
0
class FFTWMiscTest(unittest.TestCase):
    
    def __init__(self, *args, **kwargs):

        super(FFTWMiscTest, self).__init__(*args, **kwargs)

        # Assume python 3, but keep backwards compatibility
        if not hasattr(self, 'assertRaisesRegex'):
            self.assertRaisesRegex = self.assertRaisesRegexp


    def setUp(self):

        self.input_array = n_byte_align_empty((256, 512), 16, 
                dtype='complex128')
        self.output_array = n_byte_align_empty((256, 512), 16,
                dtype='complex128')

        self.fft = FFTW(self.input_array, self.output_array)

        self.output_array[:] = (numpy.random.randn(*self.output_array.shape) 
                + 1j*numpy.random.randn(*self.output_array.shape))

    def test_aligned_flag(self):
        '''Test to see if the aligned flag is correct
        '''
        fft = FFTW(self.input_array, self.output_array)
        self.assertTrue(fft.simd_aligned)

        fft = FFTW(self.input_array, self.output_array, 
                flags=('FFTW_UNALIGNED',))

        self.assertFalse(fft.simd_aligned)

    def test_flags(self):
        '''Test to see if the flags are correct
        '''
        fft = FFTW(self.input_array, self.output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE',))

        fft = FFTW(self.input_array, self.output_array, 
                flags=('FFTW_DESTROY_INPUT', 'FFTW_UNALIGNED'))
        self.assertEqual(fft.flags, ('FFTW_DESTROY_INPUT', 'FFTW_UNALIGNED'))

        # Test an implicit flag
        _input_array = n_byte_align_empty(256, 16, dtype='complex64')
        _output_array = n_byte_align_empty(256, 16, dtype='complex64')

        # These are guaranteed to be misaligned (due to dtype size == 8)
        input_array = _input_array[:-1]
        output_array = _output_array[:-1]
        u_input_array = _input_array[1:]
        u_output_array = _output_array[1:]

        fft = FFTW(input_array, u_output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))

        fft = FFTW(u_input_array, output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))

        fft = FFTW(u_input_array, u_output_array)
        self.assertEqual(fft.flags, ('FFTW_MEASURE', 'FFTW_UNALIGNED'))

    def test_differing_aligned_arrays_update(self):
        '''Test to see if the alignment code is working as expected
        '''

        # Start by creating arrays that are only on various byte 
        # alignments (4, 16 and 32)
        _input_array = n_byte_align_empty(
                len(self.input_array.ravel())*2+5,
                32, dtype='float32')
        _output_array = n_byte_align_empty(
                len(self.output_array.ravel())*2+5,
                32, dtype='float32')

        _input_array[:] = 0
        _output_array[:] = 0

        input_array_4 = (
                numpy.frombuffer(_input_array[1:-4].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_4 = (
                numpy.frombuffer(_output_array[1:-4].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_array_16 = (
                numpy.frombuffer(_input_array[4:-1].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_16 = (
                numpy.frombuffer(_output_array[4:-1].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_array_32 = (
                numpy.frombuffer(_input_array[:-5].data, dtype='complex64')
                .reshape(self.input_array.shape))
        output_array_32 = (
                numpy.frombuffer(_output_array[:-5].data, dtype='complex64')
                .reshape(self.output_array.shape))

        input_arrays = {4: input_array_4,
                16: input_array_16,
                32: input_array_32}

        output_arrays = {4: output_array_4,
                16: output_array_16,
                32: output_array_32}

        alignments = (4, 16, 32)

        # Test the arrays are aligned on 4 bytes...
        self.assertTrue(is_n_byte_aligned(input_arrays[4], 4))
        self.assertTrue(is_n_byte_aligned(output_arrays[4], 4))

        # ...and on 16...
        self.assertFalse(is_n_byte_aligned(input_arrays[4], 16))
        self.assertFalse(is_n_byte_aligned(output_arrays[4], 16))
        self.assertTrue(is_n_byte_aligned(input_arrays[16], 16))
        self.assertTrue(is_n_byte_aligned(output_arrays[16], 16))

        # ...and on 32...
        self.assertFalse(is_n_byte_aligned(input_arrays[16], 32))
        self.assertFalse(is_n_byte_aligned(output_arrays[16], 32))
        self.assertTrue(is_n_byte_aligned(input_arrays[32], 32))
        self.assertTrue(is_n_byte_aligned(output_arrays[32], 32))

        if len(pyfftw.pyfftw._valid_simd_alignments) > 0:
            max_align = pyfftw.pyfftw._valid_simd_alignments[0]
        else:
            max_align = simd_alignment

        for in_align in alignments:
            for out_align in alignments:
                expected_align = min(in_align, out_align, max_align)
                fft = FFTW(input_arrays[in_align], output_arrays[out_align])

                self.assertTrue(fft.input_alignment == expected_align)
                self.assertTrue(fft.output_alignment == expected_align)

                for update_align in alignments:

                    if update_align < expected_align:
                        # This should fail (not aligned properly)
                        self.assertRaisesRegex(ValueError,
                                'Invalid input alignment',
                                fft.update_arrays,
                                input_arrays[update_align],
                                output_arrays[out_align])

                        self.assertRaisesRegex(ValueError,
                                'Invalid output alignment',
                                fft.update_arrays,
                                input_arrays[in_align],
                                output_arrays[update_align])

                    else:
                        # This should work (and not segfault!)
                        fft.update_arrays(input_arrays[update_align], 
                                output_arrays[out_align])
                        fft.update_arrays(input_arrays[in_align], 
                                output_arrays[update_align])
                        fft.execute()


    def test_get_input_array(self):
        '''Test to see the get_input_array method returns the correct thing
        '''
        with warnings.catch_warnings(record=True) as w:
            # This method is deprecated, so check the deprecation warning
            # is raised.
            warnings.simplefilter("always")
            input_array = self.fft.get_input_array()
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))

        self.assertIs(self.input_array, input_array)

    def test_get_output_array(self):
        '''Test to see the get_output_array method returns the correct thing
        '''
        with warnings.catch_warnings(record=True) as w:
            # This method is deprecated, so check the deprecation warning
            # is raised.
            warnings.simplefilter("always")
            output_array = self.fft.get_output_array()
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))

        self.assertIs(self.output_array, output_array)

    def test_input_array(self):
        '''Test to see the input_array property returns the correct thing
        '''
        self.assertIs(self.input_array, self.fft.input_array)

    def test_output_array(self):
        '''Test to see the output_array property returns the correct thing
        '''
        self.assertIs(self.output_array, self.fft.output_array)

    def test_input_strides(self):
        '''Test to see if the input_strides property returns the correct thing
        '''
        self.assertEqual(self.fft.input_strides, self.input_array.strides)

        new_input_array = self.input_array[::2, ::4]
        new_output_array = self.output_array[::2, ::4]

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.input_strides, new_input_array.strides)

    def test_output_strides(self):
        '''Test to see if the output_strides property returns the correct thing
        '''
        self.assertEqual(self.fft.output_strides, self.output_array.strides)

        new_input_array = self.output_array[::2, ::4]
        new_output_array = self.output_array[::2, ::4]

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.output_strides, new_output_array.strides)

    def test_input_shape(self):
        '''Test to see if the input_shape property returns the correct thing
        '''
        self.assertEqual(self.fft.input_shape, self.input_array.shape)

        new_input_array = self.input_array[::2, ::4]
        new_output_array = self.output_array[::2, ::4]

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.input_shape, new_input_array.shape)

    def test_output_strides(self):
        '''Test to see if the output_shape property returns the correct thing
        '''
        self.assertEqual(self.fft.output_shape, self.output_array.shape)

        new_input_array = self.output_array[::2, ::4]
        new_output_array = self.output_array[::2, ::4]

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.output_shape, new_output_array.shape)

    def test_input_dtype(self):
        '''Test to see if the input_dtype property returns the correct thing
        '''
        self.assertEqual(self.fft.input_dtype, self.input_array.dtype)

        new_input_array = numpy.complex64(self.input_array)
        new_output_array = numpy.complex64(self.output_array)

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.input_dtype, new_input_array.dtype)

    def test_output_dtype(self):
        '''Test to see if the output_dtype property returns the correct thing
        '''
        self.assertEqual(self.fft.output_dtype, self.output_array.dtype)

        new_input_array = numpy.complex64(self.input_array)
        new_output_array = numpy.complex64(self.output_array)

        new_fft = FFTW(new_input_array, new_output_array)

        self.assertEqual(new_fft.output_dtype, new_output_array.dtype)

    def test_direction_property(self):
        '''Test to see if the direction property returns the correct thing
        '''
        self.assertEqual(self.fft.direction, 'FFTW_FORWARD')

        new_fft = FFTW(self.input_array, self.output_array, 
                direction='FFTW_BACKWARD')

        self.assertEqual(new_fft.direction, 'FFTW_BACKWARD')

    def test_axes_property(self):
        '''Test to see if the axes property returns the correct thing
        '''
        self.assertEqual(self.fft.axes, (1,))

        new_fft = FFTW(self.input_array, self.output_array, axes=(-1, -2))
        self.assertEqual(new_fft.axes, (1, 0))

        new_fft = FFTW(self.input_array, self.output_array, axes=(-2, -1))
        self.assertEqual(new_fft.axes, (0, 1))

        new_fft = FFTW(self.input_array, self.output_array, axes=(1, 0))
        self.assertEqual(new_fft.axes, (1, 0))

        new_fft = FFTW(self.input_array, self.output_array, axes=(1,))
        self.assertEqual(new_fft.axes, (1,))

        new_fft = FFTW(self.input_array, self.output_array, axes=(0,))
        self.assertEqual(new_fft.axes, (0,))
コード例 #38
0
 def do_fft(self, inputa):
   outputa = np.zeros(self.fft_size, dtype=complex)
   fft_plan = FFTW(inputa, outputa, direction='FFTW_FORWARD')
   #fft_plan = FFTW.Plan(inputa, outputa, direction='forward', flags=['estimate'])
   fft_plan.execute()
   return (np.log10(np.abs(outputa)) * 20)[:self.fft_size/2]
コード例 #39
0
    def run_validate_fft(self, a, b, axes, fft=None, ifft=None,
            force_unaligned_data=False, create_array_copies=True,
            threads=1, flags=('FFTW_ESTIMATE',)):
        ''' *** EVERYTHING IS FLIPPED AROUND BECAUSE WE ARE
        VALIDATING AN INVERSE FFT ***

        Run a validation of the FFTW routines for the passed pair
        of arrays, a and b, and the axes argument.

        a and b are assumed to be the same shape (but not necessarily
        the same layout in memory).

        fft and ifft, if passed, should be instantiated FFTW objects.

        If force_unaligned_data is True, the flag FFTW_UNALIGNED
        will be passed to the fftw routines.
        '''
        if create_array_copies:
            # Don't corrupt the original mutable arrays
            a = a.copy()
            b = b.copy()

        a_orig = a.copy()

        flags = list(flags)

        if force_unaligned_data:
            flags.append('FFTW_UNALIGNED')

        if ifft == None:
            ifft = FFTW(a, b, axes=axes, direction='FFTW_BACKWARD',
                    flags=flags, threads=threads)
        else:
            ifft.update_arrays(a,b)

        if fft == None:
            fft = FFTW(b, a, axes=axes, direction='FFTW_FORWARD',
                    flags=flags, threads=threads)
        else:
            fft.update_arrays(b,a)


        a[:] = a_orig
        # Test the inverse FFT by comparing it to the result from numpy.fft
        ifft.execute()

        a[:] = a_orig
        ref_b = self.reference_fftn(a, axes=axes)

        # The scaling is the product of the lengths of the fft along
        # the axes along which the fft is taken.
        scaling = numpy.prod(numpy.array(b.shape)[list(axes)])
        self.assertEqual(ifft.N, scaling)
        self.assertEqual(fft.N, scaling)

        # This is actually quite a poor relative error, but it still
        # sometimes fails. I assume that numpy.fft has different internals
        # to fftw.
        self.assertTrue(numpy.allclose(b/scaling, ref_b, rtol=1e-2, atol=1e-3))

        # Test the FFT by comparing the result to the starting
        # value (which is scaled as per FFTW being unnormalised).
        fft.execute()

        self.assertTrue(numpy.allclose(a/scaling, a_orig, rtol=1e-2, atol=1e-3))
        return fft, ifft