From b32f27da030d89cf3ea9b801a041819241d9418c Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 11:10:32 +1100 Subject: [PATCH 01/18] `signal`: Add type stubs for `check_NOLA` and `check_COLA`. In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 1c147706..def56a22 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -1,9 +1,15 @@ -from typing import Literal +from typing import Literal, TypeAlias +from typing_extensions import Unpack -from scipy._typing import Untyped, UntypedCallable +import optype as op +from numpy._typing import _ArrayLikeFloat_co +from scipy._typing import AnyInt, AnyReal, Untyped, UntypedCallable +from scipy.signal.windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] +_GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] + def lombscargle(x: Untyped, y: Untyped, freqs: Untyped, precenter: bool = False, normalize: bool = False) -> Untyped: ... def periodogram( x: Untyped, @@ -55,8 +61,18 @@ def spectrogram( axis: int = -1, mode: str = "psd", ) -> Untyped: ... -def check_COLA(window: Untyped, nperseg: int, noverlap: int, tol: float = 1e-10) -> Untyped: ... -def check_NOLA(window: Untyped, nperseg: int, noverlap: int, tol: float = 1e-10) -> Untyped: ... +def check_COLA( + window: _GetWindowArgument | _ArrayLikeFloat_co, + nperseg: AnyInt, + noverlap: AnyInt, + tol: AnyReal = 1e-10, +) -> bool: ... +def check_NOLA( + window: _GetWindowArgument | _ArrayLikeFloat_co, + nperseg: AnyInt, + noverlap: AnyInt, + tol: AnyReal = 1e-10, +) -> bool: ... def stft( x: Untyped, fs: float = 1.0, From f7ba43912000922d74106418f19f10a7e905fd1a Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 11:43:24 +1100 Subject: [PATCH 02/18] `signal`: Add type stubs for function `csd`. In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 36 +++++++++++++++++------------ 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index def56a22..38b80297 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -1,14 +1,20 @@ -from typing import Literal, TypeAlias +from collections.abc import Callable +from typing import Any, Literal, TypeAlias from typing_extensions import Unpack +import numpy as np +import numpy.typing as npt import optype as op -from numpy._typing import _ArrayLikeFloat_co +from numpy._typing import _ArrayLikeComplex_co, _ArrayLikeFloat_co from scipy._typing import AnyInt, AnyReal, Untyped, UntypedCallable from scipy.signal.windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] +_Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] +_Scaling: TypeAlias = Literal["density", "spectrum"] +_Average: TypeAlias = Literal["mean", "median"] def lombscargle(x: Untyped, y: Untyped, freqs: Untyped, precenter: bool = False, normalize: bool = False) -> Untyped: ... def periodogram( @@ -35,19 +41,19 @@ def welch( average: str = "mean", ) -> Untyped: ... def csd( - x: Untyped, - y: Untyped, - fs: float = 1.0, - window: str = "hann", - nperseg: int | None = None, - noverlap: int | None = None, - nfft: int | None = None, - detrend: str | Literal[False] | UntypedCallable = "constant", - return_onesided: bool = True, - scaling: str = "density", - axis: int = -1, - average: str = "mean", -) -> Untyped: ... + x: _ArrayLikeComplex_co, + y: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + return_onesided: op.CanBool = True, + scaling: _Scaling = "density", + axis: op.CanIndex = -1, + average: _Average = "mean", +) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.complexfloating[Any, Any]]]: ... def spectrogram( x: Untyped, fs: float = 1.0, From 58cfd7566098701671692babc2e8df69f2188abb Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 12:11:39 +1100 Subject: [PATCH 03/18] `signal`: Add type stubs for `lombscargle`, `periodogram` and `welch`. In `_spectral_py.pyi`. The `lombscargle` stubs are not up to date with the latest dev branch of scipy. --- scipy-stubs/signal/_spectral_py.pyi | 55 +++++++++++++++++------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 38b80297..1c796a4b 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -11,35 +11,46 @@ from scipy.signal.windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] +_Array_f8_1d: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] + _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] _Scaling: TypeAlias = Literal["density", "spectrum"] _Average: TypeAlias = Literal["mean", "median"] -def lombscargle(x: Untyped, y: Untyped, freqs: Untyped, precenter: bool = False, normalize: bool = False) -> Untyped: ... +# NOTE(pavyamsiri): This function was actually recently updated, adding new arguments and return types. +def lombscargle( + x: _ArrayLikeFloat_co, + y: _ArrayLikeFloat_co, + freqs: _ArrayLikeFloat_co, + precenter: op.CanBool = False, + normalize: op.CanBool = False, +) -> _Array_f8_1d: ... + +# NOTE(pavyamsiri): The docs don't allow `None` for `window` but the body does? def periodogram( - x: Untyped, - fs: float = 1.0, - window: str = "boxcar", - nfft: int | None = None, - detrend: str | Literal[False] | UntypedCallable = "constant", - return_onesided: bool = True, - scaling: str = "density", - axis: int = -1, -) -> Untyped: ... + x: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co | None = "boxcar", + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + return_onesided: op.CanBool = True, + scaling: _Scaling = "density", + axis: op.CanIndex = -1, +) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.floating[Any]]]: ... def welch( - x: Untyped, - fs: float = 1.0, - window: str = "hann", - nperseg: int | None = None, - noverlap: int | None = None, - nfft: int | None = None, - detrend: str | Literal[False] | UntypedCallable = "constant", - return_onesided: bool = True, - scaling: str = "density", - axis: int = -1, - average: str = "mean", -) -> Untyped: ... + x: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + return_onesided: op.CanBool = True, + scaling: _Scaling = "density", + axis: op.CanIndex = -1, + average: _Average = "mean", +) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.floating[Any]]]: ... def csd( x: _ArrayLikeComplex_co, y: _ArrayLikeComplex_co, From 9f24afa8724acc0bfd8c8d3d65d6c37687b7be94 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 12:37:15 +1100 Subject: [PATCH 04/18] `signal`: Add type stubs for `spectrogram`. In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 74 ++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 1c796a4b..766d7a1c 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import Any, Literal, TypeAlias +from typing import Any, Literal, TypeAlias, overload from typing_extensions import Unpack import numpy as np @@ -11,7 +11,10 @@ from scipy.signal.windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] +_Array_f8: TypeAlias = npt.NDArray[np.float64] _Array_f8_1d: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] +_ArrayReal: TypeAlias = npt.NDArray[np.floating[Any]] +_ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] @@ -37,7 +40,7 @@ def periodogram( return_onesided: op.CanBool = True, scaling: _Scaling = "density", axis: op.CanIndex = -1, -) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.floating[Any]]]: ... +) -> tuple[_Array_f8, _ArrayReal]: ... def welch( x: _ArrayLikeComplex_co, fs: AnyReal = 1.0, @@ -50,7 +53,7 @@ def welch( scaling: _Scaling = "density", axis: op.CanIndex = -1, average: _Average = "mean", -) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.floating[Any]]]: ... +) -> tuple[_Array_f8, _ArrayReal]: ... def csd( x: _ArrayLikeComplex_co, y: _ArrayLikeComplex_co, @@ -64,20 +67,59 @@ def csd( scaling: _Scaling = "density", axis: op.CanIndex = -1, average: _Average = "mean", -) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.complexfloating[Any, Any]]]: ... +) -> tuple[_Array_f8, _ArrayComplex]: ... + +# +@overload def spectrogram( - x: Untyped, - fs: float = 1.0, - window: Untyped = ("tukey", 0.25), - nperseg: int | None = None, - noverlap: int | None = None, - nfft: int | None = None, - detrend: str | Literal[False] | UntypedCallable = "constant", - return_onesided: bool = True, - scaling: str = "density", - axis: int = -1, - mode: str = "psd", -) -> Untyped: ... + x: npt.NDArray[np.generic], + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + return_onesided: op.CanBool = True, + scaling: _Scaling = "density", + axis: op.CanIndex = -1, + mode: Literal["psd", "magnitude", "angle", "phase"] = "psd", +) -> tuple[_Array_f8, _Array_f8, _ArrayReal]: ... + +# complex mode (positional) +@overload +def spectrogram( + x: npt.NDArray[np.generic], + fs: AnyReal, + window: _GetWindowArgument | _ArrayLikeFloat_co, + nperseg: AnyInt | None, + noverlap: AnyInt | None, + nfft: AnyInt | None, + detrend: _Detrend, + return_onesided: op.CanBool, + scaling: _Scaling, + axis: op.CanIndex, + mode: Literal["complex"], +) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... + +# complex mode (keyword) + +@overload +def spectrogram( + x: npt.NDArray[np.generic], + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + return_onesided: op.CanBool = True, + scaling: _Scaling = "density", + axis: op.CanIndex = -1, + *, + mode: Literal["complex"], +) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... + +# def check_COLA( window: _GetWindowArgument | _ArrayLikeFloat_co, nperseg: AnyInt, From 3c30e058a20e032316a3acf59bb8f612cf1b4880 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 12:37:45 +1100 Subject: [PATCH 05/18] tests: Add type test for `spectrogram` from the `signal` module. This is because of the overloads. --- tests/signal/test_spectral.pyi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/signal/test_spectral.pyi diff --git a/tests/signal/test_spectral.pyi b/tests/signal/test_spectral.pyi new file mode 100644 index 00000000..7781f746 --- /dev/null +++ b/tests/signal/test_spectral.pyi @@ -0,0 +1,22 @@ +from typing import Any, TypeAlias +from typing_extensions import assert_type + +import numpy as np +import numpy.typing as npt +from scipy.signal import spectrogram + +_Array_f8: TypeAlias = npt.NDArray[np.float64] +_ArrayReal: TypeAlias = npt.NDArray[np.floating[Any]] +_ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] + +# test spectrogram function overloads +assert_type(spectrogram(np.linspace(200, 300, 256)), tuple[_Array_f8, _Array_f8, _ArrayReal]) +assert_type(spectrogram(np.linspace(200, 300, 256), mode="psd"), tuple[_Array_f8, _Array_f8, _ArrayReal]) +assert_type(spectrogram(np.linspace(200, 300, 256), mode="magnitude"), tuple[_Array_f8, _Array_f8, _ArrayReal]) +assert_type(spectrogram(np.linspace(200, 300, 256), mode="angle"), tuple[_Array_f8, _Array_f8, _ArrayReal]) +assert_type(spectrogram(np.linspace(200, 300, 256), mode="phase"), tuple[_Array_f8, _Array_f8, _ArrayReal]) +assert_type(spectrogram(np.linspace(200, 300, 256), mode="complex"), tuple[_Array_f8, _Array_f8, _ArrayComplex]) +assert_type( + spectrogram(np.linspace(200, 300, 256), 1.0, ("tukey", 2.5), None, None, None, "constant", True, "density", -1, "complex"), + tuple[_Array_f8, _Array_f8, _ArrayComplex], +) From 22dad835abc55e4204768372d8ca71c594be61dd Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 13:01:47 +1100 Subject: [PATCH 06/18] `signal`: Add type stubs for `stft` and `istft`. In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 104 +++++++++++++++++++++------- 1 file changed, 79 insertions(+), 25 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 766d7a1c..a1b9d92f 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -19,7 +19,9 @@ _ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] _Scaling: TypeAlias = Literal["density", "spectrum"] +_LegacyScaling: TypeAlias = Literal["psd", "spectrum"] _Average: TypeAlias = Literal["mean", "median"] +_Boundary: TypeAlias = Literal["even", "odd", "constant", "zeros"] | None # NOTE(pavyamsiri): This function was actually recently updated, adding new arguments and return types. def lombscargle( @@ -133,32 +135,84 @@ def check_NOLA( tol: AnyReal = 1e-10, ) -> bool: ... def stft( - x: Untyped, - fs: float = 1.0, - window: str = "hann", - nperseg: int = 256, - noverlap: int | None = None, - nfft: int | None = None, - detrend: bool = False, - return_onesided: bool = True, - boundary: str = "zeros", - padded: bool = True, - axis: int = -1, - scaling: str = "spectrum", -) -> Untyped: ... + x: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt = 256, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = False, + return_onesided: op.CanBool = True, + boundary: _Boundary = "zeros", + padded: op.CanBool = True, + axis: op.CanIndex = -1, + scaling: _LegacyScaling = "spectrum", +) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... + +# def istft( +# Zxx: _ArrayLikeComplex_co, +# fs: AnyReal = 1.0, +# window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", +# nperseg: AnyInt | None = None, +# noverlap: AnyInt | None = None, +# nfft: AnyInt | None = None, +# input_onesided: op.CanBool = True, +# boundary: op.CanBool = True, +# time_axis: op.CanIndex = -1, +# freq_axis: op.CanIndex = -2, +# scaling: _LegacyScaling = "spectrum", +# ) -> tuple[_Array_f8]: ... + +# input_onesided is `True` +@overload def istft( - Zxx: Untyped, - fs: float = 1.0, - window: str = "hann", - nperseg: int | None = None, - noverlap: int | None = None, - nfft: int | None = None, - input_onesided: bool = True, - boundary: bool = True, - time_axis: int = -1, - freq_axis: int = -2, - scaling: str = "spectrum", -) -> Untyped: ... + Zxx: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + input_onesided: Literal[True] = True, + boundary: op.CanBool = True, + time_axis: op.CanIndex = -1, + freq_axis: op.CanIndex = -2, + scaling: _LegacyScaling = "spectrum", +) -> tuple[_Array_f8, _ArrayReal]: ... + +# input_onesided is `False` (positional) +@overload +def istft( + Zxx: _ArrayLikeComplex_co, + fs: AnyReal, + window: _GetWindowArgument | _ArrayLikeFloat_co, + nperseg: AnyInt | None, + noverlap: AnyInt | None, + nfft: AnyInt | None, + input_onesided: Literal[False], + boundary: op.CanBool = True, + time_axis: op.CanIndex = -1, + freq_axis: op.CanIndex = -2, + scaling: _LegacyScaling = "spectrum", +) -> tuple[_Array_f8, _ArrayComplex]: ... + +# input_onesided is `False` (keyword) +@overload +def istft( + Zxx: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + *, + input_onesided: Literal[False], + boundary: op.CanBool = True, + time_axis: op.CanIndex = -1, + freq_axis: op.CanIndex = -2, + scaling: _LegacyScaling = "spectrum", +) -> tuple[_Array_f8, _ArrayComplex]: ... + +# def coherence( x: Untyped, y: Untyped, From 973820e6368bb10b01c01eabfa225d0b03446ae5 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 13:02:10 +1100 Subject: [PATCH 07/18] tests: Add type tests for function overloads of `istft`. From the module `signal`. --- tests/signal/test_spectral.pyi | 45 +++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/tests/signal/test_spectral.pyi b/tests/signal/test_spectral.pyi index 7781f746..607646cf 100644 --- a/tests/signal/test_spectral.pyi +++ b/tests/signal/test_spectral.pyi @@ -3,7 +3,7 @@ from typing_extensions import assert_type import numpy as np import numpy.typing as npt -from scipy.signal import spectrogram +from scipy.signal import istft, spectrogram _Array_f8: TypeAlias = npt.NDArray[np.float64] _ArrayReal: TypeAlias = npt.NDArray[np.floating[Any]] @@ -20,3 +20,46 @@ assert_type( spectrogram(np.linspace(200, 300, 256), 1.0, ("tukey", 2.5), None, None, None, "constant", True, "density", -1, "complex"), tuple[_Array_f8, _Array_f8, _ArrayComplex], ) + +# test isft function overloads +assert_type(istft(np.ones((129, 100), dtype=np.complex128)), tuple[_Array_f8, _ArrayReal]) +assert_type(istft(np.ones((129, 100), dtype=np.complex128), input_onesided=True), tuple[_Array_f8, _ArrayReal]) +assert_type(istft(np.ones((129, 100), dtype=np.complex128), 1.0, "hann", 256, 128, 256, False), tuple[_Array_f8, _ArrayComplex]) +assert_type( + istft( + np.ones((129, 100), dtype=np.complex128), input_onesided=False, fs=1.0, window="hann", nperseg=256, noverlap=128, nfft=256 + ), + tuple[_Array_f8, _ArrayComplex], +) +assert_type( + istft( + np.ones((129, 100), dtype=np.complex128), + fs=2.0, + window=("tukey", 0.25), + nperseg=256, + noverlap=128, + nfft=256, + input_onesided=True, + boundary=False, + time_axis=-1, + freq_axis=0, + scaling="spectrum", + ), + tuple[_Array_f8, _ArrayReal], +) +assert_type( + istft( + np.ones((129, 100), dtype=np.complex128), + fs=2.0, + window=("tukey", 0.25), + nperseg=256, + noverlap=128, + nfft=256, + input_onesided=False, + boundary=False, + time_axis=0, + freq_axis=1, + scaling="spectrum", + ), + tuple[_Array_f8, _ArrayComplex], +) From bcf3d422a5289ccda6af6b62548e28b63a5e46be Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 13:06:14 +1100 Subject: [PATCH 08/18] `signal`: Add type stubs for `coherence`. In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index a1b9d92f..8c29a4ce 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -6,7 +6,7 @@ import numpy as np import numpy.typing as npt import optype as op from numpy._typing import _ArrayLikeComplex_co, _ArrayLikeFloat_co -from scipy._typing import AnyInt, AnyReal, Untyped, UntypedCallable +from scipy._typing import AnyInt, AnyReal from scipy.signal.windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] @@ -214,13 +214,13 @@ def istft( # def coherence( - x: Untyped, - y: Untyped, - fs: float = 1.0, - window: str = "hann", - nperseg: int | None = None, - noverlap: int | None = None, - nfft: int | None = None, - detrend: str | Literal[False] | UntypedCallable = "constant", - axis: int = -1, -) -> Untyped: ... + x: _ArrayLikeComplex_co, + y: _ArrayLikeComplex_co, + fs: AnyReal = 1.0, + window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + nperseg: AnyInt | None = None, + noverlap: AnyInt | None = None, + nfft: AnyInt | None = None, + detrend: _Detrend = "constant", + axis: op.CanIndex = -1, +) -> tuple[_Array_f8, _ArrayReal]: ... From cc8f55a2b4840d0ac59aebe837504ae3733131e1 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Mon, 4 Nov 2024 13:20:32 +1100 Subject: [PATCH 09/18] `signal`: Clean up `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 8c29a4ce..595f0458 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -23,7 +23,6 @@ _LegacyScaling: TypeAlias = Literal["psd", "spectrum"] _Average: TypeAlias = Literal["mean", "median"] _Boundary: TypeAlias = Literal["even", "odd", "constant", "zeros"] | None -# NOTE(pavyamsiri): This function was actually recently updated, adding new arguments and return types. def lombscargle( x: _ArrayLikeFloat_co, y: _ArrayLikeFloat_co, @@ -31,8 +30,6 @@ def lombscargle( precenter: op.CanBool = False, normalize: op.CanBool = False, ) -> _Array_f8_1d: ... - -# NOTE(pavyamsiri): The docs don't allow `None` for `window` but the body does? def periodogram( x: _ArrayLikeComplex_co, fs: AnyReal = 1.0, @@ -149,20 +146,6 @@ def stft( scaling: _LegacyScaling = "spectrum", ) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... -# def istft( -# Zxx: _ArrayLikeComplex_co, -# fs: AnyReal = 1.0, -# window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", -# nperseg: AnyInt | None = None, -# noverlap: AnyInt | None = None, -# nfft: AnyInt | None = None, -# input_onesided: op.CanBool = True, -# boundary: op.CanBool = True, -# time_axis: op.CanIndex = -1, -# freq_axis: op.CanIndex = -2, -# scaling: _LegacyScaling = "spectrum", -# ) -> tuple[_Array_f8]: ... - # input_onesided is `True` @overload def istft( From f302e55160a0716d0d79a49ca6a3409bc9ea2fb0 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 05:38:18 +1100 Subject: [PATCH 10/18] `signal`: Adjust type aliases in `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 69 ++++++++++++++--------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 595f0458..1717e38f 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -5,15 +5,15 @@ from typing_extensions import Unpack import numpy as np import numpy.typing as npt import optype as op -from numpy._typing import _ArrayLikeComplex_co, _ArrayLikeFloat_co +from numpy._typing import _ArrayLikeFloat_co, _ArrayLikeNumber_co from scipy._typing import AnyInt, AnyReal -from scipy.signal.windows._windows import _Window, _WindowNeedsParams +from .windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] +_Array_f: TypeAlias = npt.NDArray[np.floating[Any]] _Array_f8: TypeAlias = npt.NDArray[np.float64] _Array_f8_1d: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] -_ArrayReal: TypeAlias = npt.NDArray[np.floating[Any]] _ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] @@ -31,7 +31,7 @@ def lombscargle( normalize: op.CanBool = False, ) -> _Array_f8_1d: ... def periodogram( - x: _ArrayLikeComplex_co, + x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co | None = "boxcar", nfft: AnyInt | None = None, @@ -39,9 +39,9 @@ def periodogram( return_onesided: op.CanBool = True, scaling: _Scaling = "density", axis: op.CanIndex = -1, -) -> tuple[_Array_f8, _ArrayReal]: ... +) -> tuple[_Array_f8, _Array_f]: ... def welch( - x: _ArrayLikeComplex_co, + x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt | None = None, @@ -52,10 +52,10 @@ def welch( scaling: _Scaling = "density", axis: op.CanIndex = -1, average: _Average = "mean", -) -> tuple[_Array_f8, _ArrayReal]: ... +) -> tuple[_Array_f8, _Array_f]: ... def csd( - x: _ArrayLikeComplex_co, - y: _ArrayLikeComplex_co, + x: _ArrayLikeNumber_co, + y: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt | None = None, @@ -69,9 +69,10 @@ def csd( ) -> tuple[_Array_f8, _ArrayComplex]: ... # +# non-complex mode (positional and keyword) @overload def spectrogram( - x: npt.NDArray[np.generic], + x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), nperseg: AnyInt | None = None, @@ -82,12 +83,11 @@ def spectrogram( scaling: _Scaling = "density", axis: op.CanIndex = -1, mode: Literal["psd", "magnitude", "angle", "phase"] = "psd", -) -> tuple[_Array_f8, _Array_f8, _ArrayReal]: ... - -# complex mode (positional) +) -> tuple[_Array_f8, _Array_f8, _Array_f]: ... @overload +# complex mode (positional) def spectrogram( - x: npt.NDArray[np.generic], + x: _ArrayLikeNumber_co, fs: AnyReal, window: _GetWindowArgument | _ArrayLikeFloat_co, nperseg: AnyInt | None, @@ -99,12 +99,10 @@ def spectrogram( axis: op.CanIndex, mode: Literal["complex"], ) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... - -# complex mode (keyword) - @overload +# complex mode (keyword) def spectrogram( - x: npt.NDArray[np.generic], + x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), nperseg: AnyInt | None = None, @@ -124,15 +122,15 @@ def check_COLA( nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, -) -> bool: ... +) -> np.bool: ... def check_NOLA( window: _GetWindowArgument | _ArrayLikeFloat_co, nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, -) -> bool: ... +) -> np.bool: ... def stft( - x: _ArrayLikeComplex_co, + x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt = 256, @@ -146,49 +144,48 @@ def stft( scaling: _LegacyScaling = "spectrum", ) -> tuple[_Array_f8, _Array_f8, _ArrayComplex]: ... -# input_onesided is `True` +# @overload +# input_onesided is `True` def istft( - Zxx: _ArrayLikeComplex_co, + Zxx: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, - input_onesided: Literal[True] = True, + input_onesided: Literal[True, 1] = True, boundary: op.CanBool = True, time_axis: op.CanIndex = -1, freq_axis: op.CanIndex = -2, scaling: _LegacyScaling = "spectrum", -) -> tuple[_Array_f8, _ArrayReal]: ... - -# input_onesided is `False` (positional) +) -> tuple[_Array_f8, _Array_f]: ... @overload +# input_onesided is `False` (positional) def istft( - Zxx: _ArrayLikeComplex_co, + Zxx: _ArrayLikeNumber_co, fs: AnyReal, window: _GetWindowArgument | _ArrayLikeFloat_co, nperseg: AnyInt | None, noverlap: AnyInt | None, nfft: AnyInt | None, - input_onesided: Literal[False], + input_onesided: Literal[False, 0], boundary: op.CanBool = True, time_axis: op.CanIndex = -1, freq_axis: op.CanIndex = -2, scaling: _LegacyScaling = "spectrum", ) -> tuple[_Array_f8, _ArrayComplex]: ... - -# input_onesided is `False` (keyword) @overload +# input_onesided is `False` (keyword) def istft( - Zxx: _ArrayLikeComplex_co, + Zxx: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, *, - input_onesided: Literal[False], + input_onesided: Literal[False, 0], boundary: op.CanBool = True, time_axis: op.CanIndex = -1, freq_axis: op.CanIndex = -2, @@ -197,8 +194,8 @@ def istft( # def coherence( - x: _ArrayLikeComplex_co, - y: _ArrayLikeComplex_co, + x: _ArrayLikeNumber_co, + y: _ArrayLikeNumber_co, fs: AnyReal = 1.0, window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", nperseg: AnyInt | None = None, @@ -206,4 +203,4 @@ def coherence( nfft: AnyInt | None = None, detrend: _Detrend = "constant", axis: op.CanIndex = -1, -) -> tuple[_Array_f8, _ArrayReal]: ... +) -> tuple[_Array_f8, _Array_f]: ... From d8e6561a1b319769a09b6d6e9719f4d060c22582 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 05:51:52 +1100 Subject: [PATCH 11/18] `signal`: Tighten the return array dtypes in `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 1717e38f..d563f4c0 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -1,5 +1,5 @@ from collections.abc import Callable -from typing import Any, Literal, TypeAlias, overload +from typing import Literal, TypeAlias, overload from typing_extensions import Unpack import numpy as np @@ -11,10 +11,10 @@ from .windows._windows import _Window, _WindowNeedsParams __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle", "periodogram", "spectrogram", "stft", "welch"] -_Array_f: TypeAlias = npt.NDArray[np.floating[Any]] _Array_f8: TypeAlias = npt.NDArray[np.float64] _Array_f8_1d: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] -_ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] +_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.float128] +_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.complex256] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] @@ -39,7 +39,7 @@ def periodogram( return_onesided: op.CanBool = True, scaling: _Scaling = "density", axis: op.CanIndex = -1, -) -> tuple[_Array_f8, _Array_f]: ... +) -> tuple[_Array_f8, _ArrayFloat]: ... def welch( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, @@ -52,7 +52,7 @@ def welch( scaling: _Scaling = "density", axis: op.CanIndex = -1, average: _Average = "mean", -) -> tuple[_Array_f8, _Array_f]: ... +) -> tuple[_Array_f8, _ArrayFloat]: ... def csd( x: _ArrayLikeNumber_co, y: _ArrayLikeNumber_co, @@ -83,7 +83,7 @@ def spectrogram( scaling: _Scaling = "density", axis: op.CanIndex = -1, mode: Literal["psd", "magnitude", "angle", "phase"] = "psd", -) -> tuple[_Array_f8, _Array_f8, _Array_f]: ... +) -> tuple[_Array_f8, _Array_f8, _ArrayFloat]: ... @overload # complex mode (positional) def spectrogram( @@ -159,7 +159,7 @@ def istft( time_axis: op.CanIndex = -1, freq_axis: op.CanIndex = -2, scaling: _LegacyScaling = "spectrum", -) -> tuple[_Array_f8, _Array_f]: ... +) -> tuple[_Array_f8, _ArrayFloat]: ... @overload # input_onesided is `False` (positional) def istft( @@ -203,4 +203,4 @@ def coherence( nfft: AnyInt | None = None, detrend: _Detrend = "constant", axis: op.CanIndex = -1, -) -> tuple[_Array_f8, _Array_f]: ... +) -> tuple[_Array_f8, _ArrayFloat]: ... From face996d56b35a451be287f132e32bb8b4edbfec Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 06:05:22 +1100 Subject: [PATCH 12/18] tests: Clean up `test_spectral.pyi`. --- tests/signal/test_spectral.pyi | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/signal/test_spectral.pyi b/tests/signal/test_spectral.pyi index 607646cf..a8d66df6 100644 --- a/tests/signal/test_spectral.pyi +++ b/tests/signal/test_spectral.pyi @@ -1,39 +1,39 @@ -from typing import Any, TypeAlias +from typing import Literal, TypeAlias from typing_extensions import assert_type import numpy as np import numpy.typing as npt +import optype.numpy as onpt from scipy.signal import istft, spectrogram _Array_f8: TypeAlias = npt.NDArray[np.float64] -_ArrayReal: TypeAlias = npt.NDArray[np.floating[Any]] -_ArrayComplex: TypeAlias = npt.NDArray[np.complexfloating[Any, Any]] +_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.float128] +_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.complex256] + +array_f8_1d: onpt.Array[tuple[Literal[256]], np.float64] +array_c16_1d: onpt.Array[tuple[Literal[256]], np.complex128] +spectrogram_mode_real: Literal["psd", "magnitude", "angle", "phase"] # test spectrogram function overloads -assert_type(spectrogram(np.linspace(200, 300, 256)), tuple[_Array_f8, _Array_f8, _ArrayReal]) -assert_type(spectrogram(np.linspace(200, 300, 256), mode="psd"), tuple[_Array_f8, _Array_f8, _ArrayReal]) -assert_type(spectrogram(np.linspace(200, 300, 256), mode="magnitude"), tuple[_Array_f8, _Array_f8, _ArrayReal]) -assert_type(spectrogram(np.linspace(200, 300, 256), mode="angle"), tuple[_Array_f8, _Array_f8, _ArrayReal]) -assert_type(spectrogram(np.linspace(200, 300, 256), mode="phase"), tuple[_Array_f8, _Array_f8, _ArrayReal]) -assert_type(spectrogram(np.linspace(200, 300, 256), mode="complex"), tuple[_Array_f8, _Array_f8, _ArrayComplex]) +assert_type(spectrogram(array_f8_1d), tuple[_Array_f8, _Array_f8, _ArrayFloat]) +assert_type(spectrogram(array_f8_1d, mode=spectrogram_mode_real), tuple[_Array_f8, _Array_f8, _ArrayFloat]) +assert_type(spectrogram(array_f8_1d, mode="complex"), tuple[_Array_f8, _Array_f8, _ArrayComplex]) assert_type( - spectrogram(np.linspace(200, 300, 256), 1.0, ("tukey", 2.5), None, None, None, "constant", True, "density", -1, "complex"), + spectrogram(array_f8_1d, 1.0, ("tukey", 2.5), None, None, None, "constant", True, "density", -1, "complex"), tuple[_Array_f8, _Array_f8, _ArrayComplex], ) # test isft function overloads -assert_type(istft(np.ones((129, 100), dtype=np.complex128)), tuple[_Array_f8, _ArrayReal]) -assert_type(istft(np.ones((129, 100), dtype=np.complex128), input_onesided=True), tuple[_Array_f8, _ArrayReal]) -assert_type(istft(np.ones((129, 100), dtype=np.complex128), 1.0, "hann", 256, 128, 256, False), tuple[_Array_f8, _ArrayComplex]) +assert_type(istft(array_c16_1d), tuple[_Array_f8, _ArrayFloat]) +assert_type(istft(array_c16_1d, input_onesided=True), tuple[_Array_f8, _ArrayFloat]) +assert_type(istft(array_c16_1d, 1.0, "hann", 256, 128, 256, False), tuple[_Array_f8, _ArrayComplex]) assert_type( - istft( - np.ones((129, 100), dtype=np.complex128), input_onesided=False, fs=1.0, window="hann", nperseg=256, noverlap=128, nfft=256 - ), + istft(array_c16_1d, input_onesided=False, fs=1.0, window="hann", nperseg=256, noverlap=128, nfft=256), tuple[_Array_f8, _ArrayComplex], ) assert_type( istft( - np.ones((129, 100), dtype=np.complex128), + array_c16_1d, fs=2.0, window=("tukey", 0.25), nperseg=256, @@ -45,11 +45,11 @@ assert_type( freq_axis=0, scaling="spectrum", ), - tuple[_Array_f8, _ArrayReal], + tuple[_Array_f8, _ArrayFloat], ) assert_type( istft( - np.ones((129, 100), dtype=np.complex128), + array_c16_1d, fs=2.0, window=("tukey", 0.25), nperseg=256, From 2f7e1c6101bfb9306672d41e32291dc79533fb2e Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 06:06:32 +1100 Subject: [PATCH 13/18] `signal`: Fix up comment inconsistency in `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index d563f4c0..c0157cd9 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -69,8 +69,8 @@ def csd( ) -> tuple[_Array_f8, _ArrayComplex]: ... # -# non-complex mode (positional and keyword) @overload +# non-complex mode (positional and keyword) def spectrogram( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, From 4dfb44a7be1b3c843e9f211d8db6775eba367757 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri <78515468+pavyamsiri@users.noreply.github.com> Date: Tue, 5 Nov 2024 08:01:27 +1100 Subject: [PATCH 14/18] `signal`: Use the more portable names for dtypes in `_spectral_py.pyi`. Co-authored-by: Joren Hammudoglu --- scipy-stubs/signal/_spectral_py.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index c0157cd9..1f9633cc 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -13,8 +13,8 @@ __all__ = ["check_COLA", "check_NOLA", "coherence", "csd", "istft", "lombscargle _Array_f8: TypeAlias = npt.NDArray[np.float64] _Array_f8_1d: TypeAlias = np.ndarray[tuple[int], np.dtype[np.float64]] -_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.float128] -_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.complex256] +_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.longdouble] +_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.clongdouble] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] From 67282169bf49e19982066a5fdef1e0a1219ef8da Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri <78515468+pavyamsiri@users.noreply.github.com> Date: Tue, 5 Nov 2024 08:03:45 +1100 Subject: [PATCH 15/18] `signal`: Use `np.bool_` instead of `np.bool`. In `_spectral_py.pyi` to be backwards compatible with numpy<2. Co-authored-by: Joren Hammudoglu --- scipy-stubs/signal/_spectral_py.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 1f9633cc..e4bf6dc1 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -122,7 +122,7 @@ def check_COLA( nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, -) -> np.bool: ... +) -> np.bool_: ... def check_NOLA( window: _GetWindowArgument | _ArrayLikeFloat_co, nperseg: AnyInt, From 847504cfe04566af4d432cbfd9ac306f5fa4b6a6 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri <78515468+pavyamsiri@users.noreply.github.com> Date: Tue, 5 Nov 2024 08:04:33 +1100 Subject: [PATCH 16/18] `signal`: Use `np.bool_` instead of `np.bool` In `_spectral_py.pyi` to be backwards compatible. Co-authored-by: Joren Hammudoglu --- scipy-stubs/signal/_spectral_py.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index e4bf6dc1..40a461ef 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -128,7 +128,7 @@ def check_NOLA( nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, -) -> np.bool: ... +) -> np.bool_: ... def stft( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, From 3bb87802d8c9f2b9faf98b433310d19b91698220 Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 08:06:32 +1100 Subject: [PATCH 17/18] `signal`: Use a type alias for `_GetWindowArgument | _ArrayLikeFloat_co` In `_spectral_py.pyi`. --- scipy-stubs/signal/_spectral_py.pyi | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/scipy-stubs/signal/_spectral_py.pyi b/scipy-stubs/signal/_spectral_py.pyi index 40a461ef..d9cf6d81 100644 --- a/scipy-stubs/signal/_spectral_py.pyi +++ b/scipy-stubs/signal/_spectral_py.pyi @@ -17,6 +17,7 @@ _ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.longdouble] _ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.clongdouble] _GetWindowArgument: TypeAlias = _Window | tuple[_Window | _WindowNeedsParams, Unpack[tuple[object, ...]]] +_WindowLike: TypeAlias = _GetWindowArgument | _ArrayLikeFloat_co _Detrend: TypeAlias = Literal["literal", "constant", False] | Callable[[npt.NDArray[np.generic]], npt.NDArray[np.generic]] _Scaling: TypeAlias = Literal["density", "spectrum"] _LegacyScaling: TypeAlias = Literal["psd", "spectrum"] @@ -33,7 +34,7 @@ def lombscargle( def periodogram( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co | None = "boxcar", + window: _WindowLike | None = "boxcar", nfft: AnyInt | None = None, detrend: _Detrend = "constant", return_onesided: op.CanBool = True, @@ -43,7 +44,7 @@ def periodogram( def welch( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -57,7 +58,7 @@ def csd( x: _ArrayLikeNumber_co, y: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -74,7 +75,7 @@ def csd( def spectrogram( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), + window: _WindowLike = ("tukey", 0.25), nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -89,7 +90,7 @@ def spectrogram( def spectrogram( x: _ArrayLikeNumber_co, fs: AnyReal, - window: _GetWindowArgument | _ArrayLikeFloat_co, + window: _WindowLike, nperseg: AnyInt | None, noverlap: AnyInt | None, nfft: AnyInt | None, @@ -104,7 +105,7 @@ def spectrogram( def spectrogram( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = ("tukey", 0.25), + window: _WindowLike = ("tukey", 0.25), nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -118,13 +119,13 @@ def spectrogram( # def check_COLA( - window: _GetWindowArgument | _ArrayLikeFloat_co, + window: _WindowLike, nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, ) -> np.bool_: ... def check_NOLA( - window: _GetWindowArgument | _ArrayLikeFloat_co, + window: _WindowLike, nperseg: AnyInt, noverlap: AnyInt, tol: AnyReal = 1e-10, @@ -132,7 +133,7 @@ def check_NOLA( def stft( x: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt = 256, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -150,7 +151,7 @@ def stft( def istft( Zxx: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -165,7 +166,7 @@ def istft( def istft( Zxx: _ArrayLikeNumber_co, fs: AnyReal, - window: _GetWindowArgument | _ArrayLikeFloat_co, + window: _WindowLike, nperseg: AnyInt | None, noverlap: AnyInt | None, nfft: AnyInt | None, @@ -180,7 +181,7 @@ def istft( def istft( Zxx: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, @@ -197,7 +198,7 @@ def coherence( x: _ArrayLikeNumber_co, y: _ArrayLikeNumber_co, fs: AnyReal = 1.0, - window: _GetWindowArgument | _ArrayLikeFloat_co = "hann", + window: _WindowLike = "hann", nperseg: AnyInt | None = None, noverlap: AnyInt | None = None, nfft: AnyInt | None = None, From fb5c85db09cbccfe72b3bcc6ec308974fb17b05d Mon Sep 17 00:00:00 2001 From: Pavadol Yamsiri Date: Tue, 5 Nov 2024 08:08:14 +1100 Subject: [PATCH 18/18] tests: Update `test_spectral.pyi` to use the correct dtypes --- tests/signal/test_spectral.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/signal/test_spectral.pyi b/tests/signal/test_spectral.pyi index a8d66df6..a60b76b1 100644 --- a/tests/signal/test_spectral.pyi +++ b/tests/signal/test_spectral.pyi @@ -7,8 +7,8 @@ import optype.numpy as onpt from scipy.signal import istft, spectrogram _Array_f8: TypeAlias = npt.NDArray[np.float64] -_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.float128] -_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.complex256] +_ArrayFloat: TypeAlias = npt.NDArray[np.float32 | np.float64 | np.longdouble] +_ArrayComplex: TypeAlias = npt.NDArray[np.complex64 | np.complex128 | np.clongdouble] array_f8_1d: onpt.Array[tuple[Literal[256]], np.float64] array_c16_1d: onpt.Array[tuple[Literal[256]], np.complex128]