bundles / scipy latest / scipy / signal / _short_time_fft / closest_STFT_dual_window
function
scipy.signal._short_time_fft:closest_STFT_dual_window
Signature
def closest_STFT_dual_window ( win : np.ndarray , hop : int , desired_dual : np.ndarray | None = None , * , scaled : bool = True ) → tuple[np.ndarray, float | complex] Summary
Calculate the STFT dual window of a given window closest to a desired dual window.
Extended Summary
For a given short-time Fourier transform window win incremented by hop samples, the dual window is calculated, which minimizes abs(dual_win - desired_dual)**2 when scaled is False. For scaled set to True, abs(alpha*dual_win - desired_dual)**2 is minimized with alpha being the optimal scaling factor. A ValueError is raised if no valid dual window can be determined.
Parameters
win: np.ndarrayThe window must be a real- or complex-valued 1d array.
hop: intThe increment in samples by which the window is shifted in each step.
desired_dual: np.ndarray | NoneThe desired dual window must be a 1d array of the same length as
win. If set toNone(default), thendesired_dualis assumed to be the rectangular window, i.e.,np.ones_like(win).scaled: boolIf set (default), the closest scaled version instead of closest dual window is calculated.
Returns
dual_win: np.ndarrayA dual window of
alpha*win(with hop intervalhop), which is closest todesired_dual. Note that the dual window ofwinisdual_win/alphaand that the dual window of dual_win isalpha*win. dual_win has the same shape aswinanddesired_win.alpha: float | complexScale factor for
win. It is always one ifscaledis set toFalse.
Notes
For a given window and hop interval, all possible dual windows are expressed by the hop linear conditions of Eq. eq_STFT_AllDualWinsCond in the tutorial_stft section of the user_guide. Hence, decreasing hop, increases the number of degrees of freedom of the set of all possible dual windows, improving the ability to better approximate a desired_dual.
This function can also be used to determine windows which fulfill the so-called "Constant OverLap Add" (COLA) condition [1]. It states that summing all touching window values at any given sample position results in the same constant . Eq. eq_STFT_AllDualWinsCond shows that this is equal to having a rectangular dual window, i.e., the dual being alpha*np.ones(m).
Some examples of windows that satisfy COLA (taken from [2]):
Rectangular window at overlap of 0, 1/2, 2/3, 3/4, ...
Bartlett window at overlap of 1/2, 3/4, 5/6, ...
Hann window at 1/2, 2/3, 3/4, ...
Any Blackman family window at 2/3 overlap
Any window with
hop=1
Array API Standard Support
closest_STFT_dual_window has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable SCIPY_ARRAY_API=1 and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.
==================== ==================== ==================== Library CPU GPU ==================== ==================== ==================== NumPy ✅ n/a CuPy n/a ⛔ PyTorch ⛔ ⛔ JAX ⛔ ⛔ Dask ⛔ n/a ==================== ==================== ====================
See
dev-arrayapifor more information.
Examples
Let's show that a Bartlett window with 75% overlap fulfills the COLA condition:import matplotlib.pyplot as plt import numpy as np from scipy.signal import closest_STFT_dual_window, windows m = 24 win, w_rect = windows.bartlett(m, sym=False), np.ones(m) d_win, alpha = closest_STFT_dual_window(win, m//4, w_rect, scaled=True) print(f"COLA: {np.allclose(d_win, w_rect*alpha)}, {alpha = :g}")✓
hops, deviations, alphas = np.arange(1, 16, dtype=int), [], [] for h_ in hops: w_cola, alpha = closest_STFT_dual_window(w_rect, h_, win, scaled=True) deviations.append(np.linalg.norm(w_cola - win*alpha)) alphas.append(alpha) fg0, (ax0, ax1) = plt.subplots(2, 1, sharex='all', tight_layout=True)✓
ax0.set_title(f"COLA Window closest to a {m}-Sample Bartlett Window") ax0.set(ylabel=r"$||w_\text{cola}-\alpha w||$", xlim=(0, hops[-1]-.5)) ax1.set(xlabel="Hop Interval", ylabel=r"Scaling factor $\alpha$", ylim=(0, 1.25)) ax0.plot(hops, deviations, 'C0.-') ax1.plot(hops, alphas, 'C1.-')✗
for ax_ in (ax0, ax1): ax_.grid() plt.show()✓

See also
- ShortTimeFFT
Short-time Fourier transform which is able to utilize a dual window for calculating the inverse.
- ShortTimeFFT.from_win_equals_dual
Create instance where the window and its dual are equal.
Aliases
-
scipy.signal.closest_STFT_dual_window