-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Closed
Labels
defectA clear bug or issue that prevents SciPy from being installed or used as expectedA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.signal
Milestone
Description
Describe your issue.
ShortTimeFFT fails with complex input. The following reproduction uses a lightly modified version of the code from the example found in the documentation. The documentation states that the signal input x can be complex:
x
The input signal as real or complex valued array.
Thanks for all the team's efforts on this great project!
Reproducing Code Example
import numpy as np
import math # REZ10101 added
import matplotlib.pyplot as plt
from scipy.signal import ShortTimeFFT
from scipy.signal.windows import gaussian
T_x, N = 1 / 20, 1000 # 20 Hz sampling rate for 50 s signal
t_x = np.arange(N) * T_x # time indexes for signal
f_i = 1 * np.arctan((t_x - t_x[N // 2]) / 2) + 5
sig = 2*np.pi*np.cumsum(f_i)*T_x # REZ10101 split out
x = math.e ** (np.sin(sig) + 1j * np.cos(sig)) # REZ10101 made complex
g_std = 8 # standard deviation for Gaussian window in samples
w = gaussian(50, std=g_std, sym=True) # symmetric Gaussian window
SFT = ShortTimeFFT(w, hop=10, fs=1/T_x, mfft=200, scale_to='magnitude')
Sx = SFT.stft(x) # perform the STFT
fig1, ax1 = plt.subplots(figsize=(6., 4.)) # enlarge plot a bit
t_lo, t_hi = SFT.extent(N)[:2] # time range of plot
ax1.set_title(
rf"STFT ({SFT.m_num*SFT.T:g}$\,s$ Gaussian window, " +
rf"$\sigma_t={g_std*SFT.T}\,$s)"
)
ax1.set(
xlabel=(
f"Time $t$ in seconds ({SFT.p_num(N)} slices, " +
rf"$\Delta t = {SFT.delta_t:g}\,$s)"
),
ylabel=(
f"Freq. $f$ in Hz ({SFT.f_pts} bins, " +
rf"$\Delta f = {SFT.delta_f:g}\,$Hz)"
),
xlim=(t_lo, t_hi)
)
im1 = ax1.imshow(
abs(Sx),
origin='lower',
aspect='auto',
extent=SFT.extent(N),
cmap='viridis'
)
ax1.plot(t_x, f_i, 'r--', alpha=.5, label='$f_i(t)$')
fig1.colorbar(im1, label="Magnitude $|S_x(t, f)|$")
# Shade areas where window slices stick out to the side:
for t0_, t1_ in [(t_lo, SFT.lower_border_end[0] * SFT.T),
(SFT.upper_border_begin(N)[0] * SFT.T, t_hi)]:
ax1.axvspan(t0_, t1_, color='w', linewidth=0, alpha=.2)
for t_ in [0, N * SFT.T]: # mark signal borders with vertical line:
ax1.axvline(t_, color='y', linestyle='--', alpha=0.5)
ax1.legend()
fig1.tight_layout()
plt.show()
Error message
Traceback (most recent call last):
File "/home/zuber/git/test/test_shortTimeFFT.py", line 24, in <module>
Sx = SFT.stft(x) # perform the STFT
^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/signal/_short_time_fft.py", line 795, in stft
return self.stft_detrend(x, None, p0, p1, k_offset=k_offset,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/signal/_short_time_fft.py", line 844, in stft_detrend
S[..., :, p_] = self._fft_func(x_ * self.win.conj())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/signal/_short_time_fft.py", line 1583, in _fft_func
return fft_lib.rfft(x, n=self.mfft, axis=-1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/fft/_backend.py", line 28, in __ua_function__
return fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/fft/_basic_backend.py", line 72, in rfft
return _execute_1D('rfft', _pocketfft.rfft, x, n=n, axis=axis, norm=norm,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/fft/_basic_backend.py", line 28, in _execute_1D
return pocketfft_func(x, n=n, axis=axis, norm=norm,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zuber/git/venv/lib/python3.12/site-packages/scipy/fft/_pocketfft/basic.py", line 53, in r2c
raise TypeError("x must be a real sequence")
TypeError: x must be a real sequence
SciPy/NumPy/Python version and system information
Python 3.12.1 (main, Dec 10 2023, 15:16:41) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, scipy, numpy; print(scipy.__version__, numpy.__version__, sys.version_info); scipy.show_config()
1.12.0 1.26.3 sys.version_info(major=3, minor=12, micro=1, releaselevel='final', serial=0)
/home/zuber/git/venv/lib/python3.12/site-packages/scipy/__config__.py:154: UserWarning: Install `pyyaml` for better output
warnings.warn("Install `pyyaml` for better output", stacklevel=1)
{
"Compilers": {
"c": {
"name": "gcc",
"linker": "ld.bfd",
"version": "10.2.1",
"commands": "cc"
},
"cython": {
"name": "cython",
"linker": "cython",
"version": "3.0.8",
"commands": "cython"
},
"c++": {
"name": "gcc",
"linker": "ld.bfd",
"version": "10.2.1",
"commands": "c++"
},
"fortran": {
"name": "gcc",
"linker": "ld.bfd",
"version": "10.2.1",
"commands": "gfortran"
},
"pythran": {
"version": "0.15.0",
"include directory": "../../tmp/pip-build-env-tfqmvy7q/overlay/lib/python3.12/site-packages/pythran"
}
},
"Machine Information": {
"host": {
"cpu": "x86_64",
"family": "x86_64",
"endian": "little",
"system": "linux"
},
"build": {
"cpu": "x86_64",
"family": "x86_64",
"endian": "little",
"system": "linux"
},
"cross-compiled": false
},
"Build Dependencies": {
"blas": {
"name": "openblas",
"found": true,
"version": "0.3.21.dev",
"detection method": "pkgconfig",
"include directory": "/usr/local/include",
"lib directory": "/usr/local/lib",
"openblas configuration": "USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS= NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= HASWELL MAX_THREADS=2",
"pc file directory": "/usr/local/lib/pkgconfig"
},
"lapack": {
"name": "openblas",
"found": true,
"version": "0.3.21.dev",
"detection method": "pkgconfig",
"include directory": "/usr/local/include",
"lib directory": "/usr/local/lib",
"openblas configuration": "USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS= NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= HASWELL MAX_THREADS=2",
"pc file directory": "/usr/local/lib/pkgconfig"
},
"pybind11": {
"name": "pybind11",
"version": "2.11.1",
"detection method": "config-tool",
"include directory": "unknown"
}
},
"Python Information": {
"path": "/opt/python/cp312-cp312/bin/python",
"version": "3.12"
}
}
Metadata
Metadata
Assignees
Labels
defectA clear bug or issue that prevents SciPy from being installed or used as expectedA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.signal