scipy 1.16.1__cp312-cp312-macosx_12_0_arm64.whl → 1.16.2__cp312-cp312-macosx_12_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scipy/.dylibs/libscipy_openblas.dylib +0 -0
- scipy/__config__.py +12 -12
- scipy/_cyutility.cpython-312-darwin.so +0 -0
- scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
- scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
- scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
- scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
- scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
- scipy/cluster/_vq.cpython-312-darwin.so +0 -0
- scipy/fft/_pocketfft/pypocketfft.cpython-312-darwin.so +0 -0
- scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
- scipy/integrate/_dop.cpython-312-darwin.so +0 -0
- scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
- scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
- scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
- scipy/integrate/_vode.cpython-312-darwin.so +0 -0
- scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
- scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
- scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
- scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
- scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cpython-312-darwin.so +0 -0
- scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
- scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
- scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
- scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
- scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
- scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
- scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
- scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
- scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
- scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
- scipy/linalg/tests/test_lapack.py +5 -1
- scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
- scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
- scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
- scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
- scipy/optimize/_highspy/_core.cpython-312-darwin.so +0 -0
- scipy/optimize/_highspy/_highs_options.cpython-312-darwin.so +0 -0
- scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
- scipy/optimize/_lbfgsb_py.py +2 -2
- scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
- scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
- scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
- scipy/optimize/_slsqp_py.py +5 -5
- scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
- scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
- scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
- scipy/optimize/tests/test_optimize.py +9 -0
- scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
- scipy/signal/_short_time_fft.py +74 -33
- scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
- scipy/signal/_spectral_py.py +2 -2
- scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
- scipy/signal/tests/test_short_time_fft.py +9 -0
- scipy/signal/tests/test_signaltools.py +8 -2
- scipy/signal/tests/test_spectral.py +39 -1
- scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
- scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
- scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
- scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
- scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
- scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
- scipy/spatial/qhull_src/COPYING_QHULL.txt +39 -0
- scipy/spatial/tests/test_distance.py +5 -4
- scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
- scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
- scipy/special/_comb.cpython-312-darwin.so +0 -0
- scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
- scipy/special/_specfun.cpython-312-darwin.so +0 -0
- scipy/special/_test_internal.cpython-312-darwin.so +0 -0
- scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
- scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
- scipy/special/cython_special.cpython-312-darwin.so +0 -0
- scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
- scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
- scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
- scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
- scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
- scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
- scipy/stats/_sobol.cpython-312-darwin.so +0 -0
- scipy/stats/_stats.cpython-312-darwin.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
- scipy/version.py +2 -2
- {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/METADATA +2 -2
- {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/RECORD +107 -106
- {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/LICENSE.txt +0 -0
- {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/WHEEL +0 -0
Binary file
|
scipy/__config__.py
CHANGED
@@ -36,7 +36,7 @@ CONFIG = _cleanup(
|
|
36
36
|
"cython": {
|
37
37
|
"name": r"cython",
|
38
38
|
"linker": r"cython",
|
39
|
-
"version": r"3.1.
|
39
|
+
"version": r"3.1.3",
|
40
40
|
"commands": r"cython",
|
41
41
|
"args": r"",
|
42
42
|
"linker args": r"",
|
@@ -59,7 +59,7 @@ CONFIG = _cleanup(
|
|
59
59
|
},
|
60
60
|
"pythran": {
|
61
61
|
"version": r"0.18.0",
|
62
|
-
"include directory": r"../../../../../../private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/build-env-
|
62
|
+
"include directory": r"../../../../../../private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/build-env-fba5f_a2/lib/python3.12/site-packages/pythran"
|
63
63
|
},
|
64
64
|
},
|
65
65
|
"Machine Information": {
|
@@ -81,32 +81,32 @@ CONFIG = _cleanup(
|
|
81
81
|
"blas": {
|
82
82
|
"name": "scipy-openblas",
|
83
83
|
"found": bool("True".lower().replace('false', '')),
|
84
|
-
"version": "0.3.
|
84
|
+
"version": "0.3.29.dev",
|
85
85
|
"detection method": "pkgconfig",
|
86
|
-
"include directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-
|
87
|
-
"lib directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-
|
88
|
-
"openblas configuration": r"OpenBLAS 0.3.
|
86
|
+
"include directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-rdqle_au/cp312-macosx_arm64/build/venv/lib/python3.12/site-packages/scipy_openblas32/include",
|
87
|
+
"lib directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-rdqle_au/cp312-macosx_arm64/build/venv/lib/python3.12/site-packages/scipy_openblas32/lib",
|
88
|
+
"openblas configuration": r"OpenBLAS 0.3.29.dev DYNAMIC_ARCH NO_AFFINITY neoversen1 MAX_THREADS=64",
|
89
89
|
"pc file directory": r"/Users/runner/work/scipy/scipy",
|
90
90
|
},
|
91
91
|
"lapack": {
|
92
92
|
"name": "scipy-openblas",
|
93
93
|
"found": bool("True".lower().replace('false', '')),
|
94
|
-
"version": "0.3.
|
94
|
+
"version": "0.3.29.dev",
|
95
95
|
"detection method": "pkgconfig",
|
96
|
-
"include directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-
|
97
|
-
"lib directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-
|
98
|
-
"openblas configuration": r"OpenBLAS 0.3.
|
96
|
+
"include directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-rdqle_au/cp312-macosx_arm64/build/venv/lib/python3.12/site-packages/scipy_openblas32/include",
|
97
|
+
"lib directory": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/cibw-run-rdqle_au/cp312-macosx_arm64/build/venv/lib/python3.12/site-packages/scipy_openblas32/lib",
|
98
|
+
"openblas configuration": r"OpenBLAS 0.3.29.dev DYNAMIC_ARCH NO_AFFINITY neoversen1 MAX_THREADS=64",
|
99
99
|
"pc file directory": r"/Users/runner/work/scipy/scipy",
|
100
100
|
},
|
101
101
|
"pybind11": {
|
102
102
|
"name": "pybind11",
|
103
|
-
"version": "3.0.
|
103
|
+
"version": "3.0.1",
|
104
104
|
"detection method": "config-tool",
|
105
105
|
"include directory": r"unknown",
|
106
106
|
},
|
107
107
|
},
|
108
108
|
"Python Information": {
|
109
|
-
"path": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/build-env-
|
109
|
+
"path": r"/private/var/folders/y6/nj790rtn62lfktb1sh__79hc0000gn/T/build-env-fba5f_a2/bin/python",
|
110
110
|
"version": "3.12",
|
111
111
|
},
|
112
112
|
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
from functools import reduce
|
6
6
|
import random
|
7
|
+
import sysconfig
|
7
8
|
|
8
9
|
from numpy.testing import (assert_equal, assert_array_almost_equal, assert_,
|
9
10
|
assert_allclose, assert_almost_equal,
|
@@ -503,7 +504,7 @@ class TestDlasd4:
|
|
503
504
|
roots.append(res[1])
|
504
505
|
|
505
506
|
assert_(
|
506
|
-
(res[3] <= 0),
|
507
|
+
(res[3] <= 0),
|
507
508
|
f"LAPACK root finding dlasd4 failed to find the singular value {i}"
|
508
509
|
)
|
509
510
|
roots = np.array(roots)[::-1]
|
@@ -3495,6 +3496,9 @@ def test_sy_hetrs(mtype, dtype, lower):
|
|
3495
3496
|
def test_sy_he_tri(dtype, lower, mtype):
|
3496
3497
|
if mtype == 'he' and dtype in REAL_DTYPES:
|
3497
3498
|
pytest.skip("hetri not for real dtypes.")
|
3499
|
+
if sysconfig.get_platform() == 'win-arm64' and dtype in COMPLEX_DTYPES:
|
3500
|
+
pytest.skip("Test segfaulting on win-arm64 in CI, see gh-23133")
|
3501
|
+
|
3498
3502
|
rng = np.random.default_rng(1723059677121834)
|
3499
3503
|
n = 20
|
3500
3504
|
A = rng.random((n, n)) + rng.random((n, n))*1j
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
scipy/optimize/_lbfgsb_py.py
CHANGED
@@ -440,8 +440,8 @@ def _minimize_lbfgsb(fun, x0, args=(), jac=None, bounds=None,
|
|
440
440
|
raise ValueError('maxls must be positive.')
|
441
441
|
|
442
442
|
x = array(x0, dtype=np.float64)
|
443
|
-
f = array(0.0, dtype=np.
|
444
|
-
g = zeros((n,), dtype=np.
|
443
|
+
f = array(0.0, dtype=np.float64)
|
444
|
+
g = zeros((n,), dtype=np.float64)
|
445
445
|
wa = zeros(2*m*n + 5*n + 11*m*m + 8*m, float64)
|
446
446
|
iwa = zeros(3*n, dtype=np.int32)
|
447
447
|
task = zeros(2, dtype=np.int32)
|
Binary file
|
Binary file
|
Binary file
|
scipy/optimize/_slsqp_py.py
CHANGED
@@ -234,8 +234,8 @@ def _minimize_slsqp(func, x0, args=(), jac=None, bounds=None,
|
|
234
234
|
disp : bool
|
235
235
|
Set to True to print convergence messages. If False,
|
236
236
|
`verbosity` is ignored and set to 0.
|
237
|
-
maxiter : int
|
238
|
-
Maximum number of iterations.
|
237
|
+
maxiter : int, optional
|
238
|
+
Maximum number of iterations. Default value is 100.
|
239
239
|
finite_diff_rel_step : None or array_like, optional
|
240
240
|
If ``jac in ['2-point', '3-point', 'cs']`` the relative step size to
|
241
241
|
use for numerical approximation of `jac`. The absolute step
|
@@ -268,8 +268,8 @@ def _minimize_slsqp(func, x0, args=(), jac=None, bounds=None,
|
|
268
268
|
attribute as a NumPy array. Denoting the dimension of the equality constraints
|
269
269
|
with ``meq``, and of inequality constraints with ``mineq``, then the returned
|
270
270
|
array slice ``m[:meq]`` contains the multipliers for the equality constraints,
|
271
|
-
and the remaining ``m[meq:meq + mineq]`` contains the multipliers for the
|
272
|
-
inequality constraints. The multipliers corresponding to bound inequalities
|
271
|
+
and the remaining ``m[meq:meq + mineq]`` contains the multipliers for the
|
272
|
+
inequality constraints. The multipliers corresponding to bound inequalities
|
273
273
|
are not returned. See [1]_ pp. 321 or [2]_ for an explanation of how to interpret
|
274
274
|
these multipliers. The internal QP problem is solved using the methods given
|
275
275
|
in [3]_ Chapter 25.
|
@@ -461,7 +461,7 @@ def _minimize_slsqp(func, x0, args=(), jac=None, bounds=None,
|
|
461
461
|
"inconsistent": 0,
|
462
462
|
"reset": 0,
|
463
463
|
"iter": 0,
|
464
|
-
"itermax": maxiter,
|
464
|
+
"itermax": int(maxiter),
|
465
465
|
"line": 0,
|
466
466
|
"m": m,
|
467
467
|
"meq": meq,
|
Binary file
|
Binary file
|
Binary file
|
@@ -3167,6 +3167,15 @@ def test_bounds_with_list():
|
|
3167
3167
|
)
|
3168
3168
|
|
3169
3169
|
|
3170
|
+
@pytest.mark.parametrize('method', (
|
3171
|
+
'slsqp', 'cg', 'cobyqa', 'powell','nelder-mead', 'bfgs', 'l-bfgs-b',
|
3172
|
+
'trust-constr'))
|
3173
|
+
def test_minimize_maxiter_noninteger(method):
|
3174
|
+
# Regression test for gh-23430
|
3175
|
+
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
|
3176
|
+
optimize.minimize(rosen, x0, method=method, options={'maxiter': 100.1})
|
3177
|
+
|
3178
|
+
|
3170
3179
|
def test_x_overwritten_user_function():
|
3171
3180
|
# if the user overwrites the x-array in the user function it's likely
|
3172
3181
|
# that the minimizer stops working properly.
|
Binary file
|
scipy/signal/_short_time_fft.py
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
"""Implementation of an FFT-based Short-time Fourier Transform. """
|
2
2
|
|
3
|
-
# Implementation Notes for this file (as of
|
3
|
+
# Implementation Notes for this file (as of 2025-08)
|
4
4
|
# --------------------------------------------------
|
5
|
-
# * MyPy version 1.1.1 does not seem to support decorated property methods
|
6
|
-
# properly. Hence, applying ``@property`` to methods decorated with `@cache``
|
7
|
-
# (as tried with the ``lower_border_end`` method) causes a mypy error when
|
8
|
-
# accessing it as an index (e.g., ``SFT.lower_border_end[0]``).
|
9
5
|
# * Since the method `stft` and `istft` have identical names as the legacy
|
10
6
|
# functions in the signal module, referencing them as HTML link in the
|
11
7
|
# docstrings has to be done by an explicit `~ShortTimeFFT.stft` instead of an
|
@@ -17,10 +13,9 @@
|
|
17
13
|
# (currently 0.9). Consult Issue 18512 and PR 16660 for further details.
|
18
14
|
|
19
15
|
|
20
|
-
# Provides typing union operator ``|`` in Python 3.9:
|
21
16
|
# Linter does not allow to import ``Generator`` from ``typing`` module:
|
22
17
|
from collections.abc import Generator, Callable
|
23
|
-
from functools import
|
18
|
+
from functools import partial, cached_property
|
24
19
|
from typing import get_args, Literal
|
25
20
|
|
26
21
|
import numpy as np
|
@@ -419,6 +414,15 @@ class ShortTimeFFT:
|
|
419
414
|
_fac_mag: float | None = None
|
420
415
|
_fac_psd: float | None = None
|
421
416
|
_lower_border_end: tuple[int, int] | None = None
|
417
|
+
# The following tuples store parameter(s) and return value(s) of methods for caching
|
418
|
+
# (initialized with invalid parameters; should only be accessed by atomic
|
419
|
+
# read/writes to alleviate potential multithreading issues):
|
420
|
+
_cache_post_padding: tuple[int, tuple[int, int]] = -1, (0, 0)
|
421
|
+
_cache_upper_border_begin: tuple[int, tuple[int, int]] = -1, (0, 0)
|
422
|
+
_cache_t: tuple[tuple[int, int | None, int | None, int, float], np.ndarray] = \
|
423
|
+
(-1, None, None, 0, 0.), np.ndarray([])
|
424
|
+
_cache_f: tuple[tuple[FFT_MODE_TYPE, int, float], np.ndarray] = \
|
425
|
+
('onesided', -1, 1.), np.ndarray([])
|
422
426
|
|
423
427
|
def __init__(self, win: np.ndarray, hop: int, fs: float, *,
|
424
428
|
fft_mode: FFT_MODE_TYPE = 'onesided',
|
@@ -1607,7 +1611,7 @@ class ShortTimeFFT:
|
|
1607
1611
|
"""
|
1608
1612
|
return self.m_num // 2
|
1609
1613
|
|
1610
|
-
@
|
1614
|
+
@cached_property
|
1611
1615
|
def _pre_padding(self) -> tuple[int, int]:
|
1612
1616
|
"""Smallest signal index and slice index due to padding.
|
1613
1617
|
|
@@ -1617,13 +1621,12 @@ class ShortTimeFFT:
|
|
1617
1621
|
w2 = self.win.real**2 + self.win.imag**2
|
1618
1622
|
# move window to the left until the overlap with t >= 0 vanishes:
|
1619
1623
|
n0 = -self.m_num_mid
|
1620
|
-
for
|
1624
|
+
for p_, n_ in enumerate(range(n0, n0-self.m_num-1, -self.hop)):
|
1621
1625
|
n_next = n_ - self.hop
|
1622
1626
|
if n_next + self.m_num <= 0 or all(w2[n_next:] == 0):
|
1623
|
-
return n_, -
|
1624
|
-
|
1625
|
-
|
1626
|
-
# returned, i.e.: return n0, 0
|
1627
|
+
return n_, -p_
|
1628
|
+
# Make the linter happy:
|
1629
|
+
raise RuntimeError("This code line should never run! Please file a bug.")
|
1627
1630
|
|
1628
1631
|
@property
|
1629
1632
|
def k_min(self) -> int:
|
@@ -1646,7 +1649,7 @@ class ShortTimeFFT:
|
|
1646
1649
|
upper_border_begin: Where post-padding effects start.
|
1647
1650
|
ShortTimeFFT: Class this property belongs to.
|
1648
1651
|
"""
|
1649
|
-
return self._pre_padding
|
1652
|
+
return self._pre_padding[0]
|
1650
1653
|
|
1651
1654
|
@property
|
1652
1655
|
def p_min(self) -> int:
|
@@ -1671,9 +1674,8 @@ class ShortTimeFFT:
|
|
1671
1674
|
p_range: Determine and validate slice index range.
|
1672
1675
|
ShortTimeFFT: Class this property belongs to.
|
1673
1676
|
"""
|
1674
|
-
return self._pre_padding
|
1677
|
+
return self._pre_padding[1]
|
1675
1678
|
|
1676
|
-
@lru_cache(maxsize=256)
|
1677
1679
|
def _post_padding(self, n: int) -> tuple[int, int]:
|
1678
1680
|
"""Largest signal index and slice index due to padding.
|
1679
1681
|
|
@@ -1681,9 +1683,17 @@ class ShortTimeFFT:
|
|
1681
1683
|
----------
|
1682
1684
|
n : int
|
1683
1685
|
Number of samples of input signal (must be ≥ half of the window length).
|
1686
|
+
|
1687
|
+
Notes
|
1688
|
+
-----
|
1689
|
+
Note that the return values are cached together with the parameter `n` to avoid
|
1690
|
+
unnecessary recalculations.
|
1684
1691
|
"""
|
1685
1692
|
if not (n >= (m2p := self.m_num - self.m_num_mid)):
|
1686
1693
|
raise ValueError(f"Parameter n must be >= ceil(m_num/2) = {m2p}!")
|
1694
|
+
last_arg, last_return_value = self._cache_post_padding
|
1695
|
+
if n == last_arg: # use cached value:
|
1696
|
+
return last_return_value
|
1687
1697
|
w2 = self.win.real**2 + self.win.imag**2
|
1688
1698
|
# move window to the right until the overlap for t < t[n] vanishes:
|
1689
1699
|
q1 = n // self.hop # last slice index with t[p1] <= t[n]
|
@@ -1691,15 +1701,17 @@ class ShortTimeFFT:
|
|
1691
1701
|
for q_, k_ in enumerate(range(k1, n+self.m_num, self.hop), start=q1):
|
1692
1702
|
n_next = k_ + self.hop
|
1693
1703
|
if n_next >= n or all(w2[:n-n_next] == 0):
|
1694
|
-
|
1695
|
-
|
1704
|
+
return_value = k_ + self.m_num, q_ + 1
|
1705
|
+
self._cache_post_padding = n, return_value
|
1706
|
+
return return_value
|
1707
|
+
raise RuntimeError("This code line should never run! Please file a bug.")
|
1696
1708
|
# If this case is reached, it probably means the last slice should be
|
1697
1709
|
# returned, i.e.: return k1 + self.m_num - self.m_num_mid, q1 + 1
|
1698
1710
|
|
1699
1711
|
def k_max(self, n: int) -> int:
|
1700
1712
|
"""First sample index after signal end not touched by a time slice.
|
1701
1713
|
|
1702
|
-
`k_max` - 1 is the largest sample index of the slice `p_max` for a
|
1714
|
+
`k_max` - 1 is the largest sample index of the slice `p_max` - 1 for a
|
1703
1715
|
given input signal of `n` samples.
|
1704
1716
|
A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
|
1705
1717
|
section of the :ref:`user_guide`.
|
@@ -1785,7 +1797,6 @@ class ShortTimeFFT:
|
|
1785
1797
|
upper_border_begin: Where post-padding effects start.
|
1786
1798
|
ShortTimeFFT: Class this property belongs to.
|
1787
1799
|
"""
|
1788
|
-
# not using @cache decorator due to MyPy limitations
|
1789
1800
|
if self._lower_border_end is not None:
|
1790
1801
|
return self._lower_border_end
|
1791
1802
|
|
@@ -1801,7 +1812,6 @@ class ShortTimeFFT:
|
|
1801
1812
|
self._lower_border_end = (0, max(self.p_min, 0)) # ends at first slice
|
1802
1813
|
return self._lower_border_end
|
1803
1814
|
|
1804
|
-
@lru_cache(maxsize=256)
|
1805
1815
|
def upper_border_begin(self, n: int) -> tuple[int, int]:
|
1806
1816
|
"""First signal index and first slice index affected by post-padding.
|
1807
1817
|
|
@@ -1823,6 +1833,11 @@ class ShortTimeFFT:
|
|
1823
1833
|
p_ub : int
|
1824
1834
|
Lowest index of time slice of which the end sticks out past the signal end.
|
1825
1835
|
|
1836
|
+
Notes
|
1837
|
+
-----
|
1838
|
+
Note that the return values are cached together with the parameter `n` to avoid
|
1839
|
+
unnecessary recalculations.
|
1840
|
+
|
1826
1841
|
See Also
|
1827
1842
|
--------
|
1828
1843
|
k_min: The smallest possible signal index.
|
@@ -1836,6 +1851,9 @@ class ShortTimeFFT:
|
|
1836
1851
|
"""
|
1837
1852
|
if not (n >= (m2p := self.m_num - self.m_num_mid)):
|
1838
1853
|
raise ValueError(f"Parameter n must be >= ceil(m_num/2) = {m2p}!")
|
1854
|
+
last_arg, last_return_value = self._cache_upper_border_begin
|
1855
|
+
if n == last_arg: # use cached value:
|
1856
|
+
return last_return_value
|
1839
1857
|
w2 = self.win.real**2 + self.win.imag**2
|
1840
1858
|
q2 = n // self.hop + 1 # first t[q] >= t[n]
|
1841
1859
|
q1 = max((n-self.m_num) // self.hop - 1, -1)
|
@@ -1843,8 +1861,11 @@ class ShortTimeFFT:
|
|
1843
1861
|
for q_ in range(q2, q1, -1):
|
1844
1862
|
k_ = q_ * self.hop + (self.m_num - self.m_num_mid)
|
1845
1863
|
if k_ <= n or all(w2[n-k_:] == 0):
|
1846
|
-
|
1847
|
-
|
1864
|
+
return_value = (q_ + 1) * self.hop - self.m_num_mid, q_ + 1
|
1865
|
+
self. _cache_upper_border_begin = n, return_value
|
1866
|
+
return return_value
|
1867
|
+
# make linter happy:
|
1868
|
+
raise RuntimeError("This code line should never run! Please file a bug.")
|
1848
1869
|
|
1849
1870
|
@property
|
1850
1871
|
def delta_t(self) -> float:
|
@@ -1912,7 +1933,6 @@ class ShortTimeFFT:
|
|
1912
1933
|
f"does not hold for signal length {n=}!")
|
1913
1934
|
return p0_, p1_
|
1914
1935
|
|
1915
|
-
@lru_cache(maxsize=1)
|
1916
1936
|
def t(self, n: int, p0: int | None = None, p1: int | None = None,
|
1917
1937
|
k_offset: int = 0) -> np.ndarray:
|
1918
1938
|
"""Times of STFT for an input signal with `n` samples.
|
@@ -1934,6 +1954,10 @@ class ShortTimeFFT:
|
|
1934
1954
|
k_offset
|
1935
1955
|
Index of first sample (t = 0) in `x`.
|
1936
1956
|
|
1957
|
+
Notes
|
1958
|
+
-----
|
1959
|
+
Note that the returned array is cached together with the method's call
|
1960
|
+
parameters to avoid unnecessary recalculations.
|
1937
1961
|
|
1938
1962
|
See Also
|
1939
1963
|
--------
|
@@ -1944,8 +1968,18 @@ class ShortTimeFFT:
|
|
1944
1968
|
fs: Sampling frequency (being ``1/T``)
|
1945
1969
|
ShortTimeFFT: Class this method belongs to.
|
1946
1970
|
"""
|
1971
|
+
if not (n > 0 and isinstance(n, int | np.integer)):
|
1972
|
+
raise ValueError(f"Parameter {n=} is not a positive integer!")
|
1973
|
+
args = n, p0, p1, k_offset, self.T # since `self.T` is mutable, it's needed too
|
1974
|
+
last_args, last_return_value = self._cache_t
|
1975
|
+
if args == last_args: # use cached value:
|
1976
|
+
return last_return_value
|
1977
|
+
|
1947
1978
|
p0, p1 = self.p_range(n, p0, p1)
|
1948
|
-
|
1979
|
+
return_value = np.arange(p0, p1) * self.delta_t + k_offset * self.T
|
1980
|
+
|
1981
|
+
self._cache_t = args, return_value
|
1982
|
+
return return_value
|
1949
1983
|
|
1950
1984
|
def nearest_k_p(self, k: int, left: bool = True) -> int:
|
1951
1985
|
"""Return nearest sample index k_p for which t[k_p] == t[p] holds.
|
@@ -2022,6 +2056,7 @@ class ShortTimeFFT:
|
|
2022
2056
|
"""Frequencies values of the STFT.
|
2023
2057
|
|
2024
2058
|
A 1d array of length `f_pts` with `delta_f` spaced entries is returned.
|
2059
|
+
This array is calculated lazily.
|
2025
2060
|
|
2026
2061
|
See Also
|
2027
2062
|
--------
|
@@ -2030,15 +2065,22 @@ class ShortTimeFFT:
|
|
2030
2065
|
mfft: Length of the input for FFT used.
|
2031
2066
|
ShortTimeFFT: Class this property belongs to.
|
2032
2067
|
"""
|
2068
|
+
last_state, last_return_value = self._cache_f
|
2069
|
+
current_state = self.fft_mode, self.mfft, self.T
|
2070
|
+
if current_state == last_state: # use cached value:
|
2071
|
+
return last_return_value
|
2072
|
+
|
2033
2073
|
if self.fft_mode in {'onesided', 'onesided2X'}:
|
2034
|
-
|
2074
|
+
return_value = fft_lib.rfftfreq(self.mfft, self.T)
|
2035
2075
|
elif self.fft_mode == 'twosided':
|
2036
|
-
|
2076
|
+
return_value = fft_lib.fftfreq(self.mfft, self.T)
|
2037
2077
|
elif self.fft_mode == 'centered':
|
2038
|
-
|
2039
|
-
# This should never happen but makes the Linters happy:
|
2040
|
-
|
2041
|
-
|
2078
|
+
return_value = fft_lib.fftshift(fft_lib.fftfreq(self.mfft, self.T))
|
2079
|
+
else: # This should never happen but makes the Linters happy:
|
2080
|
+
fft_modes = get_args(FFT_MODE_TYPE)
|
2081
|
+
raise RuntimeError(f"{self.fft_mode=} not in {fft_modes}!")
|
2082
|
+
self._cache_f = current_state, return_value
|
2083
|
+
return return_value
|
2042
2084
|
|
2043
2085
|
def _fft_func(self, x: np.ndarray) -> np.ndarray:
|
2044
2086
|
"""FFT based on the `fft_mode`, `mfft`, `scaling` and `phase_shift`
|
@@ -2095,8 +2137,7 @@ class ShortTimeFFT:
|
|
2095
2137
|
Xc[..., 1:q1] /= fac
|
2096
2138
|
x = fft_lib.irfft(Xc, n=self.mfft, axis=-1)
|
2097
2139
|
else: # This should never happen but makes the Linter happy:
|
2098
|
-
|
2099
|
-
raise RuntimeError(error_str)
|
2140
|
+
raise RuntimeError(f"{self.fft_mode=} not in {get_args(FFT_MODE_TYPE)}!")
|
2100
2141
|
|
2101
2142
|
if self.phase_shift is None:
|
2102
2143
|
return x[..., :self.m_num]
|
Binary file
|
scipy/signal/_spectral_py.py
CHANGED
@@ -243,11 +243,11 @@ def lombscargle(
|
|
243
243
|
)
|
244
244
|
|
245
245
|
# weight vector must sum to 1
|
246
|
-
weights
|
246
|
+
weights = weights * (1.0 / weights.sum())
|
247
247
|
|
248
248
|
# if requested, perform precenter
|
249
249
|
if precenter:
|
250
|
-
y
|
250
|
+
y = y - y.mean()
|
251
251
|
|
252
252
|
# transform arrays
|
253
253
|
# row vector
|
Binary file
|
@@ -531,11 +531,15 @@ def test_border_values():
|
|
531
531
|
assert SFT.p_max(10) == 4
|
532
532
|
assert SFT.k_max(10) == 16
|
533
533
|
assert SFT.upper_border_begin(10) == (4, 2)
|
534
|
+
assert SFT.upper_border_begin(10) == (4, 2) # needed to test caching
|
534
535
|
# Raise exceptions:
|
535
536
|
with pytest.raises(ValueError, match="^Parameter n must be"):
|
536
537
|
SFT.upper_border_begin(3)
|
537
538
|
with pytest.raises(ValueError, match="^Parameter n must be"):
|
538
539
|
SFT._post_padding(3)
|
540
|
+
with pytest.raises(RuntimeError):
|
541
|
+
SFT._hop = -1 # illegal hop interval
|
542
|
+
SFT.upper_border_begin(8)
|
539
543
|
|
540
544
|
def test_border_values_exotic():
|
541
545
|
"""Ensure that the border calculations are correct for windows with
|
@@ -573,6 +577,11 @@ def test_t():
|
|
573
577
|
SFT.fs = 1/8
|
574
578
|
assert SFT.fs == 1/8
|
575
579
|
assert SFT.T == 8
|
580
|
+
with pytest.raises(ValueError):
|
581
|
+
# noinspection PyTypeChecker
|
582
|
+
SFT.t(1.5) # only integers allowed
|
583
|
+
with pytest.raises(ValueError):
|
584
|
+
SFT.t(-1) # only positive `n` allowed
|
576
585
|
|
577
586
|
|
578
587
|
@pytest.mark.parametrize('fft_mode, f',
|
@@ -2084,7 +2084,9 @@ class _TestLinearFilter:
|
|
2084
2084
|
a = self.convert_dtype(a, xp)
|
2085
2085
|
x = self.convert_dtype(x, xp)
|
2086
2086
|
zi = self.convert_dtype(zi, xp)
|
2087
|
-
|
2087
|
+
# NOTE: MemoryError is currently allowed below because of:
|
2088
|
+
# https://github.com/numpy/numpy/issues/29721
|
2089
|
+
assert_raises((ValueError, MemoryError), lfilter, b, a, x, axis, zi)
|
2088
2090
|
|
2089
2091
|
@skip_xp_backends('cupy', reason='cupy does not raise')
|
2090
2092
|
def test_bad_size_zi(self, xp):
|
@@ -2134,7 +2136,11 @@ class _TestLinearFilter:
|
|
2134
2136
|
self.base_bad_size_zi([1, 1, 1], [1], x2, 0, [[0, 1, 2, 3], [4, 5, 6, 7]], xp)
|
2135
2137
|
|
2136
2138
|
self.base_bad_size_zi([1], [1, 1], x2, 0, [0, 1, 2], xp)
|
2137
|
-
|
2139
|
+
# this case is disabled on the release branch
|
2140
|
+
# because of:
|
2141
|
+
# https://github.com/scipy/scipy/pull/23543#issuecomment-3276286172
|
2142
|
+
# https://github.com/numpy/numpy/issues/29721
|
2143
|
+
#self.base_bad_size_zi([1], [1, 1], x2, 0, [[[0, 1, 2]]], xp)
|
2138
2144
|
self.base_bad_size_zi([1], [1, 1], x2, 0, [[0], [1], [2]], xp)
|
2139
2145
|
self.base_bad_size_zi([1], [1, 1], x2, 0, [[0, 1]], xp)
|
2140
2146
|
self.base_bad_size_zi([1], [1, 1], x2, 0, [[0, 1, 2, 3]], xp)
|