From 6073bd4f368c10ee7961da93bf5907cdb4392cef Mon Sep 17 00:00:00 2001 From: Henry Gomersall Date: Fri, 10 Jan 2014 18:17:03 +0000 Subject: [PATCH] Added the raw rst docs files to MANIFEST.in to satisfy issue 32 --- MANIFEST.in | 2 +- pyfftw/builders/_utils.py | 6 +- pyfftw/builders/builders.py | 8 +-- pyfftw/interfaces/_utils.py | 4 +- pyfftw/pyfftw.pyx | 116 ++++++++++++++++++++++++++++----- pyfftw/pyfftw.rst | 16 +++++ sphinx/tutorial.rst | 8 +-- test/test_pyfftw_builders.py | 20 +++--- test/test_pyfftw_class_misc.py | 101 +++++++++++++++++++++++++++- 9 files changed, 238 insertions(+), 43 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 991e7908..b2767c26 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,4 +11,4 @@ include pyfftw/utils.pxi include test/test_*.py include test/__init__.py recursive-include include *.h -recursive-include docs *.html *.css *.png *.js +recursive-include docs *.html *.css *.png *.js *.rst diff --git a/pyfftw/builders/_utils.py b/pyfftw/builders/_utils.py index 6e9decbb..0315e69e 100644 --- a/pyfftw/builders/_utils.py +++ b/pyfftw/builders/_utils.py @@ -136,7 +136,7 @@ def _Xfftn(a, s, axes, overwrite_input, FFTW_array_slicer=FFTW_array_slicer) # We copy the data back into the internal FFTW object array - internal_array = FFTW_object.get_input_array() + internal_array = FFTW_object.input_array internal_array[:] = 0 internal_array[FFTW_array_slicer] = ( a_copy[update_input_array_slicer]) @@ -176,7 +176,7 @@ def _Xfftn(a, s, axes, overwrite_input, if not avoid_copy: # Copy the data back into the (likely) destroyed array - FFTW_object.get_input_array()[:] = a_copy + FFTW_object.input_array[:] = a_copy return FFTW_object @@ -231,7 +231,7 @@ def __call__(self, input_array=None, output_array=None, # Do the update here (which is a copy, so it's alignment # safe etc). - internal_input_array = self.get_input_array() + internal_input_array = self.input_array input_array = numpy.asanyarray(input_array) if self._input_destroyed: diff --git a/pyfftw/builders/builders.py b/pyfftw/builders/builders.py index f6c4c05a..939ca236 100644 --- a/pyfftw/builders/builders.py +++ b/pyfftw/builders/builders.py @@ -52,7 +52,7 @@ array that is passed in (due to ``s`` dictating a larger size), then the extra entries are padded with zeros. This is a one time action. If the internal input array is then extracted using -:meth:`pyfftw.FFTW.get_input_array`, it is possible to +:attr:`pyfftw.FFTW.input_array`, it is possible to persistently fill the padding space with whatever the user desires, so subsequent calls with a new input only overwrite the values that aren't padding (even if the array that is used for the call is bigger than the @@ -73,7 +73,7 @@ will be correctly loaded with the values within the input array, it is not necessarily the case that the internal array *is* the input array. The actual internal input array can always be retrieved with -:meth:`pyfftw.FFTW.get_input_array`. +:attr:`pyfftw.FFTW.input_array`. **Example:** @@ -178,7 +178,7 @@ :func:`pyfftw.n_byte_align`). If and only if a realignment is necessary is a new array created. If a new array *is* created, it is up to the calling code to acquire that new input array using - :func:`pyfftw.FFTW.get_input_array`. + :attr:`pyfftw.FFTW.input_array`. The resultant :class:`pyfftw.FFTW` object that is created will be designed to operate on arrays that are aligned. If the object is @@ -207,7 +207,7 @@ Like ``auto_align_input``, If a new array is created, it is up to the calling code to acquire that new input array using - :func:`pyfftw.FFTW.get_input_array`. + :attr:`pyfftw.FFTW.input_array`. * ``avoid_copy``: By default, these functions will always create a copy (and sometimes more than one) of the passed in input array. This is diff --git a/pyfftw/interfaces/_utils.py b/pyfftw/interfaces/_utils.py index 48555e05..3cf1542f 100644 --- a/pyfftw/interfaces/_utils.py +++ b/pyfftw/interfaces/_utils.py @@ -87,7 +87,7 @@ def _Xfftn(a, s, axes, overwrite_input, planner_effort, # Only copy if the input array is what was actually used # (otherwise it shouldn't be overwritten) - if FFTW_object.get_input_array() is a: + if FFTW_object.input_array is a: a[:] = a_copy if cache.is_enabled(): @@ -99,7 +99,7 @@ def _Xfftn(a, s, axes, overwrite_input, planner_effort, if reload_after_transform: a_copy = a.copy() - orig_output_array = FFTW_object.get_output_array() + orig_output_array = FFTW_object.output_array output_shape = orig_output_array.shape output_dtype = orig_output_array.dtype output_alignment = FFTW_object.output_alignment diff --git a/pyfftw/pyfftw.pyx b/pyfftw/pyfftw.pyx index 144fa932..857e469b 100644 --- a/pyfftw/pyfftw.pyx +++ b/pyfftw/pyfftw.pyx @@ -22,6 +22,8 @@ from libc.stdlib cimport calloc, malloc, free from libc.stdint cimport intptr_t, int64_t from libc cimport limits +import warnings + include 'utils.pxi' cdef extern from *: @@ -615,10 +617,10 @@ cdef class FFTW: cdef int _output_array_alignment cdef bint _use_threads + cdef object _input_item_strides cdef object _input_strides - cdef object _input_byte_strides + cdef object _output_item_strides cdef object _output_strides - cdef object _output_byte_strides cdef object _input_shape cdef object _output_shape cdef object _input_dtype @@ -691,6 +693,72 @@ cdef class FFTW: flags = property(_get_flags_used) + def _get_input_array(self): + ''' + Return the input array that is associated with the FFTW + instance. + ''' + return self._input_array + + input_array = property(_get_input_array) + + def _get_output_array(self): + ''' + Return the output array that is associated with the FFTW + instance. + ''' + return self._output_array + + output_array = property(_get_output_array) + + def _get_input_strides(self): + ''' + Return the strides of the input array for which the FFT is planned. + ''' + return self._input_strides + + input_strides = property(_get_input_strides) + + def _get_output_strides(self): + ''' + Return the strides of the output array for which the FFT is planned. + ''' + return self._output_strides + + output_strides = property(_get_output_strides) + + def _get_input_shape(self): + ''' + Return the shape of the input array for which the FFT is planned. + ''' + return self._input_shape + + input_shape = property(_get_input_shape) + + def _get_output_shape(self): + ''' + Return the shape of the output array for which the FFT is planned. + ''' + return self._output_shape + + output_shape = property(_get_output_shape) + + def _get_input_dtype(self): + ''' + Return the dtype of the input array for which the FFT is planned. + ''' + return self._input_dtype + + input_dtype = property(_get_input_dtype) + + def _get_output_dtype(self): + ''' + Return the shape of the output array for which the FFT is planned. + ''' + return self._output_dtype + + output_dtype = property(_get_output_dtype) + def __cinit__(self, input_array, output_array, axes=(-1,), direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), unsigned int threads=1, planning_timelimit=None, @@ -909,12 +977,12 @@ cdef class FFTW: raise MemoryError # Find the strides for all the axes of both arrays in terms of the - # number of elements (as opposed to the number of bytes). - self._input_byte_strides = input_array.strides - self._input_strides = tuple([stride/input_array.itemsize + # number of items (as opposed to the number of bytes). + self._input_strides = input_array.strides + self._input_item_strides = tuple([stride/input_array.itemsize for stride in input_array.strides]) - self._output_byte_strides = output_array.strides - self._output_strides = tuple([stride/output_array.itemsize + self._output_strides = output_array.strides + self._output_item_strides = tuple([stride/output_array.itemsize for stride in output_array.strides]) # Make sure that the arrays are not too big for fftw @@ -926,7 +994,7 @@ cdef class FFTW: raise ValueError('Dimensions of the input array must be ' + 'less than ', str(limits.INT_MAX)) - if self._input_strides[i] >= limits.INT_MAX: + if self._input_item_strides[i] >= limits.INT_MAX: raise ValueError('Strides of the input array must be ' + 'less than ', str(limits.INT_MAX)) @@ -935,7 +1003,7 @@ cdef class FFTW: raise ValueError('Dimensions of the output array must be ' + 'less than ', str(limits.INT_MAX)) - if self._output_strides[i] >= limits.INT_MAX: + if self._output_item_strides[i] >= limits.INT_MAX: raise ValueError('Strides of the output array must be ' + 'less than ', str(limits.INT_MAX)) @@ -946,8 +1014,8 @@ cdef class FFTW: fft_shape = fft_shape_lookup(input_array, output_array) # Fill in the stride and shape information - input_strides_array = self._input_strides - output_strides_array = self._output_strides + input_strides_array = self._input_item_strides + output_strides_array = self._output_item_strides for i in range(0, self._rank): self._dims[i]._n = fft_shape[self._axes[i]] self._dims[i]._is = input_strides_array[self._axes[i]] @@ -1264,7 +1332,7 @@ cdef class FFTW: copy_needed = True elif (not input_array.dtype == self._input_dtype): copy_needed = True - elif (not input_array.strides == self._input_byte_strides): + elif (not input_array.strides == self._input_strides): copy_needed = True elif not (np.PyArray_DATA(input_array) % self.input_alignment == 0): @@ -1374,12 +1442,12 @@ cdef class FFTW: 'The new output array should be the same shape as ' 'the output array used to instantiate the object.') - if not new_input_strides == self._input_byte_strides: + if not new_input_strides == self._input_strides: raise ValueError('Invalid input striding: ' 'The strides should be identical for the new ' 'input array as for the old.') - if not new_output_strides == self._output_byte_strides: + if not new_output_strides == self._output_strides: raise ValueError('Invalid output striding: ' 'The strides should be identical for the new ' 'output array as for the old.') @@ -1399,7 +1467,14 @@ cdef class FFTW: Return the input array that is associated with the FFTW instance. + + *Deprecated since 0.10. Consider using the* :attr:`FFTW.input_array` + *property instead.* ''' + warnings.warn('get_input_array is deprecated. ' + 'Consider using the input_array property instead.', + DeprecationWarning) + return self._input_array def get_output_array(self): @@ -1407,16 +1482,23 @@ cdef class FFTW: Return the output array that is associated with the FFTW instance. + + *Deprecated since 0.10. Consider using the* :attr:`FFTW.output_array` + *property instead.* ''' + warnings.warn('get_output_array is deprecated. ' + 'Consider using the output_array property instead.', + DeprecationWarning) + return self._output_array cpdef execute(self): '''execute() Execute the planned operation, taking the correct kind of FFT of - the input array (what is returned by :meth:`get_input_array`), - and putting the result in the output array (what is returned by - :meth:`get_output_array`). + the input array (i.e. :attr:`FFTW.input_array`), + and putting the result in the output array (i.e. + :attr:`FFTW.output_array`). ''' cdef void *input_pointer = ( np.PyArray_DATA(self._input_array)) diff --git a/pyfftw/pyfftw.rst b/pyfftw/pyfftw.rst index 73477f03..52949d15 100644 --- a/pyfftw/pyfftw.rst +++ b/pyfftw/pyfftw.rst @@ -17,6 +17,22 @@ FFTW Class .. autoattribute:: pyfftw.FFTW.output_alignment .. autoattribute:: pyfftw.FFTW.flags + + .. autoattribute:: pyfftw.FFTW.input_array + + .. autoattribute:: pyfftw.FFTW.output_array + + .. autoattribute:: pyfftw.FFTW.input_shape + + .. autoattribute:: pyfftw.FFTW.output_shape + + .. autoattribute:: pyfftw.FFTW.input_strides + + .. autoattribute:: pyfftw.FFTW.output_strides + + .. autoattribute:: pyfftw.FFTW.input_dtype + + .. autoattribute:: pyfftw.FFTW.output_dtype .. automethod:: pyfftw.FFTW.__call__ diff --git a/sphinx/tutorial.rst b/sphinx/tutorial.rst index 31e1dee1..81d35459 100644 --- a/sphinx/tutorial.rst +++ b/sphinx/tutorial.rst @@ -276,14 +276,14 @@ requirements for updating the array. >>> e = pyfftw.n_byte_align_empty(4, 16, 'complex128') >>> f = pyfftw.n_byte_align_empty(4, 16, 'complex128') >>> fft_object = pyfftw.FFTW(d, e) - >>> fft_object.get_input_array() is d # get the input array from the object + >>> fft_object.input_array is d # get the input array from the object True >>> f[:] = [1, 2, 3, 4] # Add some data to f >>> fft_object(f) array([ 10.+0.j, -2.+2.j, -2.+0.j, -2.-2.j]) - >>> fft_object.get_input_array() is d # No longer true! + >>> fft_object.input_array is d # No longer true! False - >>> fft_object.get_input_array() is f # It has been updated with f :) + >>> fft_object.input_array is f # It has been updated with f :) True If the new input array is of the wrong dtype or wrongly strided, @@ -435,7 +435,7 @@ Inspecting these objects gives us their shapes: >>> b.shape (32, 256) - >>> fft_wrapper_object.get_input_array().shape + >>> fft_wrapper_object.input_array.shape (32, 256) >>> a.shape (128, 64) diff --git a/test/test_pyfftw_builders.py b/test/test_pyfftw_builders.py index b217aca2..04fbe977 100644 --- a/test/test_pyfftw_builders.py +++ b/test/test_pyfftw_builders.py @@ -377,7 +377,7 @@ def test_auto_contiguous_input(self): FFTW_object = getattr(builders, self.func)( input_array, s1, **_kwargs) - internal_input_array = FFTW_object.get_input_array() + internal_input_array = FFTW_object.input_array flags = internal_input_array.flags self.assertTrue(input_array is internal_input_array) self.assertFalse(flags['C_CONTIGUOUS'] or @@ -386,7 +386,7 @@ def test_auto_contiguous_input(self): FFTW_object = getattr(builders, self.func)( input_array, s2, **_kwargs) - internal_input_array = FFTW_object.get_input_array() + internal_input_array = FFTW_object.input_array flags = internal_input_array.flags # We actually expect the _FFTWWrapper to be C_CONTIGUOUS self.assertTrue(flags['C_CONTIGUOUS']) @@ -397,7 +397,7 @@ def test_auto_contiguous_input(self): FFTW_object = getattr(builders, self.func)( input_array, s1, **_kwargs) - internal_input_array = FFTW_object.get_input_array() + internal_input_array = FFTW_object.input_array flags = internal_input_array.flags self.assertTrue(flags['C_CONTIGUOUS'] or flags['F_CONTIGUOUS']) @@ -405,7 +405,7 @@ def test_auto_contiguous_input(self): FFTW_object = getattr(builders, self.func)( input_array, s2, **_kwargs) - internal_input_array = FFTW_object.get_input_array() + internal_input_array = FFTW_object.input_array flags = internal_input_array.flags # as above self.assertTrue(flags['C_CONTIGUOUS']) @@ -498,7 +498,7 @@ def test_persistent_padding(self): FFTW_object = self.validate_pyfftw_object(dtype_tuple[1], test_shape, dtype, s, kwargs) - internal_array = FFTW_object.get_input_array() + internal_array = FFTW_object.input_array padding = internal_array[padding_slicer] # Fill the padding with garbage @@ -509,7 +509,7 @@ def test_persistent_padding(self): # Now confirm that nothing is done to the padding FFTW_object() - final_padding = FFTW_object.get_input_array()[padding_slicer] + final_padding = FFTW_object.input_array[padding_slicer] self.assertTrue(numpy.all(final_padding == initial_padding)) @@ -606,7 +606,7 @@ def test_input_maintained(self): FFTW_object = getattr( builders, self.func)(input_array, s, **kwargs) - final_input_array = FFTW_object.get_input_array() + final_input_array = FFTW_object.input_array self.assertTrue( numpy.alltrue(input_array == final_input_array)) @@ -670,7 +670,7 @@ def test_avoid_copy(self): # A catch all to make sure the internal array # is not a copy - self.assertTrue(FFTW_object.get_input_array() is + self.assertTrue(FFTW_object.input_array is _input_array) @@ -776,8 +776,8 @@ def update_arrays(self, input_array, output_array): '''Does what the internal update arrays does for an FFTW object but with a reslicing. ''' - internal_input_array = self.fft.get_input_array() - internal_output_array = self.fft.get_output_array() + internal_input_array = self.fft.input_array + internal_output_array = self.fft.output_array internal_input_array[self.FFTW_array_slicer] = ( input_array[self.input_array_slicer]) diff --git a/test/test_pyfftw_class_misc.py b/test/test_pyfftw_class_misc.py index 535d0d85..8e08b681 100644 --- a/test/test_pyfftw_class_misc.py +++ b/test/test_pyfftw_class_misc.py @@ -21,6 +21,7 @@ import unittest import numpy +import warnings # FFTW tests that don't seem to fit anywhere else @@ -191,14 +192,110 @@ def test_differing_aligned_arrays_update(self): 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, self.fft.get_input_array()) + 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.assertIs(self.output_array, self.fft.get_output_array()) + self.assertEqual(new_fft.output_dtype, new_output_array.dtype) test_cases = ( FFTWMiscTest,)