update
This commit is contained in:
379
.CondaPkg/env/Lib/site-packages/scipy/fft/_helper.py
vendored
Normal file
379
.CondaPkg/env/Lib/site-packages/scipy/fft/_helper.py
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
from functools import update_wrapper, lru_cache
|
||||
import inspect
|
||||
|
||||
from ._pocketfft import helper as _helper
|
||||
|
||||
import numpy as np
|
||||
from scipy._lib._array_api import array_namespace
|
||||
|
||||
|
||||
def next_fast_len(target, real=False):
|
||||
"""Find the next fast size of input data to ``fft``, for zero-padding, etc.
|
||||
|
||||
SciPy's FFT algorithms gain their speed by a recursive divide and conquer
|
||||
strategy. This relies on efficient functions for small prime factors of the
|
||||
input length. Thus, the transforms are fastest when using composites of the
|
||||
prime factors handled by the fft implementation. If there are efficient
|
||||
functions for all radices <= `n`, then the result will be a number `x`
|
||||
>= ``target`` with only prime factors < `n`. (Also known as `n`-smooth
|
||||
numbers)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : int
|
||||
Length to start searching from. Must be a positive integer.
|
||||
real : bool, optional
|
||||
True if the FFT involves real input or output (e.g., `rfft` or `hfft`
|
||||
but not `fft`). Defaults to False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : int
|
||||
The smallest fast length greater than or equal to ``target``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The result of this function may change in future as performance
|
||||
considerations change, for example, if new prime factors are added.
|
||||
|
||||
Calling `fft` or `ifft` with real input data performs an ``'R2C'``
|
||||
transform internally.
|
||||
|
||||
Examples
|
||||
--------
|
||||
On a particular machine, an FFT of prime length takes 11.4 ms:
|
||||
|
||||
>>> from scipy import fft
|
||||
>>> import numpy as np
|
||||
>>> rng = np.random.default_rng()
|
||||
>>> min_len = 93059 # prime length is worst case for speed
|
||||
>>> a = rng.standard_normal(min_len)
|
||||
>>> b = fft.fft(a)
|
||||
|
||||
Zero-padding to the next regular length reduces computation time to
|
||||
1.6 ms, a speedup of 7.3 times:
|
||||
|
||||
>>> fft.next_fast_len(min_len, real=True)
|
||||
93312
|
||||
>>> b = fft.fft(a, 93312)
|
||||
|
||||
Rounding up to the next power of 2 is not optimal, taking 3.0 ms to
|
||||
compute; 1.9 times longer than the size given by ``next_fast_len``:
|
||||
|
||||
>>> b = fft.fft(a, 131072)
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# Directly wrap the c-function good_size but take the docstring etc., from the
|
||||
# next_fast_len function above
|
||||
_sig = inspect.signature(next_fast_len)
|
||||
next_fast_len = update_wrapper(lru_cache(_helper.good_size), next_fast_len)
|
||||
next_fast_len.__wrapped__ = _helper.good_size
|
||||
next_fast_len.__signature__ = _sig
|
||||
|
||||
|
||||
def prev_fast_len(target, real=False):
|
||||
"""Find the previous fast size of input data to ``fft``.
|
||||
Useful for discarding a minimal number of samples before FFT.
|
||||
|
||||
SciPy's FFT algorithms gain their speed by a recursive divide and conquer
|
||||
strategy. This relies on efficient functions for small prime factors of the
|
||||
input length. Thus, the transforms are fastest when using composites of the
|
||||
prime factors handled by the fft implementation. If there are efficient
|
||||
functions for all radices <= `n`, then the result will be a number `x`
|
||||
<= ``target`` with only prime factors <= `n`. (Also known as `n`-smooth
|
||||
numbers)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target : int
|
||||
Maximum length to search until. Must be a positive integer.
|
||||
real : bool, optional
|
||||
True if the FFT involves real input or output (e.g., `rfft` or `hfft`
|
||||
but not `fft`). Defaults to False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : int
|
||||
The largest fast length less than or equal to ``target``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The result of this function may change in future as performance
|
||||
considerations change, for example, if new prime factors are added.
|
||||
|
||||
Calling `fft` or `ifft` with real input data performs an ``'R2C'``
|
||||
transform internally.
|
||||
|
||||
In the current implementation, prev_fast_len assumes radices of
|
||||
2,3,5,7,11 for complex FFT and 2,3,5 for real FFT.
|
||||
|
||||
Examples
|
||||
--------
|
||||
On a particular machine, an FFT of prime length takes 16.2 ms:
|
||||
|
||||
>>> from scipy import fft
|
||||
>>> import numpy as np
|
||||
>>> rng = np.random.default_rng()
|
||||
>>> max_len = 93059 # prime length is worst case for speed
|
||||
>>> a = rng.standard_normal(max_len)
|
||||
>>> b = fft.fft(a)
|
||||
|
||||
Performing FFT on the maximum fast length less than max_len
|
||||
reduces the computation time to 1.5 ms, a speedup of 10.5 times:
|
||||
|
||||
>>> fft.prev_fast_len(max_len, real=True)
|
||||
92160
|
||||
>>> c = fft.fft(a[:92160]) # discard last 899 samples
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# Directly wrap the c-function prev_good_size but take the docstring etc.,
|
||||
# from the prev_fast_len function above
|
||||
_sig_prev_fast_len = inspect.signature(prev_fast_len)
|
||||
prev_fast_len = update_wrapper(lru_cache()(_helper.prev_good_size), prev_fast_len)
|
||||
prev_fast_len.__wrapped__ = _helper.prev_good_size
|
||||
prev_fast_len.__signature__ = _sig_prev_fast_len
|
||||
|
||||
|
||||
def _init_nd_shape_and_axes(x, shape, axes):
|
||||
"""Handle shape and axes arguments for N-D transforms.
|
||||
|
||||
Returns the shape and axes in a standard form, taking into account negative
|
||||
values and checking for various potential errors.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The input array.
|
||||
shape : int or array_like of ints or None
|
||||
The shape of the result. If both `shape` and `axes` (see below) are
|
||||
None, `shape` is ``x.shape``; if `shape` is None but `axes` is
|
||||
not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
|
||||
If `shape` is -1, the size of the corresponding dimension of `x` is
|
||||
used.
|
||||
axes : int or array_like of ints or None
|
||||
Axes along which the calculation is computed.
|
||||
The default is over all axes.
|
||||
Negative indices are automatically converted to their positive
|
||||
counterparts.
|
||||
|
||||
Returns
|
||||
-------
|
||||
shape : tuple
|
||||
The shape of the result as a tuple of integers.
|
||||
axes : list
|
||||
Axes along which the calculation is computed, as a list of integers.
|
||||
|
||||
"""
|
||||
x = np.asarray(x)
|
||||
return _helper._init_nd_shape_and_axes(x, shape, axes)
|
||||
|
||||
|
||||
def fftfreq(n, d=1.0, *, xp=None, device=None):
|
||||
"""Return the Discrete Fourier Transform sample frequencies.
|
||||
|
||||
The returned float array `f` contains the frequency bin centers in cycles
|
||||
per unit of the sample spacing (with zero at the start). For instance, if
|
||||
the sample spacing is in seconds, then the frequency unit is cycles/second.
|
||||
|
||||
Given a window length `n` and a sample spacing `d`::
|
||||
|
||||
f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even
|
||||
f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int
|
||||
Window length.
|
||||
d : scalar, optional
|
||||
Sample spacing (inverse of the sampling rate). Defaults to 1.
|
||||
xp : array_namespace, optional
|
||||
The namespace for the return array. Default is None, where NumPy is used.
|
||||
device : device, optional
|
||||
The device for the return array.
|
||||
Only valid when `xp.fft.fftfreq` implements the device parameter.
|
||||
|
||||
Returns
|
||||
-------
|
||||
f : ndarray
|
||||
Array of length `n` containing the sample frequencies.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> import scipy.fft
|
||||
>>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
|
||||
>>> fourier = scipy.fft.fft(signal)
|
||||
>>> n = signal.size
|
||||
>>> timestep = 0.1
|
||||
>>> freq = scipy.fft.fftfreq(n, d=timestep)
|
||||
>>> freq
|
||||
array([ 0. , 1.25, 2.5 , ..., -3.75, -2.5 , -1.25])
|
||||
|
||||
"""
|
||||
xp = np if xp is None else xp
|
||||
# numpy does not yet support the `device` keyword
|
||||
# `xp.__name__ != 'numpy'` should be removed when numpy is compatible
|
||||
if hasattr(xp, 'fft') and xp.__name__ != 'numpy':
|
||||
return xp.fft.fftfreq(n, d=d, device=device)
|
||||
if device is not None:
|
||||
raise ValueError('device parameter is not supported for input array type')
|
||||
return np.fft.fftfreq(n, d=d)
|
||||
|
||||
|
||||
def rfftfreq(n, d=1.0, *, xp=None, device=None):
|
||||
"""Return the Discrete Fourier Transform sample frequencies
|
||||
(for usage with rfft, irfft).
|
||||
|
||||
The returned float array `f` contains the frequency bin centers in cycles
|
||||
per unit of the sample spacing (with zero at the start). For instance, if
|
||||
the sample spacing is in seconds, then the frequency unit is cycles/second.
|
||||
|
||||
Given a window length `n` and a sample spacing `d`::
|
||||
|
||||
f = [0, 1, ..., n/2-1, n/2] / (d*n) if n is even
|
||||
f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n) if n is odd
|
||||
|
||||
Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`)
|
||||
the Nyquist frequency component is considered to be positive.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : int
|
||||
Window length.
|
||||
d : scalar, optional
|
||||
Sample spacing (inverse of the sampling rate). Defaults to 1.
|
||||
xp : array_namespace, optional
|
||||
The namespace for the return array. Default is None, where NumPy is used.
|
||||
device : device, optional
|
||||
The device for the return array.
|
||||
Only valid when `xp.fft.rfftfreq` implements the device parameter.
|
||||
|
||||
Returns
|
||||
-------
|
||||
f : ndarray
|
||||
Array of length ``n//2 + 1`` containing the sample frequencies.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> import scipy.fft
|
||||
>>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
|
||||
>>> fourier = scipy.fft.rfft(signal)
|
||||
>>> n = signal.size
|
||||
>>> sample_rate = 100
|
||||
>>> freq = scipy.fft.fftfreq(n, d=1./sample_rate)
|
||||
>>> freq
|
||||
array([ 0., 10., 20., ..., -30., -20., -10.])
|
||||
>>> freq = scipy.fft.rfftfreq(n, d=1./sample_rate)
|
||||
>>> freq
|
||||
array([ 0., 10., 20., 30., 40., 50.])
|
||||
|
||||
"""
|
||||
xp = np if xp is None else xp
|
||||
# numpy does not yet support the `device` keyword
|
||||
# `xp.__name__ != 'numpy'` should be removed when numpy is compatible
|
||||
if hasattr(xp, 'fft') and xp.__name__ != 'numpy':
|
||||
return xp.fft.rfftfreq(n, d=d, device=device)
|
||||
if device is not None:
|
||||
raise ValueError('device parameter is not supported for input array type')
|
||||
return np.fft.rfftfreq(n, d=d)
|
||||
|
||||
|
||||
def fftshift(x, axes=None):
|
||||
"""Shift the zero-frequency component to the center of the spectrum.
|
||||
|
||||
This function swaps half-spaces for all axes listed (defaults to all).
|
||||
Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
Input array.
|
||||
axes : int or shape tuple, optional
|
||||
Axes over which to shift. Default is None, which shifts all axes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
y : ndarray
|
||||
The shifted array.
|
||||
|
||||
See Also
|
||||
--------
|
||||
ifftshift : The inverse of `fftshift`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> freqs = np.fft.fftfreq(10, 0.1)
|
||||
>>> freqs
|
||||
array([ 0., 1., 2., ..., -3., -2., -1.])
|
||||
>>> np.fft.fftshift(freqs)
|
||||
array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.])
|
||||
|
||||
Shift the zero-frequency component only along the second axis:
|
||||
|
||||
>>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
|
||||
>>> freqs
|
||||
array([[ 0., 1., 2.],
|
||||
[ 3., 4., -4.],
|
||||
[-3., -2., -1.]])
|
||||
>>> np.fft.fftshift(freqs, axes=(1,))
|
||||
array([[ 2., 0., 1.],
|
||||
[-4., 3., 4.],
|
||||
[-1., -3., -2.]])
|
||||
|
||||
"""
|
||||
xp = array_namespace(x)
|
||||
if hasattr(xp, 'fft'):
|
||||
return xp.fft.fftshift(x, axes=axes)
|
||||
x = np.asarray(x)
|
||||
y = np.fft.fftshift(x, axes=axes)
|
||||
return xp.asarray(y)
|
||||
|
||||
|
||||
def ifftshift(x, axes=None):
|
||||
"""The inverse of `fftshift`. Although identical for even-length `x`, the
|
||||
functions differ by one sample for odd-length `x`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
Input array.
|
||||
axes : int or shape tuple, optional
|
||||
Axes over which to calculate. Defaults to None, which shifts all axes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
y : ndarray
|
||||
The shifted array.
|
||||
|
||||
See Also
|
||||
--------
|
||||
fftshift : Shift zero-frequency component to the center of the spectrum.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import numpy as np
|
||||
>>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
|
||||
>>> freqs
|
||||
array([[ 0., 1., 2.],
|
||||
[ 3., 4., -4.],
|
||||
[-3., -2., -1.]])
|
||||
>>> np.fft.ifftshift(np.fft.fftshift(freqs))
|
||||
array([[ 0., 1., 2.],
|
||||
[ 3., 4., -4.],
|
||||
[-3., -2., -1.]])
|
||||
|
||||
"""
|
||||
xp = array_namespace(x)
|
||||
if hasattr(xp, 'fft'):
|
||||
return xp.fft.ifftshift(x, axes=axes)
|
||||
x = np.asarray(x)
|
||||
y = np.fft.ifftshift(x, axes=axes)
|
||||
return xp.asarray(y)
|
||||
Reference in New Issue
Block a user