scipy 1.16.1__cp313-cp313-win_amd64.whl → 1.16.2__cp313-cp313-win_amd64.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.
Files changed (250) hide show
  1. scipy/__config__.py +12 -12
  2. scipy/__init__.py +4 -4
  3. scipy/_cyutility.cp313-win_amd64.dll.a +0 -0
  4. scipy/_cyutility.cp313-win_amd64.pyd +0 -0
  5. scipy/_lib/_ccallback_c.cp313-win_amd64.dll.a +0 -0
  6. scipy/_lib/_ccallback_c.cp313-win_amd64.pyd +0 -0
  7. scipy/_lib/_fpumode.cp313-win_amd64.dll.a +0 -0
  8. scipy/_lib/_fpumode.cp313-win_amd64.pyd +0 -0
  9. scipy/_lib/_test_ccallback.cp313-win_amd64.dll.a +0 -0
  10. scipy/_lib/_test_ccallback.cp313-win_amd64.pyd +0 -0
  11. scipy/_lib/_test_deprecation_call.cp313-win_amd64.dll.a +0 -0
  12. scipy/_lib/_test_deprecation_call.cp313-win_amd64.pyd +0 -0
  13. scipy/_lib/_test_deprecation_def.cp313-win_amd64.dll.a +0 -0
  14. scipy/_lib/_test_deprecation_def.cp313-win_amd64.pyd +0 -0
  15. scipy/_lib/_uarray/_uarray.cp313-win_amd64.dll.a +0 -0
  16. scipy/_lib/_uarray/_uarray.cp313-win_amd64.pyd +0 -0
  17. scipy/_lib/messagestream.cp313-win_amd64.dll.a +0 -0
  18. scipy/_lib/messagestream.cp313-win_amd64.pyd +0 -0
  19. scipy/cluster/_hierarchy.cp313-win_amd64.dll.a +0 -0
  20. scipy/cluster/_hierarchy.cp313-win_amd64.pyd +0 -0
  21. scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.dll.a +0 -0
  22. scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.pyd +0 -0
  23. scipy/cluster/_vq.cp313-win_amd64.dll.a +0 -0
  24. scipy/cluster/_vq.cp313-win_amd64.pyd +0 -0
  25. scipy/fft/_pocketfft/pypocketfft.cp313-win_amd64.dll.a +0 -0
  26. scipy/fft/_pocketfft/pypocketfft.cp313-win_amd64.pyd +0 -0
  27. scipy/fftpack/convolve.cp313-win_amd64.dll.a +0 -0
  28. scipy/fftpack/convolve.cp313-win_amd64.pyd +0 -0
  29. scipy/integrate/_dop.cp313-win_amd64.dll.a +0 -0
  30. scipy/integrate/_dop.cp313-win_amd64.pyd +0 -0
  31. scipy/integrate/_lsoda.cp313-win_amd64.dll.a +0 -0
  32. scipy/integrate/_lsoda.cp313-win_amd64.pyd +0 -0
  33. scipy/integrate/_odepack.cp313-win_amd64.dll.a +0 -0
  34. scipy/integrate/_odepack.cp313-win_amd64.pyd +0 -0
  35. scipy/integrate/_quadpack.cp313-win_amd64.dll.a +0 -0
  36. scipy/integrate/_quadpack.cp313-win_amd64.pyd +0 -0
  37. scipy/integrate/_test_multivariate.cp313-win_amd64.dll.a +0 -0
  38. scipy/integrate/_test_multivariate.cp313-win_amd64.pyd +0 -0
  39. scipy/integrate/_test_odeint_banded.cp313-win_amd64.dll.a +0 -0
  40. scipy/integrate/_test_odeint_banded.cp313-win_amd64.pyd +0 -0
  41. scipy/integrate/_vode.cp313-win_amd64.dll.a +0 -0
  42. scipy/integrate/_vode.cp313-win_amd64.pyd +0 -0
  43. scipy/interpolate/_dfitpack.cp313-win_amd64.dll.a +0 -0
  44. scipy/interpolate/_dfitpack.cp313-win_amd64.pyd +0 -0
  45. scipy/interpolate/_dierckx.cp313-win_amd64.dll.a +0 -0
  46. scipy/interpolate/_dierckx.cp313-win_amd64.pyd +0 -0
  47. scipy/interpolate/_fitpack.cp313-win_amd64.dll.a +0 -0
  48. scipy/interpolate/_fitpack.cp313-win_amd64.pyd +0 -0
  49. scipy/interpolate/_interpnd.cp313-win_amd64.dll.a +0 -0
  50. scipy/interpolate/_interpnd.cp313-win_amd64.pyd +0 -0
  51. scipy/interpolate/_ppoly.cp313-win_amd64.dll.a +0 -0
  52. scipy/interpolate/_ppoly.cp313-win_amd64.pyd +0 -0
  53. scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.dll.a +0 -0
  54. scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.pyd +0 -0
  55. scipy/interpolate/_rgi_cython.cp313-win_amd64.dll.a +0 -0
  56. scipy/interpolate/_rgi_cython.cp313-win_amd64.pyd +0 -0
  57. scipy/io/_fast_matrix_market/_fmm_core.cp313-win_amd64.dll.a +0 -0
  58. scipy/io/_fast_matrix_market/_fmm_core.cp313-win_amd64.pyd +0 -0
  59. scipy/io/_test_fortran.cp313-win_amd64.dll.a +0 -0
  60. scipy/io/_test_fortran.cp313-win_amd64.pyd +0 -0
  61. scipy/io/matlab/_mio5_utils.cp313-win_amd64.dll.a +0 -0
  62. scipy/io/matlab/_mio5_utils.cp313-win_amd64.pyd +0 -0
  63. scipy/io/matlab/_mio_utils.cp313-win_amd64.dll.a +0 -0
  64. scipy/io/matlab/_mio_utils.cp313-win_amd64.pyd +0 -0
  65. scipy/io/matlab/_streams.cp313-win_amd64.dll.a +0 -0
  66. scipy/io/matlab/_streams.cp313-win_amd64.pyd +0 -0
  67. scipy/linalg/_cythonized_array_utils.cp313-win_amd64.dll.a +0 -0
  68. scipy/linalg/_cythonized_array_utils.cp313-win_amd64.pyd +0 -0
  69. scipy/linalg/_decomp_interpolative.cp313-win_amd64.dll.a +0 -0
  70. scipy/linalg/_decomp_interpolative.cp313-win_amd64.pyd +0 -0
  71. scipy/linalg/_decomp_lu_cython.cp313-win_amd64.dll.a +0 -0
  72. scipy/linalg/_decomp_lu_cython.cp313-win_amd64.pyd +0 -0
  73. scipy/linalg/_decomp_update.cp313-win_amd64.dll.a +0 -0
  74. scipy/linalg/_decomp_update.cp313-win_amd64.pyd +0 -0
  75. scipy/linalg/_fblas.cp313-win_amd64.dll.a +0 -0
  76. scipy/linalg/_fblas.cp313-win_amd64.pyd +0 -0
  77. scipy/linalg/_flapack.cp313-win_amd64.dll.a +0 -0
  78. scipy/linalg/_flapack.cp313-win_amd64.pyd +0 -0
  79. scipy/linalg/_linalg_pythran.cp313-win_amd64.dll.a +0 -0
  80. scipy/linalg/_linalg_pythran.cp313-win_amd64.pyd +0 -0
  81. scipy/linalg/_matfuncs_expm.cp313-win_amd64.dll.a +0 -0
  82. scipy/linalg/_matfuncs_expm.cp313-win_amd64.pyd +0 -0
  83. scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.dll.a +0 -0
  84. scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.pyd +0 -0
  85. scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.dll.a +0 -0
  86. scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.pyd +0 -0
  87. scipy/linalg/_solve_toeplitz.cp313-win_amd64.dll.a +0 -0
  88. scipy/linalg/_solve_toeplitz.cp313-win_amd64.pyd +0 -0
  89. scipy/linalg/cython_blas.cp313-win_amd64.dll.a +0 -0
  90. scipy/linalg/cython_blas.cp313-win_amd64.pyd +0 -0
  91. scipy/linalg/cython_lapack.cp313-win_amd64.dll.a +0 -0
  92. scipy/linalg/cython_lapack.cp313-win_amd64.pyd +0 -0
  93. scipy/linalg/tests/test_lapack.py +5 -1
  94. scipy/ndimage/_ctest.cp313-win_amd64.dll.a +0 -0
  95. scipy/ndimage/_ctest.cp313-win_amd64.pyd +0 -0
  96. scipy/ndimage/_cytest.cp313-win_amd64.dll.a +0 -0
  97. scipy/ndimage/_cytest.cp313-win_amd64.pyd +0 -0
  98. scipy/ndimage/_nd_image.cp313-win_amd64.dll.a +0 -0
  99. scipy/ndimage/_nd_image.cp313-win_amd64.pyd +0 -0
  100. scipy/ndimage/_ni_label.cp313-win_amd64.dll.a +0 -0
  101. scipy/ndimage/_ni_label.cp313-win_amd64.pyd +0 -0
  102. scipy/ndimage/_rank_filter_1d.cp313-win_amd64.dll.a +0 -0
  103. scipy/ndimage/_rank_filter_1d.cp313-win_amd64.pyd +0 -0
  104. scipy/odr/__odrpack.cp313-win_amd64.dll.a +0 -0
  105. scipy/odr/__odrpack.cp313-win_amd64.pyd +0 -0
  106. scipy/optimize/_bglu_dense.cp313-win_amd64.dll.a +0 -0
  107. scipy/optimize/_bglu_dense.cp313-win_amd64.pyd +0 -0
  108. scipy/optimize/_direct.cp313-win_amd64.dll.a +0 -0
  109. scipy/optimize/_direct.cp313-win_amd64.pyd +0 -0
  110. scipy/optimize/_group_columns.cp313-win_amd64.dll.a +0 -0
  111. scipy/optimize/_group_columns.cp313-win_amd64.pyd +0 -0
  112. scipy/optimize/_highspy/_core.cp313-win_amd64.dll.a +0 -0
  113. scipy/optimize/_highspy/_core.cp313-win_amd64.pyd +0 -0
  114. scipy/optimize/_highspy/_highs_options.cp313-win_amd64.dll.a +0 -0
  115. scipy/optimize/_highspy/_highs_options.cp313-win_amd64.pyd +0 -0
  116. scipy/optimize/_lbfgsb.cp313-win_amd64.dll.a +0 -0
  117. scipy/optimize/_lbfgsb.cp313-win_amd64.pyd +0 -0
  118. scipy/optimize/_lbfgsb_py.py +2 -2
  119. scipy/optimize/_lsap.cp313-win_amd64.dll.a +0 -0
  120. scipy/optimize/_lsap.cp313-win_amd64.pyd +0 -0
  121. scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.dll.a +0 -0
  122. scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.pyd +0 -0
  123. scipy/optimize/_minpack.cp313-win_amd64.dll.a +0 -0
  124. scipy/optimize/_minpack.cp313-win_amd64.pyd +0 -0
  125. scipy/optimize/_moduleTNC.cp313-win_amd64.dll.a +0 -0
  126. scipy/optimize/_moduleTNC.cp313-win_amd64.pyd +0 -0
  127. scipy/optimize/_pava_pybind.cp313-win_amd64.dll.a +0 -0
  128. scipy/optimize/_pava_pybind.cp313-win_amd64.pyd +0 -0
  129. scipy/optimize/_slsqp_py.py +5 -5
  130. scipy/optimize/_slsqplib.cp313-win_amd64.dll.a +0 -0
  131. scipy/optimize/_slsqplib.cp313-win_amd64.pyd +0 -0
  132. scipy/optimize/_trlib/_trlib.cp313-win_amd64.dll.a +0 -0
  133. scipy/optimize/_trlib/_trlib.cp313-win_amd64.pyd +0 -0
  134. scipy/optimize/_zeros.cp313-win_amd64.dll.a +0 -0
  135. scipy/optimize/_zeros.cp313-win_amd64.pyd +0 -0
  136. scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.dll.a +0 -0
  137. scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.pyd +0 -0
  138. scipy/optimize/tests/test_optimize.py +9 -0
  139. scipy/signal/_max_len_seq_inner.cp313-win_amd64.dll.a +0 -0
  140. scipy/signal/_max_len_seq_inner.cp313-win_amd64.pyd +0 -0
  141. scipy/signal/_peak_finding_utils.cp313-win_amd64.dll.a +0 -0
  142. scipy/signal/_peak_finding_utils.cp313-win_amd64.pyd +0 -0
  143. scipy/signal/_short_time_fft.py +74 -33
  144. scipy/signal/_sigtools.cp313-win_amd64.dll.a +0 -0
  145. scipy/signal/_sigtools.cp313-win_amd64.pyd +0 -0
  146. scipy/signal/_sosfilt.cp313-win_amd64.dll.a +0 -0
  147. scipy/signal/_sosfilt.cp313-win_amd64.pyd +0 -0
  148. scipy/signal/_spectral_py.py +2 -2
  149. scipy/signal/_spline.cp313-win_amd64.dll.a +0 -0
  150. scipy/signal/_spline.cp313-win_amd64.pyd +0 -0
  151. scipy/signal/_upfirdn_apply.cp313-win_amd64.dll.a +0 -0
  152. scipy/signal/_upfirdn_apply.cp313-win_amd64.pyd +0 -0
  153. scipy/signal/tests/test_short_time_fft.py +9 -0
  154. scipy/signal/tests/test_signaltools.py +8 -2
  155. scipy/signal/tests/test_spectral.py +39 -1
  156. scipy/sparse/_csparsetools.cp313-win_amd64.dll.a +0 -0
  157. scipy/sparse/_csparsetools.cp313-win_amd64.pyd +0 -0
  158. scipy/sparse/_sparsetools.cp313-win_amd64.dll.a +0 -0
  159. scipy/sparse/_sparsetools.cp313-win_amd64.pyd +0 -0
  160. scipy/sparse/csgraph/_flow.cp313-win_amd64.dll.a +0 -0
  161. scipy/sparse/csgraph/_flow.cp313-win_amd64.pyd +0 -0
  162. scipy/sparse/csgraph/_matching.cp313-win_amd64.dll.a +0 -0
  163. scipy/sparse/csgraph/_matching.cp313-win_amd64.pyd +0 -0
  164. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.dll.a +0 -0
  165. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.pyd +0 -0
  166. scipy/sparse/csgraph/_reordering.cp313-win_amd64.dll.a +0 -0
  167. scipy/sparse/csgraph/_reordering.cp313-win_amd64.pyd +0 -0
  168. scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.dll.a +0 -0
  169. scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.pyd +0 -0
  170. scipy/sparse/csgraph/_tools.cp313-win_amd64.dll.a +0 -0
  171. scipy/sparse/csgraph/_tools.cp313-win_amd64.pyd +0 -0
  172. scipy/sparse/csgraph/_traversal.cp313-win_amd64.dll.a +0 -0
  173. scipy/sparse/csgraph/_traversal.cp313-win_amd64.pyd +0 -0
  174. scipy/sparse/linalg/_dsolve/_superlu.cp313-win_amd64.dll.a +0 -0
  175. scipy/sparse/linalg/_dsolve/_superlu.cp313-win_amd64.pyd +0 -0
  176. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-win_amd64.dll.a +0 -0
  177. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-win_amd64.pyd +0 -0
  178. scipy/sparse/linalg/_propack/_cpropack.cp313-win_amd64.dll.a +0 -0
  179. scipy/sparse/linalg/_propack/_cpropack.cp313-win_amd64.pyd +0 -0
  180. scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.dll.a +0 -0
  181. scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.pyd +0 -0
  182. scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.dll.a +0 -0
  183. scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.pyd +0 -0
  184. scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.dll.a +0 -0
  185. scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.pyd +0 -0
  186. scipy/spatial/_ckdtree.cp313-win_amd64.dll.a +0 -0
  187. scipy/spatial/_ckdtree.cp313-win_amd64.pyd +0 -0
  188. scipy/spatial/_distance_pybind.cp313-win_amd64.dll.a +0 -0
  189. scipy/spatial/_distance_pybind.cp313-win_amd64.pyd +0 -0
  190. scipy/spatial/_distance_wrap.cp313-win_amd64.dll.a +0 -0
  191. scipy/spatial/_distance_wrap.cp313-win_amd64.pyd +0 -0
  192. scipy/spatial/_hausdorff.cp313-win_amd64.dll.a +0 -0
  193. scipy/spatial/_hausdorff.cp313-win_amd64.pyd +0 -0
  194. scipy/spatial/_qhull.cp313-win_amd64.dll.a +0 -0
  195. scipy/spatial/_qhull.cp313-win_amd64.pyd +0 -0
  196. scipy/spatial/_voronoi.cp313-win_amd64.dll.a +0 -0
  197. scipy/spatial/_voronoi.cp313-win_amd64.pyd +0 -0
  198. scipy/spatial/qhull_src/COPYING_QHULL.txt +39 -0
  199. scipy/spatial/tests/test_distance.py +5 -4
  200. scipy/spatial/transform/_rigid_transform.cp313-win_amd64.dll.a +0 -0
  201. scipy/spatial/transform/_rigid_transform.cp313-win_amd64.pyd +0 -0
  202. scipy/spatial/transform/_rotation.cp313-win_amd64.dll.a +0 -0
  203. scipy/spatial/transform/_rotation.cp313-win_amd64.pyd +0 -0
  204. scipy/special/_comb.cp313-win_amd64.dll.a +0 -0
  205. scipy/special/_comb.cp313-win_amd64.pyd +0 -0
  206. scipy/special/_ellip_harm_2.cp313-win_amd64.dll.a +0 -0
  207. scipy/special/_ellip_harm_2.cp313-win_amd64.pyd +0 -0
  208. scipy/special/_gufuncs.cp313-win_amd64.dll.a +0 -0
  209. scipy/special/_gufuncs.cp313-win_amd64.pyd +0 -0
  210. scipy/special/_specfun.cp313-win_amd64.dll.a +0 -0
  211. scipy/special/_specfun.cp313-win_amd64.pyd +0 -0
  212. scipy/special/_special_ufuncs.cp313-win_amd64.dll.a +0 -0
  213. scipy/special/_special_ufuncs.cp313-win_amd64.pyd +0 -0
  214. scipy/special/_test_internal.cp313-win_amd64.dll.a +0 -0
  215. scipy/special/_test_internal.cp313-win_amd64.pyd +0 -0
  216. scipy/special/_ufuncs.cp313-win_amd64.dll.a +0 -0
  217. scipy/special/_ufuncs.cp313-win_amd64.pyd +0 -0
  218. scipy/special/_ufuncs_cxx.cp313-win_amd64.dll.a +0 -0
  219. scipy/special/_ufuncs_cxx.cp313-win_amd64.pyd +0 -0
  220. scipy/special/cython_special.cp313-win_amd64.dll.a +0 -0
  221. scipy/special/cython_special.cp313-win_amd64.pyd +0 -0
  222. scipy/stats/_ansari_swilk_statistics.cp313-win_amd64.dll.a +0 -0
  223. scipy/stats/_ansari_swilk_statistics.cp313-win_amd64.pyd +0 -0
  224. scipy/stats/_biasedurn.cp313-win_amd64.dll.a +0 -0
  225. scipy/stats/_biasedurn.cp313-win_amd64.pyd +0 -0
  226. scipy/stats/_levy_stable/levyst.cp313-win_amd64.dll.a +0 -0
  227. scipy/stats/_levy_stable/levyst.cp313-win_amd64.pyd +0 -0
  228. scipy/stats/_qmc_cy.cp313-win_amd64.dll.a +0 -0
  229. scipy/stats/_qmc_cy.cp313-win_amd64.pyd +0 -0
  230. scipy/stats/_qmvnt_cy.cp313-win_amd64.dll.a +0 -0
  231. scipy/stats/_qmvnt_cy.cp313-win_amd64.pyd +0 -0
  232. scipy/stats/_rcont/rcont.cp313-win_amd64.dll.a +0 -0
  233. scipy/stats/_rcont/rcont.cp313-win_amd64.pyd +0 -0
  234. scipy/stats/_sobol.cp313-win_amd64.dll.a +0 -0
  235. scipy/stats/_sobol.cp313-win_amd64.pyd +0 -0
  236. scipy/stats/_stats.cp313-win_amd64.dll.a +0 -0
  237. scipy/stats/_stats.cp313-win_amd64.pyd +0 -0
  238. scipy/stats/_stats_pythran.cp313-win_amd64.dll.a +0 -0
  239. scipy/stats/_stats_pythran.cp313-win_amd64.pyd +0 -0
  240. scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.dll.a +0 -0
  241. scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.pyd +0 -0
  242. scipy/version.py +2 -2
  243. scipy-1.16.2.dist-info/DELVEWHEEL +2 -0
  244. {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/METADATA +2 -2
  245. {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/RECORD +249 -248
  246. scipy.libs/{libscipy_openblas-6b2103f2ae4d8547998b5d188e9801fb.dll → libscipy_openblas-48c358d105077551cc9cc3ba79387ed5.dll} +0 -0
  247. scipy-1.16.1.dist-info/DELVEWHEEL +0 -2
  248. /scipy-1.16.1-cp313-cp313-win_amd64.whl → /scipy-1.16.2-cp313-cp313-win_amd64.whl +0 -0
  249. {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/LICENSE.txt +0 -0
  250. {scipy-1.16.1.dist-info → scipy-1.16.2.dist-info}/WHEEL +0 -0
@@ -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 2023-07)
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 cache, lru_cache, partial
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
- @cache
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 q_, n_ in enumerate(range(n0, n0-self.m_num-1, -self.hop)):
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_, -q_
1624
- raise RuntimeError("This is code line should not have been reached!")
1625
- # If this case is reached, it probably means the first slice should be
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()[0]
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()[1]
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
- return k_ + self.m_num, q_ + 1
1695
- raise RuntimeError("This is code line should not have been reached!")
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
- return (q_ + 1) * self.hop - self.m_num_mid, q_ + 1
1847
- return 0, 0 # border starts at first slice
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
- return np.arange(p0, p1) * self.delta_t + k_offset * self.T
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
- return fft_lib.rfftfreq(self.mfft, self.T)
2074
+ return_value = fft_lib.rfftfreq(self.mfft, self.T)
2035
2075
  elif self.fft_mode == 'twosided':
2036
- return fft_lib.fftfreq(self.mfft, self.T)
2076
+ return_value = fft_lib.fftfreq(self.mfft, self.T)
2037
2077
  elif self.fft_mode == 'centered':
2038
- return fft_lib.fftshift(fft_lib.fftfreq(self.mfft, self.T))
2039
- # This should never happen but makes the Linters happy:
2040
- fft_modes = get_args(FFT_MODE_TYPE)
2041
- raise RuntimeError(f"{self.fft_mode=} not in {fft_modes}!")
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
- error_str = f"{self.fft_mode=} not in {get_args(FFT_MODE_TYPE)}!"
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
Binary file
Binary file
@@ -243,11 +243,11 @@ def lombscargle(
243
243
  )
244
244
 
245
245
  # weight vector must sum to 1
246
- weights *= 1.0 / weights.sum()
246
+ weights = weights * (1.0 / weights.sum())
247
247
 
248
248
  # if requested, perform precenter
249
249
  if precenter:
250
- y -= y.mean()
250
+ y = y - y.mean()
251
251
 
252
252
  # transform arrays
253
253
  # row vector
Binary file
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
- assert_raises(ValueError, lfilter, b, a, x, axis, zi)
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
- self.base_bad_size_zi([1], [1, 1], x2, 0, [[[0, 1, 2]]], xp)
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)
@@ -1055,7 +1055,6 @@ class TestLombscargle:
1055
1055
  delta = f[1] - f[0]
1056
1056
  assert(w - f[np.argmax(P)] < (delta/2.))
1057
1057
 
1058
-
1059
1058
  def test_amplitude(self):
1060
1059
  # Test if height of peak in unnormalized Lomb-Scargle periodogram
1061
1060
  # corresponds to amplitude of the generated input signal.
@@ -1503,6 +1502,45 @@ class TestLombscargle:
1503
1502
 
1504
1503
  lombscargle(t, y, freqs)
1505
1504
 
1505
+ def test_input_mutation(self):
1506
+ # this tests for mutation of the input arrays
1507
+ # https://github.com/scipy/scipy/issues/23474
1508
+
1509
+ # Input parameters
1510
+ ampl = 2.
1511
+ w = 1.
1512
+ phi = 0.5 * np.pi
1513
+ nin = 100
1514
+ nout = 1000
1515
+ p = 0.7 # Fraction of points to select
1516
+
1517
+ # Randomly select a fraction of an array with timesteps
1518
+ rng = np.random.default_rng()
1519
+ r = rng.random(nin)
1520
+ t = np.linspace(0.01*np.pi, 10.*np.pi, nin)[r >= p]
1521
+
1522
+ # Plot a sine wave for the selected times
1523
+ y = ampl * np.sin(w*t + phi)
1524
+
1525
+ # Define the array of frequencies for which to compute the periodogram
1526
+ f = np.linspace(0.01, 10., nout)
1527
+
1528
+ weights = np.ones_like(y)
1529
+
1530
+ # create original copies before passing
1531
+ t_org = t.copy()
1532
+ y_org = y.copy()
1533
+ f_org = f.copy()
1534
+ weights_org = weights.copy()
1535
+
1536
+ lombscargle(t, y, f, precenter=True, weights=weights)
1537
+
1538
+ # check all 4 array inputs
1539
+ assert_array_equal(t, t_org)
1540
+ assert_array_equal(y, y_org)
1541
+ assert_array_equal(f, f_org)
1542
+ assert_array_equal(weights, weights_org)
1543
+
1506
1544
 
1507
1545
  class TestSTFT:
1508
1546
  @pytest.mark.thread_unsafe
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,39 @@
1
+ Qhull, Copyright (c) 1993-2020
2
+
3
+ C.B. Barber
4
+ Arlington, MA
5
+
6
+ and
7
+
8
+ The National Science and Technology Research Center for
9
+ Computation and Visualization of Geometric Structures
10
+ (The Geometry Center)
11
+ University of Minnesota
12
+
13
+ email: qhull@qhull.org
14
+
15
+ This software includes Qhull from C.B. Barber and The Geometry Center.
16
+ Files derived from Qhull 1.0 are copyrighted by the Geometry Center. The
17
+ remaining files are copyrighted by C.B. Barber. Qhull is free software
18
+ and may be obtained via http from www.qhull.org. It may be freely copied,
19
+ modified, and redistributed under the following conditions:
20
+
21
+ 1. All copyright notices must remain intact in all files.
22
+
23
+ 2. A copy of this text file must be distributed along with any copies
24
+ of Qhull that you redistribute; this includes copies that you have
25
+ modified, or copies of programs or other software products that
26
+ include Qhull.
27
+
28
+ 3. If you modify Qhull, you must include a notice giving the
29
+ name of the person performing the modification, the date of
30
+ modification, and the reason for such modification.
31
+
32
+ 4. When distributing modified versions of Qhull, or other software
33
+ products that include Qhull, you must provide notice that the original
34
+ source code may be obtained as noted above.
35
+
36
+ 5. There is no warranty or other guarantee of fitness for Qhull, it is
37
+ provided solely "as is". Bug reports or fixes may be sent to
38
+ qhull_bug@qhull.org; the authors may or may not act on them as
39
+ they desire.
@@ -32,14 +32,14 @@
32
32
  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
33
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
 
35
- import sys
36
- import os.path
37
-
38
35
  from functools import wraps, partial
36
+ import os.path
37
+ import sys
38
+ import sysconfig
39
+ import warnings
39
40
  import weakref
40
41
 
41
42
  import numpy as np
42
- import warnings
43
43
  from numpy.linalg import norm
44
44
  from numpy.testing import (verbose, assert_,
45
45
  assert_array_equal, assert_equal,
@@ -632,6 +632,7 @@ class TestCdist:
632
632
  assert_allclose(y1, y2, rtol=eps, verbose=verbose > 2)
633
633
 
634
634
  @pytest.mark.thread_unsafe
635
+ @pytest.mark.skipif(sysconfig.get_platform() == 'win-arm64', reason="numpy#29442")
635
636
  def test_cdist_out(self, metric):
636
637
  # Test that out parameter works properly
637
638
  eps = 1e-15
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file