| import operator |
|
|
| import numpy as np |
| from numpy.fft import fftshift, ifftshift, fftfreq |
|
|
| import scipy.fft._pocketfft.helper as _helper |
|
|
| __all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq', 'next_fast_len'] |
|
|
|
|
| def rfftfreq(n, d=1.0): |
| """DFT sample frequencies (for usage with rfft, irfft). |
| |
| The returned float array contains the frequency bins in |
| cycles/unit (with zero at the start) given a window length `n` and a |
| sample spacing `d`:: |
| |
| f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2]/(d*n) if n is even |
| f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2,n/2]/(d*n) if n is odd |
| |
| Parameters |
| ---------- |
| n : int |
| Window length. |
| d : scalar, optional |
| Sample spacing. Default is 1. |
| |
| Returns |
| ------- |
| out : ndarray |
| The array of length `n`, containing the sample frequencies. |
| |
| Examples |
| -------- |
| >>> import numpy as np |
| >>> from scipy import fftpack |
| >>> sig = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float) |
| >>> sig_fft = fftpack.rfft(sig) |
| >>> n = sig_fft.size |
| >>> timestep = 0.1 |
| >>> freq = fftpack.rfftfreq(n, d=timestep) |
| >>> freq |
| array([ 0. , 1.25, 1.25, 2.5 , 2.5 , 3.75, 3.75, 5. ]) |
| |
| """ |
| n = operator.index(n) |
| if n < 0: |
| raise ValueError(f"n = {n} is not valid. " |
| "n must be a nonnegative integer.") |
|
|
| return (np.arange(1, n + 1, dtype=int) // 2) / float(n * d) |
|
|
|
|
| def next_fast_len(target): |
| """ |
| Find the next fast size of input data to `fft`, for zero-padding, etc. |
| |
| SciPy's FFTPACK has efficient functions for radix {2, 3, 4, 5}, so this |
| returns the next composite of the prime factors 2, 3, and 5 which is |
| greater than or equal to `target`. (These are also known as 5-smooth |
| numbers, regular numbers, or Hamming numbers.) |
| |
| Parameters |
| ---------- |
| target : int |
| Length to start searching from. Must be a positive integer. |
| |
| Returns |
| ------- |
| out : int |
| The first 5-smooth number greater than or equal to `target`. |
| |
| Notes |
| ----- |
| .. versionadded:: 0.18.0 |
| |
| Examples |
| -------- |
| On a particular machine, an FFT of prime length takes 133 ms: |
| |
| >>> from scipy import fftpack |
| >>> import numpy as np |
| >>> rng = np.random.default_rng() |
| >>> min_len = 10007 # prime length is worst case for speed |
| >>> a = rng.standard_normal(min_len) |
| >>> b = fftpack.fft(a) |
| |
| Zero-padding to the next 5-smooth length reduces computation time to |
| 211 us, a speedup of 630 times: |
| |
| >>> fftpack.next_fast_len(min_len) |
| 10125 |
| >>> b = fftpack.fft(a, 10125) |
| |
| Rounding up to the next power of 2 is not optimal, taking 367 us to |
| compute, 1.7 times as long as the 5-smooth size: |
| |
| >>> b = fftpack.fft(a, 16384) |
| |
| """ |
| |
| return _helper.good_size(target, True) |
|
|
|
|
| def _good_shape(x, shape, axes): |
| """Ensure that shape argument is valid for scipy.fftpack |
| |
| scipy.fftpack does not support len(shape) < x.ndim when axes is not given. |
| """ |
| if shape is not None and axes is None: |
| shape = _helper._iterable_of_int(shape, 'shape') |
| if len(shape) != np.ndim(x): |
| raise ValueError("when given, axes and shape arguments" |
| " have to be of the same length") |
| return shape |
|
|