diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/numeric.py | 24 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 53 | ||||
-rw-r--r-- | numpy/fft/fftpack.py | 150 | ||||
-rw-r--r-- | numpy/fft/info.py | 10 | ||||
-rw-r--r-- | numpy/fft/tests/test_fftpack.py | 97 | ||||
-rw-r--r-- | numpy/lib/npyio.py | 41 |
6 files changed, 240 insertions, 135 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index eb92d7f52..f29b750f6 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -830,7 +830,7 @@ def _mode_from_name(mode): return _mode_from_name_dict[mode.lower()[0]] return mode -def correlate(a, v, mode='valid', old_behavior=False): +def correlate(a, v, mode='valid'): """ Cross-correlation of two 1-dimensional sequences. @@ -850,10 +850,8 @@ def correlate(a, v, mode='valid', old_behavior=False): Refer to the `convolve` docstring. Note that the default is `valid`, unlike `convolve`, which uses `full`. old_behavior : bool - If True, uses the old behavior from Numeric, - (correlate(a,v) == correlate(v,a), and the conjugate is not taken - for complex arrays). If False, uses the conventional signal - processing definition. + `old_behavior` was removed in NumPy 1.10. If you need the old + behavior, use `multiarray.correlate`. Returns ------- @@ -863,6 +861,7 @@ def correlate(a, v, mode='valid', old_behavior=False): See Also -------- convolve : Discrete, linear convolution of two one-dimensional sequences. + multiarray.correlate : Old, no conjugate, version of correlate. Notes ----- @@ -896,20 +895,7 @@ def correlate(a, v, mode='valid', old_behavior=False): """ mode = _mode_from_name(mode) -# the old behavior should be made available under a different name, see thread -# http://thread.gmane.org/gmane.comp.python.numeric.general/12609/focus=12630 - if old_behavior: - # 2009-07-18 Cannot remove without replacement function. - warnings.warn(""" -The old behavior of correlate was deprecated for 1.4.0, and will be completely removed -for NumPy 2.0. - -The new behavior fits the conventional definition of correlation: inputs are -never swapped, and the second argument is conjugated for complex arrays.""", - DeprecationWarning) - return multiarray.correlate(a, v, mode) - else: - return multiarray.correlate2(a, v, mode) + return multiarray.correlate2(a, v, mode) def convolve(a,v,mode='full'): """ diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index 7400366ac..c39900ffa 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -980,6 +980,7 @@ class TestBinaryRepr(TestCase): assert_equal(binary_repr(-1), '-1') assert_equal(binary_repr(-1, width=8), '11111111') + class TestBaseRepr(TestCase): def test_base3(self): assert_equal(base_repr(3**5, 3), '100000') @@ -1946,7 +1947,7 @@ class TestLikeFuncs(TestCase): self.check_like_function(np.full_like, 123.456, True) self.check_like_function(np.full_like, np.inf, True) -class _TestCorrelate(TestCase): +class TestCorrelate(TestCase): def _setup(self, dt): self.x = np.array([1, 2, 3, 4, 5], dtype=dt) self.xs = np.arange(1, 20)[::3] @@ -1961,24 +1962,24 @@ class _TestCorrelate(TestCase): def test_float(self): self._setup(np.float) - z = np.correlate(self.x, self.y, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.x, self.y, 'full') assert_array_almost_equal(z, self.z1) - z = np.correlate(self.x, self.y[:-1], 'full', old_behavior=self.old_behavior) + z = np.correlate(self.x, self.y[:-1], 'full') assert_array_almost_equal(z, self.z1_4) - z = np.correlate(self.y, self.x, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.y, self.x, 'full') assert_array_almost_equal(z, self.z2) - z = np.correlate(self.x[::-1], self.y, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.x[::-1], self.y, 'full') assert_array_almost_equal(z, self.z1r) - z = np.correlate(self.y, self.x[::-1], 'full', old_behavior=self.old_behavior) + z = np.correlate(self.y, self.x[::-1], 'full') assert_array_almost_equal(z, self.z2r) - z = np.correlate(self.xs, self.y, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.xs, self.y, 'full') assert_array_almost_equal(z, self.zs) def test_object(self): self._setup(Decimal) - z = np.correlate(self.x, self.y, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.x, self.y, 'full') assert_array_almost_equal(z, self.z1) - z = np.correlate(self.y, self.x, 'full', old_behavior=self.old_behavior) + z = np.correlate(self.y, self.x, 'full') assert_array_almost_equal(z, self.z2) def test_no_overwrite(self): @@ -1988,45 +1989,15 @@ class _TestCorrelate(TestCase): assert_array_equal(d, np.ones(100)) assert_array_equal(k, np.ones(3)) -class TestCorrelate(_TestCorrelate): - old_behavior = True - def _setup(self, dt): - # correlate uses an unconventional definition so that correlate(a, b) - # == correlate(b, a), so force the corresponding outputs to be the same - # as well - _TestCorrelate._setup(self, dt) - self.z2 = self.z1 - self.z2r = self.z1r - - @dec.deprecated() - def test_complex(self): - x = np.array([1, 2, 3, 4+1j], dtype=np.complex) - y = np.array([-1, -2j, 3+1j], dtype=np.complex) - r_z = np.array([3+1j, 6, 8-1j, 9+1j, -1-8j, -4-1j], dtype=np.complex) - z = np.correlate(x, y, 'full', old_behavior=self.old_behavior) - assert_array_almost_equal(z, r_z) - - @dec.deprecated() - def test_float(self): - _TestCorrelate.test_float(self) - - @dec.deprecated() - def test_object(self): - _TestCorrelate.test_object(self) - -class TestCorrelateNew(_TestCorrelate): - old_behavior = False def test_complex(self): x = np.array([1, 2, 3, 4+1j], dtype=np.complex) y = np.array([-1, -2j, 3+1j], dtype=np.complex) r_z = np.array([3-1j, 6, 8+1j, 11+5j, -5+8j, -4-1j], dtype=np.complex) - #z = np.acorrelate(x, y, 'full') - #assert_array_almost_equal(z, r_z) - r_z = r_z[::-1].conjugate() - z = np.correlate(y, x, 'full', old_behavior=self.old_behavior) + z = correlate(y, x, mode='full') assert_array_almost_equal(z, r_z) + class TestConvolve(TestCase): def test_object(self): d = [1.] * 100 diff --git a/numpy/fft/fftpack.py b/numpy/fft/fftpack.py index e12ae1eec..4ad4f6802 100644 --- a/numpy/fft/fftpack.py +++ b/numpy/fft/fftpack.py @@ -35,7 +35,8 @@ from __future__ import division, absolute_import, print_function __all__ = ['fft', 'ifft', 'rfft', 'irfft', 'hfft', 'ihfft', 'rfftn', 'irfftn', 'rfft2', 'irfft2', 'fft2', 'ifft2', 'fftn', 'ifftn'] -from numpy.core import array, asarray, zeros, swapaxes, shape, conjugate, take +from numpy.core import (array, asarray, zeros, swapaxes, shape, conjugate, + take, sqrt) from . import fftpack_lite as fftpack _fft_cache = {} @@ -50,7 +51,8 @@ def _raw_fft(a, n=None, axis=-1, init_function=fftpack.cffti, n = a.shape[axis] if n < 1: - raise ValueError("Invalid number of FFT data points (%d) specified." % n) + raise ValueError("Invalid number of FFT data points (%d) specified." + % n) try: # Thread-safety note: We rely on list.pop() here to atomically @@ -88,7 +90,14 @@ def _raw_fft(a, n=None, axis=-1, init_function=fftpack.cffti, return r -def fft(a, n=None, axis=-1): +def _unitary(norm): + if norm not in (None, "ortho"): + raise ValueError("Invalid norm value %s, should be None or \"ortho\"." + % norm) + return norm is not None + + +def fft(a, n=None, axis=-1, norm=None): """ Compute the one-dimensional discrete Fourier Transform. @@ -108,6 +117,9 @@ def fft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the FFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -171,10 +183,16 @@ def fft(a, n=None, axis=-1): """ - return _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftf, _fft_cache) + a = asarray(a).astype(complex) + if n is None: + n = a.shape[axis] + output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftf, _fft_cache) + if _unitary(norm): + output *= 1 / sqrt(n) + return output -def ifft(a, n=None, axis=-1): +def ifft(a, n=None, axis=-1, norm=None): """ Compute the one-dimensional inverse discrete Fourier Transform. @@ -203,6 +221,9 @@ def ifft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the inverse DFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -251,11 +272,13 @@ def ifft(a, n=None, axis=-1): # The copy may be required for multithreading. a = array(a, copy=True, dtype=complex) if n is None: - n = shape(a)[axis] - return _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftb, _fft_cache) / n + n = a.shape[axis] + unitary = _unitary(norm) + output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftb, _fft_cache) + return output * (1 / (sqrt(n) if unitary else n)) -def rfft(a, n=None, axis=-1): +def rfft(a, n=None, axis=-1, norm=None): """ Compute the one-dimensional discrete Fourier Transform for real input. @@ -275,6 +298,9 @@ def rfft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the FFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -331,10 +357,14 @@ def rfft(a, n=None, axis=-1): """ # The copy may be required for multithreading. a = array(a, copy=True, dtype=float) - return _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftf, _real_fft_cache) + output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftf, + _real_fft_cache) + if _unitary(norm): + output *= 1 / sqrt(a.shape[axis]) + return output -def irfft(a, n=None, axis=-1): +def irfft(a, n=None, axis=-1, norm=None): """ Compute the inverse of the n-point DFT for real input. @@ -362,6 +392,9 @@ def irfft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the inverse FFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -413,12 +446,14 @@ def irfft(a, n=None, axis=-1): # The copy may be required for multithreading. a = array(a, copy=True, dtype=complex) if n is None: - n = (shape(a)[axis] - 1) * 2 - return _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftb, - _real_fft_cache) / n + n = (a.shape[axis] - 1) * 2 + unitary = _unitary(norm) + output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftb, + _real_fft_cache) + return output * (1 / (sqrt(n) if unitary else n)) -def hfft(a, n=None, axis=-1): +def hfft(a, n=None, axis=-1, norm=None): """ Compute the FFT of a signal which has Hermitian symmetry (real spectrum). @@ -435,6 +470,9 @@ def hfft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the FFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -487,11 +525,12 @@ def hfft(a, n=None, axis=-1): # The copy may be required for multithreading. a = array(a, copy=True, dtype=complex) if n is None: - n = (shape(a)[axis] - 1) * 2 - return irfft(conjugate(a), n, axis) * n + n = (a.shape[axis] - 1) * 2 + unitary = _unitary(norm) + return irfft(conjugate(a), n, axis) * (sqrt(n) if unitary else n) -def ihfft(a, n=None, axis=-1): +def ihfft(a, n=None, axis=-1, norm=None): """ Compute the inverse FFT of a signal which has Hermitian symmetry. @@ -508,6 +547,9 @@ def ihfft(a, n=None, axis=-1): axis : int, optional Axis over which to compute the inverse FFT. If not given, the last axis is used. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -541,8 +583,10 @@ def ihfft(a, n=None, axis=-1): # The copy may be required for multithreading. a = array(a, copy=True, dtype=float) if n is None: - n = shape(a)[axis] - return conjugate(rfft(a, n, axis))/n + n = a.shape[axis] + unitary = _unitary(norm) + output = conjugate(rfft(a, n, axis)) + return output * (1 / (sqrt(n) if unitary else n)) def _cook_nd_args(a, s=None, axes=None, invreal=0): @@ -564,17 +608,17 @@ def _cook_nd_args(a, s=None, axes=None, invreal=0): return s, axes -def _raw_fftnd(a, s=None, axes=None, function=fft): +def _raw_fftnd(a, s=None, axes=None, function=fft, norm=None): a = asarray(a) s, axes = _cook_nd_args(a, s, axes) itl = list(range(len(axes))) itl.reverse() for ii in itl: - a = function(a, n=s[ii], axis=axes[ii]) + a = function(a, n=s[ii], axis=axes[ii], norm=norm) return a -def fftn(a, s=None, axes=None): +def fftn(a, s=None, axes=None, norm=None): """ Compute the N-dimensional discrete Fourier Transform. @@ -599,6 +643,9 @@ def fftn(a, s=None, axes=None): axes are used, or all axes if `s` is also not specified. Repeated indices in `axes` means that the transform over that axis is performed multiple times. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -664,9 +711,10 @@ def fftn(a, s=None, axes=None): """ - return _raw_fftnd(a, s, axes, fft) + return _raw_fftnd(a, s, axes, fft, norm) + -def ifftn(a, s=None, axes=None): +def ifftn(a, s=None, axes=None, norm=None): """ Compute the N-dimensional inverse discrete Fourier Transform. @@ -700,6 +748,9 @@ def ifftn(a, s=None, axes=None): axes are used, or all axes if `s` is also not specified. Repeated indices in `axes` means that the inverse transform over that axis is performed multiple times. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -756,10 +807,10 @@ def ifftn(a, s=None, axes=None): """ - return _raw_fftnd(a, s, axes, ifft) + return _raw_fftnd(a, s, axes, ifft, norm) -def fft2(a, s=None, axes=(-2, -1)): +def fft2(a, s=None, axes=(-2, -1), norm=None): """ Compute the 2-dimensional discrete Fourier Transform @@ -785,6 +836,9 @@ def fft2(a, s=None, axes=(-2, -1)): axes are used. A repeated index in `axes` means the transform over that axis is performed multiple times. A one-element sequence means that a one-dimensional FFT is performed. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -842,10 +896,10 @@ def fft2(a, s=None, axes=(-2, -1)): """ - return _raw_fftnd(a, s, axes, fft) + return _raw_fftnd(a, s, axes, fft, norm) -def ifft2(a, s=None, axes=(-2, -1)): +def ifft2(a, s=None, axes=(-2, -1), norm=None): """ Compute the 2-dimensional inverse discrete Fourier Transform. @@ -878,6 +932,9 @@ def ifft2(a, s=None, axes=(-2, -1)): axes are used. A repeated index in `axes` means the transform over that axis is performed multiple times. A one-element sequence means that a one-dimensional FFT is performed. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -925,10 +982,10 @@ def ifft2(a, s=None, axes=(-2, -1)): """ - return _raw_fftnd(a, s, axes, ifft) + return _raw_fftnd(a, s, axes, ifft, norm) -def rfftn(a, s=None, axes=None): +def rfftn(a, s=None, axes=None, norm=None): """ Compute the N-dimensional discrete Fourier Transform for real input. @@ -954,6 +1011,9 @@ def rfftn(a, s=None, axes=None): axes : sequence of ints, optional Axes over which to compute the FFT. If not given, the last ``len(s)`` axes are used, or all axes if `s` is also not specified. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -1010,12 +1070,13 @@ def rfftn(a, s=None, axes=None): # The copy may be required for multithreading. a = array(a, copy=True, dtype=float) s, axes = _cook_nd_args(a, s, axes) - a = rfft(a, s[-1], axes[-1]) + a = rfft(a, s[-1], axes[-1], norm) for ii in range(len(axes)-1): - a = fft(a, s[ii], axes[ii]) + a = fft(a, s[ii], axes[ii], norm) return a -def rfft2(a, s=None, axes=(-2, -1)): + +def rfft2(a, s=None, axes=(-2, -1), norm=None): """ Compute the 2-dimensional FFT of a real array. @@ -1027,6 +1088,9 @@ def rfft2(a, s=None, axes=(-2, -1)): Shape of the FFT. axes : sequence of ints, optional Axes over which to compute the FFT. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -1045,9 +1109,10 @@ def rfft2(a, s=None, axes=(-2, -1)): """ - return rfftn(a, s, axes) + return rfftn(a, s, axes, norm) -def irfftn(a, s=None, axes=None): + +def irfftn(a, s=None, axes=None, norm=None): """ Compute the inverse of the N-dimensional FFT of real input. @@ -1080,6 +1145,9 @@ def irfftn(a, s=None, axes=None): `len(s)` axes are used, or all axes if `s` is also not specified. Repeated indices in `axes` means that the inverse transform over that axis is performed multiple times. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -1132,11 +1200,12 @@ def irfftn(a, s=None, axes=None): a = array(a, copy=True, dtype=complex) s, axes = _cook_nd_args(a, s, axes, invreal=1) for ii in range(len(axes)-1): - a = ifft(a, s[ii], axes[ii]) - a = irfft(a, s[-1], axes[-1]) + a = ifft(a, s[ii], axes[ii], norm) + a = irfft(a, s[-1], axes[-1], norm) return a -def irfft2(a, s=None, axes=(-2, -1)): + +def irfft2(a, s=None, axes=(-2, -1), norm=None): """ Compute the 2-dimensional inverse FFT of a real array. @@ -1149,6 +1218,9 @@ def irfft2(a, s=None, axes=(-2, -1)): axes : sequence of ints, optional The axes over which to compute the inverse fft. Default is the last two axes. + norm : {None, "ortho"}, optional + .. versionadded:: 1.10.0 + Normalization mode (see `numpy.fft`). Default is None. Returns ------- @@ -1166,4 +1238,4 @@ def irfft2(a, s=None, axes=(-2, -1)): """ - return irfftn(a, s, axes) + return irfftn(a, s, axes, norm) diff --git a/numpy/fft/info.py b/numpy/fft/info.py index 916d452f2..f7fc95453 100644 --- a/numpy/fft/info.py +++ b/numpy/fft/info.py @@ -116,7 +116,15 @@ The inverse DFT is defined as \\qquad m = 0,\\ldots,n-1. It differs from the forward transform by the sign of the exponential -argument and the normalization by :math:`1/n`. +argument and the default normalization by :math:`1/n`. + +Normalization +------------- +The default normalization has the direct transforms unscaled and the inverse +transforms are scaled by :math:`1/n`. It is possible to obtain unitary +transforms by setting the keyword argument ``norm`` to ``"ortho"`` (default is +`None`) so that both direct and inverse transforms will be scaled by +:math:`1/\\sqrt{n}`. Real and Hermitian transforms ----------------------------- diff --git a/numpy/fft/tests/test_fftpack.py b/numpy/fft/tests/test_fftpack.py index 45b5ac784..2e6294252 100644 --- a/numpy/fft/tests/test_fftpack.py +++ b/numpy/fft/tests/test_fftpack.py @@ -1,6 +1,7 @@ from __future__ import division, absolute_import, print_function import numpy as np +from numpy.random import random from numpy.testing import TestCase, run_module_suite, assert_array_almost_equal from numpy.testing import assert_array_equal import threading @@ -26,10 +27,100 @@ class TestFFTShift(TestCase): class TestFFT1D(TestCase): - def test_basic(self): - rand = np.random.random - x = rand(30) + 1j*rand(30) + def test_fft(self): + x = random(30) + 1j*random(30) assert_array_almost_equal(fft1(x), np.fft.fft(x)) + assert_array_almost_equal(fft1(x) / np.sqrt(30), + np.fft.fft(x, norm="ortho")) + + def test_ifft(self): + x = random(30) + 1j*random(30) + assert_array_almost_equal(x, np.fft.ifft(np.fft.fft(x))) + assert_array_almost_equal( + x, np.fft.ifft(np.fft.fft(x, norm="ortho"), norm="ortho")) + + def test_fft2(self): + x = random((30, 20)) + 1j*random((30, 20)) + assert_array_almost_equal(np.fft.fft(np.fft.fft(x, axis=1), axis=0), + np.fft.fft2(x)) + assert_array_almost_equal(np.fft.fft2(x) / np.sqrt(30 * 20), + np.fft.fft2(x, norm="ortho")) + + def test_ifft2(self): + x = random((30, 20)) + 1j*random((30, 20)) + assert_array_almost_equal(np.fft.ifft(np.fft.ifft(x, axis=1), axis=0), + np.fft.ifft2(x)) + assert_array_almost_equal(np.fft.ifft2(x) * np.sqrt(30 * 20), + np.fft.ifft2(x, norm="ortho")) + + def test_fftn(self): + x = random((30, 20, 10)) + 1j*random((30, 20, 10)) + assert_array_almost_equal( + np.fft.fft(np.fft.fft(np.fft.fft(x, axis=2), axis=1), axis=0), + np.fft.fftn(x)) + assert_array_almost_equal(np.fft.fftn(x) / np.sqrt(30 * 20 * 10), + np.fft.fftn(x, norm="ortho")) + + def test_ifftn(self): + x = random((30, 20, 10)) + 1j*random((30, 20, 10)) + assert_array_almost_equal( + np.fft.ifft(np.fft.ifft(np.fft.ifft(x, axis=2), axis=1), axis=0), + np.fft.ifftn(x)) + assert_array_almost_equal(np.fft.ifftn(x) * np.sqrt(30 * 20 * 10), + np.fft.ifftn(x, norm="ortho")) + + def test_rfft(self): + x = random(30) + assert_array_almost_equal(np.fft.fft(x)[:16], np.fft.rfft(x)) + assert_array_almost_equal(np.fft.rfft(x) / np.sqrt(30), + np.fft.rfft(x, norm="ortho")) + + def test_irfft(self): + x = random(30) + assert_array_almost_equal(x, np.fft.irfft(np.fft.rfft(x))) + assert_array_almost_equal( + x, np.fft.irfft(np.fft.rfft(x, norm="ortho"), norm="ortho")) + + def test_rfft2(self): + x = random((30, 20)) + assert_array_almost_equal(np.fft.fft2(x)[:, :11], np.fft.rfft2(x)) + assert_array_almost_equal(np.fft.rfft2(x) / np.sqrt(30 * 20), + np.fft.rfft2(x, norm="ortho")) + + def test_irfft2(self): + x = random((30, 20)) + assert_array_almost_equal(x, np.fft.irfft2(np.fft.rfft2(x))) + assert_array_almost_equal( + x, np.fft.irfft2(np.fft.rfft2(x, norm="ortho"), norm="ortho")) + + def test_rfftn(self): + x = random((30, 20, 10)) + assert_array_almost_equal(np.fft.fftn(x)[:, :, :6], np.fft.rfftn(x)) + assert_array_almost_equal(np.fft.rfftn(x) / np.sqrt(30 * 20 * 10), + np.fft.rfftn(x, norm="ortho")) + + def test_irfftn(self): + x = random((30, 20, 10)) + assert_array_almost_equal(x, np.fft.irfftn(np.fft.rfftn(x))) + assert_array_almost_equal( + x, np.fft.irfftn(np.fft.rfftn(x, norm="ortho"), norm="ortho")) + + def test_hfft(self): + x = random(14) + 1j*random(14) + x_herm = np.concatenate((random(1), x, random(1))) + x = np.concatenate((x_herm, x[::-1].conj())) + assert_array_almost_equal(np.fft.fft(x), np.fft.hfft(x_herm)) + assert_array_almost_equal(np.fft.hfft(x_herm) / np.sqrt(30), + np.fft.hfft(x_herm, norm="ortho")) + + def test_ihttf(self): + x = random(14) + 1j*random(14) + x_herm = np.concatenate((random(1), x, random(1))) + x = np.concatenate((x_herm, x[::-1].conj())) + assert_array_almost_equal(x_herm, np.fft.ihfft(np.fft.hfft(x_herm))) + assert_array_almost_equal( + x_herm, np.fft.ihfft(np.fft.hfft(x_herm, norm="ortho"), + norm="ortho")) class TestFFTThreadSafe(TestCase): diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index ac6d46a71..078c6d7ca 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -1301,13 +1301,12 @@ def fromregex(file, regexp, dtype): def genfromtxt(fname, dtype=float, comments='#', delimiter=None, - skiprows=0, skip_header=0, skip_footer=0, converters=None, - missing='', missing_values=None, filling_values=None, - usecols=None, names=None, - excludelist=None, deletechars=None, replace_space='_', - autostrip=False, case_sensitive=True, defaultfmt="f%i", - unpack=None, usemask=False, loose=True, invalid_raise=True, - max_rows=None): + skip_header=0, skip_footer=0, converters=None, + missing_values=None, filling_values=None, usecols=None, + names=None, excludelist=None, deletechars=None, + replace_space='_', autostrip=False, case_sensitive=True, + defaultfmt="f%i", unpack=None, usemask=False, loose=True, + invalid_raise=True, max_rows=None): """ Load data from a text file, with missing values handled as specified. @@ -1332,8 +1331,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None, whitespaces act as delimiter. An integer or sequence of integers can also be provided as width(s) of each field. skiprows : int, optional - `skiprows` was deprecated in numpy 1.5, and will be removed in - numpy 2.0. Please use `skip_header` instead. + `skiprows` was removed in numpy 1.10. Please use `skip_header` instead. skip_header : int, optional The number of lines to skip at the beginning of the file. skip_footer : int, optional @@ -1343,8 +1341,8 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None, The converters can also be used to provide a default value for missing data: ``converters = {3: lambda s: float(s or 0)}``. missing : variable, optional - `missing` was deprecated in numpy 1.5, and will be removed in - numpy 2.0. Please use `missing_values` instead. + `missing` was removed in numpy 1.10. Please use `missing_values` + instead. missing_values : variable, optional The set of strings corresponding to missing data. filling_values : variable, optional @@ -1475,8 +1473,6 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None, comments = asbytes(comments) if isinstance(delimiter, unicode): delimiter = asbytes(delimiter) - if isinstance(missing, unicode): - missing = asbytes(missing) if isinstance(missing_values, (unicode, list, tuple)): missing_values = asbytes_nested(missing_values) @@ -1513,14 +1509,6 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None, case_sensitive=case_sensitive, replace_space=replace_space) - # Get the first valid lines after the first skiprows ones .. - if skiprows: - # 2011-03-06 Cannot remove is keyword. - warnings.warn( - "The use of `skiprows` is deprecated, it will be removed in " - "numpy 2.0.\nPlease use `skip_header` instead.", - DeprecationWarning) - skip_header = skiprows # Skip the first `skip_header` rows for i in range(skip_header): next(fhd) @@ -1649,17 +1637,6 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None, for entry in missing_values: entry.extend([str(user_missing_values)]) - # Process the deprecated `missing` - if missing != asbytes(''): - # 2011-03-06 Cannot remove, is keyword. - warnings.warn( - "The use of `missing` is deprecated, it will be removed in " - "Numpy 2.0.\nPlease use `missing_values` instead.", - DeprecationWarning) - values = [str(_) for _ in missing.split(asbytes(","))] - for entry in missing_values: - entry.extend(values) - # Process the filling_values ............................... # Rename the input for convenience user_filling_values = filling_values |