scipy 1.15.3__cp312-cp312-macosx_12_0_arm64.whl → 1.16.0rc1__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.
Files changed (613) hide show
  1. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  2. scipy/__config__.py +7 -7
  3. scipy/__init__.py +3 -6
  4. scipy/_cyutility.cpython-312-darwin.so +0 -0
  5. scipy/_lib/_array_api.py +486 -161
  6. scipy/_lib/_array_api_compat_vendor.py +9 -0
  7. scipy/_lib/_bunch.py +4 -0
  8. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  9. scipy/_lib/_docscrape.py +1 -1
  10. scipy/_lib/_elementwise_iterative_method.py +15 -26
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +166 -35
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +263 -157
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  127. scipy/integrate/_ode.py +9 -2
  128. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_quad_vec.py +21 -29
  130. scipy/integrate/_quadpack_py.py +11 -7
  131. scipy/integrate/_quadrature.py +3 -3
  132. scipy/integrate/_rules/_base.py +2 -2
  133. scipy/integrate/_tanhsinh.py +48 -47
  134. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  136. scipy/integrate/tests/test__quad_vec.py +0 -6
  137. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  138. scipy/integrate/tests/test_cubature.py +21 -35
  139. scipy/integrate/tests/test_quadrature.py +6 -8
  140. scipy/integrate/tests/test_tanhsinh.py +56 -48
  141. scipy/interpolate/__init__.py +70 -58
  142. scipy/interpolate/_bary_rational.py +22 -22
  143. scipy/interpolate/_bsplines.py +119 -66
  144. scipy/interpolate/_cubic.py +65 -50
  145. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  146. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_fitpack2.py +9 -6
  148. scipy/interpolate/_fitpack_impl.py +32 -26
  149. scipy/interpolate/_fitpack_repro.py +23 -19
  150. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  151. scipy/interpolate/_interpolate.py +30 -12
  152. scipy/interpolate/_ndbspline.py +13 -18
  153. scipy/interpolate/_ndgriddata.py +5 -8
  154. scipy/interpolate/_polyint.py +95 -31
  155. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  156. scipy/interpolate/_rbf.py +2 -2
  157. scipy/interpolate/_rbfinterp.py +1 -1
  158. scipy/interpolate/_rgi.py +31 -26
  159. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  160. scipy/interpolate/dfitpack.py +0 -20
  161. scipy/interpolate/interpnd.py +1 -2
  162. scipy/interpolate/tests/test_bary_rational.py +2 -2
  163. scipy/interpolate/tests/test_bsplines.py +97 -1
  164. scipy/interpolate/tests/test_fitpack2.py +39 -1
  165. scipy/interpolate/tests/test_interpnd.py +32 -20
  166. scipy/interpolate/tests/test_interpolate.py +48 -4
  167. scipy/interpolate/tests/test_rgi.py +2 -1
  168. scipy/io/_fast_matrix_market/__init__.py +2 -0
  169. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  170. scipy/io/_harwell_boeing/hb.py +7 -11
  171. scipy/io/_idl.py +5 -7
  172. scipy/io/_netcdf.py +15 -5
  173. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  174. scipy/io/arff/tests/test_arffread.py +3 -3
  175. scipy/io/matlab/__init__.py +5 -3
  176. scipy/io/matlab/_mio.py +4 -1
  177. scipy/io/matlab/_mio5.py +19 -13
  178. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  179. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  180. scipy/io/matlab/_miobase.py +4 -1
  181. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/tests/test_mio.py +46 -18
  183. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  184. scipy/io/tests/test_mmio.py +7 -1
  185. scipy/io/tests/test_wavfile.py +41 -0
  186. scipy/io/wavfile.py +57 -10
  187. scipy/linalg/_basic.py +113 -86
  188. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  189. scipy/linalg/_decomp.py +22 -9
  190. scipy/linalg/_decomp_cholesky.py +28 -13
  191. scipy/linalg/_decomp_cossin.py +45 -30
  192. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  193. scipy/linalg/_decomp_ldl.py +4 -1
  194. scipy/linalg/_decomp_lu.py +18 -6
  195. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  196. scipy/linalg/_decomp_polar.py +2 -0
  197. scipy/linalg/_decomp_qr.py +6 -2
  198. scipy/linalg/_decomp_qz.py +3 -0
  199. scipy/linalg/_decomp_schur.py +3 -1
  200. scipy/linalg/_decomp_svd.py +13 -2
  201. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  202. scipy/linalg/_expm_frechet.py +4 -0
  203. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  204. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_matfuncs.py +187 -4
  206. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  209. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  210. scipy/linalg/_procrustes.py +2 -0
  211. scipy/linalg/_sketches.py +17 -6
  212. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_solvers.py +7 -2
  214. scipy/linalg/_special_matrices.py +26 -36
  215. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  216. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  217. scipy/linalg/lapack.py +22 -2
  218. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  219. scipy/linalg/tests/test_basic.py +31 -16
  220. scipy/linalg/tests/test_batch.py +588 -0
  221. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  222. scipy/linalg/tests/test_decomp.py +40 -3
  223. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  224. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  225. scipy/linalg/tests/test_lapack.py +115 -7
  226. scipy/linalg/tests/test_matfuncs.py +157 -102
  227. scipy/linalg/tests/test_procrustes.py +0 -7
  228. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  229. scipy/linalg/tests/test_special_matrices.py +1 -5
  230. scipy/ndimage/__init__.py +1 -0
  231. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  232. scipy/ndimage/_delegators.py +8 -2
  233. scipy/ndimage/_filters.py +433 -5
  234. scipy/ndimage/_interpolation.py +36 -6
  235. scipy/ndimage/_measurements.py +4 -2
  236. scipy/ndimage/_morphology.py +5 -0
  237. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  238. scipy/ndimage/_ni_docstrings.py +5 -1
  239. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  240. scipy/ndimage/_ni_support.py +1 -5
  241. scipy/ndimage/_support_alternative_backends.py +18 -6
  242. scipy/ndimage/tests/test_filters.py +337 -259
  243. scipy/ndimage/tests/test_fourier.py +7 -9
  244. scipy/ndimage/tests/test_interpolation.py +68 -61
  245. scipy/ndimage/tests/test_measurements.py +18 -35
  246. scipy/ndimage/tests/test_morphology.py +143 -131
  247. scipy/ndimage/tests/test_splines.py +1 -3
  248. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  249. scipy/optimize/_basinhopping.py +13 -7
  250. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  251. scipy/optimize/_bracket.py +17 -24
  252. scipy/optimize/_chandrupatla.py +9 -10
  253. scipy/optimize/_cobyla_py.py +104 -123
  254. scipy/optimize/_constraints.py +14 -10
  255. scipy/optimize/_differentiable_functions.py +371 -230
  256. scipy/optimize/_differentialevolution.py +4 -3
  257. scipy/optimize/_dual_annealing.py +1 -1
  258. scipy/optimize/_elementwise.py +1 -4
  259. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  260. scipy/optimize/_lbfgsb_py.py +57 -16
  261. scipy/optimize/_linprog_doc.py +2 -2
  262. scipy/optimize/_linprog_highs.py +2 -2
  263. scipy/optimize/_linprog_ip.py +25 -10
  264. scipy/optimize/_linprog_util.py +14 -16
  265. scipy/optimize/_lsq/common.py +3 -3
  266. scipy/optimize/_lsq/dogbox.py +16 -2
  267. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  268. scipy/optimize/_lsq/least_squares.py +198 -126
  269. scipy/optimize/_lsq/lsq_linear.py +6 -6
  270. scipy/optimize/_lsq/trf.py +35 -8
  271. scipy/optimize/_milp.py +3 -1
  272. scipy/optimize/_minimize.py +105 -36
  273. scipy/optimize/_minpack_py.py +21 -14
  274. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_nnls.py +20 -21
  276. scipy/optimize/_nonlin.py +34 -3
  277. scipy/optimize/_numdiff.py +288 -110
  278. scipy/optimize/_optimize.py +86 -48
  279. scipy/optimize/_remove_redundancy.py +5 -5
  280. scipy/optimize/_root_scalar.py +1 -1
  281. scipy/optimize/_shgo.py +6 -0
  282. scipy/optimize/_shgo_lib/_complex.py +1 -1
  283. scipy/optimize/_slsqp_py.py +216 -124
  284. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  285. scipy/optimize/_spectral.py +1 -1
  286. scipy/optimize/_tnc.py +8 -1
  287. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  288. scipy/optimize/_trustregion.py +20 -6
  289. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  290. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  291. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  292. scipy/optimize/_trustregion_constr/projections.py +12 -8
  293. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  294. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  295. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  296. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  297. scipy/optimize/_trustregion_exact.py +0 -1
  298. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  299. scipy/optimize/_zeros_py.py +97 -17
  300. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  301. scipy/optimize/slsqp.py +0 -1
  302. scipy/optimize/tests/test__basinhopping.py +1 -1
  303. scipy/optimize/tests/test__differential_evolution.py +4 -4
  304. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  305. scipy/optimize/tests/test__numdiff.py +66 -22
  306. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  307. scipy/optimize/tests/test__shgo.py +9 -1
  308. scipy/optimize/tests/test_bracket.py +36 -46
  309. scipy/optimize/tests/test_chandrupatla.py +133 -135
  310. scipy/optimize/tests/test_cobyla.py +74 -45
  311. scipy/optimize/tests/test_constraints.py +1 -1
  312. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  313. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  314. scipy/optimize/tests/test_least_squares.py +125 -13
  315. scipy/optimize/tests/test_linear_assignment.py +3 -3
  316. scipy/optimize/tests/test_linprog.py +3 -3
  317. scipy/optimize/tests/test_lsq_linear.py +5 -5
  318. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  319. scipy/optimize/tests/test_minpack.py +4 -4
  320. scipy/optimize/tests/test_nnls.py +43 -3
  321. scipy/optimize/tests/test_nonlin.py +36 -0
  322. scipy/optimize/tests/test_optimize.py +95 -17
  323. scipy/optimize/tests/test_slsqp.py +36 -4
  324. scipy/optimize/tests/test_zeros.py +34 -1
  325. scipy/signal/__init__.py +12 -23
  326. scipy/signal/_delegators.py +568 -0
  327. scipy/signal/_filter_design.py +459 -241
  328. scipy/signal/_fir_filter_design.py +262 -90
  329. scipy/signal/_lti_conversion.py +3 -2
  330. scipy/signal/_ltisys.py +118 -91
  331. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  332. scipy/signal/_polyutils.py +172 -0
  333. scipy/signal/_short_time_fft.py +519 -70
  334. scipy/signal/_signal_api.py +30 -0
  335. scipy/signal/_signaltools.py +719 -399
  336. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  337. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  338. scipy/signal/_spectral_py.py +221 -50
  339. scipy/signal/_spline_filters.py +108 -68
  340. scipy/signal/_support_alternative_backends.py +73 -0
  341. scipy/signal/_upfirdn.py +4 -1
  342. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  343. scipy/signal/_waveforms.py +2 -11
  344. scipy/signal/_wavelets.py +1 -1
  345. scipy/signal/fir_filter_design.py +1 -0
  346. scipy/signal/spline.py +4 -11
  347. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  348. scipy/signal/tests/test_bsplines.py +114 -79
  349. scipy/signal/tests/test_cont2discrete.py +9 -2
  350. scipy/signal/tests/test_filter_design.py +721 -481
  351. scipy/signal/tests/test_fir_filter_design.py +332 -140
  352. scipy/signal/tests/test_savitzky_golay.py +4 -3
  353. scipy/signal/tests/test_short_time_fft.py +221 -3
  354. scipy/signal/tests/test_signaltools.py +2144 -1348
  355. scipy/signal/tests/test_spectral.py +19 -6
  356. scipy/signal/tests/test_splines.py +161 -96
  357. scipy/signal/tests/test_upfirdn.py +84 -50
  358. scipy/signal/tests/test_waveforms.py +20 -0
  359. scipy/signal/tests/test_windows.py +607 -466
  360. scipy/signal/windows/_windows.py +287 -148
  361. scipy/sparse/__init__.py +23 -4
  362. scipy/sparse/_base.py +270 -108
  363. scipy/sparse/_bsr.py +7 -4
  364. scipy/sparse/_compressed.py +59 -231
  365. scipy/sparse/_construct.py +90 -38
  366. scipy/sparse/_coo.py +115 -181
  367. scipy/sparse/_csc.py +4 -4
  368. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  369. scipy/sparse/_csr.py +2 -2
  370. scipy/sparse/_data.py +48 -48
  371. scipy/sparse/_dia.py +105 -18
  372. scipy/sparse/_dok.py +0 -23
  373. scipy/sparse/_index.py +4 -4
  374. scipy/sparse/_matrix.py +23 -0
  375. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  376. scipy/sparse/_sputils.py +37 -22
  377. scipy/sparse/base.py +0 -9
  378. scipy/sparse/bsr.py +0 -14
  379. scipy/sparse/compressed.py +0 -23
  380. scipy/sparse/construct.py +0 -6
  381. scipy/sparse/coo.py +0 -14
  382. scipy/sparse/csc.py +0 -3
  383. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  384. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  385. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  386. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  387. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  388. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  389. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  390. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  391. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  392. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  393. scipy/sparse/csr.py +0 -5
  394. scipy/sparse/data.py +1 -6
  395. scipy/sparse/dia.py +0 -7
  396. scipy/sparse/dok.py +0 -10
  397. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  398. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  399. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  400. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  401. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  402. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  403. scipy/sparse/linalg/_interface.py +17 -18
  404. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  405. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  406. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  407. scipy/sparse/linalg/_isolve/minres.py +5 -5
  408. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  409. scipy/sparse/linalg/_isolve/utils.py +2 -8
  410. scipy/sparse/linalg/_matfuncs.py +1 -1
  411. scipy/sparse/linalg/_norm.py +1 -1
  412. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  413. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  414. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  415. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  416. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  417. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  418. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  419. scipy/sparse/tests/test_base.py +207 -42
  420. scipy/sparse/tests/test_common1d.py +7 -7
  421. scipy/sparse/tests/test_construct.py +1 -1
  422. scipy/sparse/tests/test_coo.py +272 -4
  423. scipy/sparse/tests/test_sparsetools.py +5 -0
  424. scipy/sparse/tests/test_sputils.py +36 -7
  425. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  426. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  427. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  428. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  429. scipy/spatial/distance.py +49 -42
  430. scipy/spatial/tests/test_distance.py +3 -1
  431. scipy/spatial/tests/test_kdtree.py +1 -0
  432. scipy/spatial/tests/test_qhull.py +7 -2
  433. scipy/spatial/transform/__init__.py +5 -3
  434. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  435. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  436. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  437. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  438. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  439. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  440. scipy/special/__init__.py +1 -47
  441. scipy/special/_add_newdocs.py +34 -772
  442. scipy/special/_basic.py +22 -25
  443. scipy/special/_comb.cpython-312-darwin.so +0 -0
  444. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  445. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  446. scipy/special/_logsumexp.py +67 -58
  447. scipy/special/_orthogonal.pyi +1 -1
  448. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  449. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  450. scipy/special/_spherical_bessel.py +4 -4
  451. scipy/special/_support_alternative_backends.py +212 -119
  452. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  453. scipy/special/_testutils.py +4 -4
  454. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  455. scipy/special/_ufuncs.pyi +1 -0
  456. scipy/special/_ufuncs.pyx +215 -1400
  457. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  458. scipy/special/_ufuncs_cxx.pxd +2 -15
  459. scipy/special/_ufuncs_cxx.pyx +5 -44
  460. scipy/special/_ufuncs_cxx_defs.h +2 -16
  461. scipy/special/_ufuncs_defs.h +0 -8
  462. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  463. scipy/special/cython_special.pxd +1 -1
  464. scipy/special/tests/_cython_examples/meson.build +10 -1
  465. scipy/special/tests/test_basic.py +153 -20
  466. scipy/special/tests/test_boost_ufuncs.py +3 -0
  467. scipy/special/tests/test_cdflib.py +35 -11
  468. scipy/special/tests/test_gammainc.py +16 -0
  469. scipy/special/tests/test_hyp2f1.py +2 -2
  470. scipy/special/tests/test_log1mexp.py +85 -0
  471. scipy/special/tests/test_logsumexp.py +206 -64
  472. scipy/special/tests/test_mpmath.py +1 -0
  473. scipy/special/tests/test_nan_inputs.py +1 -1
  474. scipy/special/tests/test_orthogonal.py +17 -18
  475. scipy/special/tests/test_sf_error.py +3 -2
  476. scipy/special/tests/test_sph_harm.py +6 -7
  477. scipy/special/tests/test_support_alternative_backends.py +211 -76
  478. scipy/stats/__init__.py +4 -1
  479. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  480. scipy/stats/_axis_nan_policy.py +4 -3
  481. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  482. scipy/stats/_continued_fraction.py +387 -0
  483. scipy/stats/_continuous_distns.py +277 -310
  484. scipy/stats/_covariance.py +6 -3
  485. scipy/stats/_discrete_distns.py +39 -32
  486. scipy/stats/_distn_infrastructure.py +39 -12
  487. scipy/stats/_distribution_infrastructure.py +900 -238
  488. scipy/stats/_entropy.py +7 -8
  489. scipy/{_lib → stats}/_finite_differences.py +1 -1
  490. scipy/stats/_hypotests.py +82 -49
  491. scipy/stats/_kde.py +53 -49
  492. scipy/stats/_ksstats.py +1 -1
  493. scipy/stats/_levy_stable/__init__.py +7 -15
  494. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  495. scipy/stats/_morestats.py +112 -67
  496. scipy/stats/_mstats_basic.py +13 -17
  497. scipy/stats/_mstats_extras.py +8 -8
  498. scipy/stats/_multivariate.py +89 -113
  499. scipy/stats/_new_distributions.py +97 -20
  500. scipy/stats/_page_trend_test.py +12 -5
  501. scipy/stats/_probability_distribution.py +265 -43
  502. scipy/stats/_qmc.py +14 -9
  503. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  504. scipy/stats/_qmvnt.py +16 -95
  505. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  506. scipy/stats/_quantile.py +335 -0
  507. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  508. scipy/stats/_resampling.py +4 -29
  509. scipy/stats/_sampling.py +1 -1
  510. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  511. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  512. scipy/stats/_stats_mstats_common.py +19 -2
  513. scipy/stats/_stats_py.py +534 -460
  514. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  515. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  516. scipy/stats/_variation.py +5 -7
  517. scipy/stats/_wilcoxon.py +13 -7
  518. scipy/stats/tests/common_tests.py +6 -4
  519. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  520. scipy/stats/tests/test_continued_fraction.py +173 -0
  521. scipy/stats/tests/test_continuous.py +379 -60
  522. scipy/stats/tests/test_continuous_basic.py +18 -12
  523. scipy/stats/tests/test_discrete_basic.py +14 -8
  524. scipy/stats/tests/test_discrete_distns.py +16 -16
  525. scipy/stats/tests/test_distributions.py +95 -75
  526. scipy/stats/tests/test_entropy.py +40 -48
  527. scipy/stats/tests/test_fit.py +4 -3
  528. scipy/stats/tests/test_hypotests.py +153 -24
  529. scipy/stats/tests/test_kdeoth.py +109 -41
  530. scipy/stats/tests/test_marray.py +289 -0
  531. scipy/stats/tests/test_morestats.py +79 -47
  532. scipy/stats/tests/test_mstats_basic.py +3 -3
  533. scipy/stats/tests/test_multivariate.py +434 -83
  534. scipy/stats/tests/test_qmc.py +13 -10
  535. scipy/stats/tests/test_quantile.py +199 -0
  536. scipy/stats/tests/test_rank.py +119 -112
  537. scipy/stats/tests/test_resampling.py +47 -56
  538. scipy/stats/tests/test_sampling.py +9 -4
  539. scipy/stats/tests/test_stats.py +799 -939
  540. scipy/stats/tests/test_variation.py +8 -6
  541. scipy/version.py +2 -2
  542. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  543. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +8 -8
  544. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +545 -552
  545. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  546. scipy/_lib/array_api_extra/_funcs.py +0 -484
  547. scipy/_lib/array_api_extra/_typing.py +0 -8
  548. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  549. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  550. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  551. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  552. scipy/spatial/qhull_src/COPYING.txt +0 -38
  553. scipy/special/libsf_error_state.dylib +0 -0
  554. scipy/special/tests/test_log_softmax.py +0 -109
  555. scipy/special/tests/test_xsf_cuda.py +0 -114
  556. scipy/special/xsf/binom.h +0 -89
  557. scipy/special/xsf/cdflib.h +0 -100
  558. scipy/special/xsf/cephes/airy.h +0 -307
  559. scipy/special/xsf/cephes/besselpoly.h +0 -51
  560. scipy/special/xsf/cephes/beta.h +0 -257
  561. scipy/special/xsf/cephes/cbrt.h +0 -131
  562. scipy/special/xsf/cephes/chbevl.h +0 -85
  563. scipy/special/xsf/cephes/chdtr.h +0 -193
  564. scipy/special/xsf/cephes/const.h +0 -87
  565. scipy/special/xsf/cephes/ellie.h +0 -293
  566. scipy/special/xsf/cephes/ellik.h +0 -251
  567. scipy/special/xsf/cephes/ellpe.h +0 -107
  568. scipy/special/xsf/cephes/ellpk.h +0 -117
  569. scipy/special/xsf/cephes/expn.h +0 -260
  570. scipy/special/xsf/cephes/gamma.h +0 -398
  571. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  572. scipy/special/xsf/cephes/hyperg.h +0 -361
  573. scipy/special/xsf/cephes/i0.h +0 -149
  574. scipy/special/xsf/cephes/i1.h +0 -158
  575. scipy/special/xsf/cephes/igam.h +0 -421
  576. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  577. scipy/special/xsf/cephes/igami.h +0 -313
  578. scipy/special/xsf/cephes/j0.h +0 -225
  579. scipy/special/xsf/cephes/j1.h +0 -198
  580. scipy/special/xsf/cephes/jv.h +0 -715
  581. scipy/special/xsf/cephes/k0.h +0 -164
  582. scipy/special/xsf/cephes/k1.h +0 -163
  583. scipy/special/xsf/cephes/kn.h +0 -243
  584. scipy/special/xsf/cephes/lanczos.h +0 -112
  585. scipy/special/xsf/cephes/ndtr.h +0 -275
  586. scipy/special/xsf/cephes/poch.h +0 -85
  587. scipy/special/xsf/cephes/polevl.h +0 -167
  588. scipy/special/xsf/cephes/psi.h +0 -194
  589. scipy/special/xsf/cephes/rgamma.h +0 -111
  590. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  591. scipy/special/xsf/cephes/shichi.h +0 -248
  592. scipy/special/xsf/cephes/sici.h +0 -224
  593. scipy/special/xsf/cephes/sindg.h +0 -221
  594. scipy/special/xsf/cephes/tandg.h +0 -139
  595. scipy/special/xsf/cephes/trig.h +0 -58
  596. scipy/special/xsf/cephes/unity.h +0 -186
  597. scipy/special/xsf/cephes/zeta.h +0 -172
  598. scipy/special/xsf/config.h +0 -304
  599. scipy/special/xsf/digamma.h +0 -205
  600. scipy/special/xsf/error.h +0 -57
  601. scipy/special/xsf/evalpoly.h +0 -47
  602. scipy/special/xsf/expint.h +0 -266
  603. scipy/special/xsf/hyp2f1.h +0 -694
  604. scipy/special/xsf/iv_ratio.h +0 -173
  605. scipy/special/xsf/lambertw.h +0 -150
  606. scipy/special/xsf/loggamma.h +0 -163
  607. scipy/special/xsf/sici.h +0 -200
  608. scipy/special/xsf/tools.h +0 -427
  609. scipy/special/xsf/trig.h +0 -164
  610. scipy/special/xsf/wright_bessel.h +0 -843
  611. scipy/special/xsf/zlog1.h +0 -35
  612. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  613. scipy-1.15.3.dist-info/WHEEL +0 -4
Binary file
@@ -4,10 +4,11 @@ import numpy as np
4
4
  import numpy.typing as npt
5
5
  from scipy import fft as sp_fft
6
6
  from . import _signaltools
7
+ from ._short_time_fft import ShortTimeFFT, FFT_MODE_TYPE
7
8
  from .windows import get_window
8
9
  from ._arraytools import const_ext, even_ext, odd_ext, zero_ext
9
10
  import warnings
10
- from typing import Literal
11
+ from typing import cast, Literal
11
12
 
12
13
 
13
14
  __all__ = ['periodogram', 'welch', 'lombscargle', 'csd', 'coherence',
@@ -377,8 +378,8 @@ def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant',
377
378
  complex data, a two-sided spectrum is always returned.
378
379
  scaling : { 'density', 'spectrum' }, optional
379
380
  Selects between computing the power spectral density ('density')
380
- where `Pxx` has units of V**2/Hz and computing the squared magnitude
381
- spectrum ('spectrum') where `Pxx` has units of V**2, if `x`
381
+ where `Pxx` has units of V²/Hz and computing the squared magnitude
382
+ spectrum ('spectrum') where `Pxx` has units of V², if `x`
382
383
  is measured in V and `fs` is measured in Hz. Defaults to
383
384
  'density'
384
385
  axis : int, optional
@@ -399,6 +400,12 @@ def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant',
399
400
 
400
401
  Notes
401
402
  -----
403
+ The ratio of the squared magnitude (``scaling='spectrum'``) divided by the spectral
404
+ power density (``scaling='density'``) is the constant factor of
405
+ ``sum(abs(window)**2)*fs / abs(sum(window))**2``.
406
+ If `return_onesided` is ``True``, the values of the negative frequencies are added
407
+ to values of the corresponding positive ones.
408
+
402
409
  Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
403
410
  for a discussion of the scalings of the power spectral density and
404
411
  the magnitude (squared) spectrum.
@@ -554,6 +561,7 @@ def welch(x, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
554
561
 
555
562
  See Also
556
563
  --------
564
+ csd: Cross power spectral density using Welch's method
557
565
  periodogram: Simple, optionally modified periodogram
558
566
  lombscargle: Lomb-Scargle periodogram for unevenly sampled data
559
567
 
@@ -561,12 +569,16 @@ def welch(x, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
561
569
  -----
562
570
  An appropriate amount of overlap will depend on the choice of window
563
571
  and on your requirements. For the default Hann window an overlap of
564
- 50% is a reasonable trade off between accurately estimating the
572
+ 50% is a reasonable trade-off between accurately estimating the
565
573
  signal power, while not over counting any of the data. Narrower
566
- windows may require a larger overlap.
574
+ windows may require a larger overlap. If `noverlap` is 0, this
575
+ method is equivalent to Bartlett's method [2]_.
567
576
 
568
- If `noverlap` is 0, this method is equivalent to Bartlett's method
569
- [2]_.
577
+ The ratio of the squared magnitude (``scaling='spectrum'``) divided by the spectral
578
+ power density (``scaling='density'``) is the constant factor of
579
+ ``sum(abs(window)**2)*fs / abs(sum(window))**2``.
580
+ If `return_onesided` is ``True``, the values of the negative frequencies are added
581
+ to values of the corresponding positive ones.
570
582
 
571
583
  Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
572
584
  for a discussion of the scalings of the power spectral density and
@@ -685,7 +697,8 @@ def csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
685
697
  length of the window.
686
698
  noverlap: int, optional
687
699
  Number of points to overlap between segments. If `None`,
688
- ``noverlap = nperseg // 2``. Defaults to `None`.
700
+ ``noverlap = nperseg // 2``. Defaults to `None` and may
701
+ not be greater than `nperseg`.
689
702
  nfft : int, optional
690
703
  Length of the FFT used, if a zero padded FFT is desired. If
691
704
  `None`, the FFT length is `nperseg`. Defaults to `None`.
@@ -739,13 +752,39 @@ def csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
739
752
 
740
753
  An appropriate amount of overlap will depend on the choice of window
741
754
  and on your requirements. For the default Hann window an overlap of
742
- 50% is a reasonable trade off between accurately estimating the
755
+ 50% is a reasonable trade-off between accurately estimating the
743
756
  signal power, while not over counting any of the data. Narrower
744
757
  windows may require a larger overlap.
745
758
 
759
+ The ratio of the cross spectrum (``scaling='spectrum'``) divided by the cross
760
+ spectral density (``scaling='density'``) is the constant factor of
761
+ ``sum(abs(window)**2)*fs / abs(sum(window))**2``.
762
+ If `return_onesided` is ``True``, the values of the negative frequencies are added
763
+ to values of the corresponding positive ones.
764
+
746
765
  Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
747
766
  for a discussion of the scalings of a spectral density and an (amplitude) spectrum.
748
767
 
768
+ Welch's method may be interpreted as taking the average over the time slices of a
769
+ (cross-) spectrogram. Internally, this function utilizes the `ShortTimeFFT` to
770
+ determine the required (cross-) spectrogram. An example below illustrates that it
771
+ is straightforward to calculate `Pxy` directly with the `ShortTimeFFT`. However,
772
+ there are some notable differences in the behavior of the `ShortTimeFFT`:
773
+
774
+ * There is no direct `ShortTimeFFT` equivalent for the `csd` parameter
775
+ combination ``return_onesided=True, scaling='density'``, since
776
+ ``fft_mode='onesided2X'`` requires ``'psd'`` scaling. The is due to `csd`
777
+ returning the doubled squared magnitude in this case, which does not have a
778
+ sensible interpretation.
779
+ * `ShortTimeFFT` uses `float64` / `complex128` internally, which is due to the
780
+ behavior of the utilized `~scipy.fft` module. Thus, those are the dtypes being
781
+ returned. The `csd` function casts the return values to `float32` / `complex64`
782
+ if the input is `float32` / `complex64` as well.
783
+ * The `csd` function calculates ``np.conj(Sx[q,p]) * Sy[q,p]``, whereas
784
+ `~ShortTimeFFT.spectrogram` calculates ``Sx[q,p] * np.conj(Sy[q,p])`` where
785
+ ``Sx[q,p]``, ``Sy[q,p]`` are the STFTs of `x` and `y`. Also, the window
786
+ positioning is different.
787
+
749
788
  .. versionadded:: 0.16.0
750
789
 
751
790
  References
@@ -759,17 +798,17 @@ def csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
759
798
 
760
799
  Examples
761
800
  --------
801
+ The following example plots the cross power spectral density of two signals with
802
+ some common features:
803
+
762
804
  >>> import numpy as np
763
805
  >>> from scipy import signal
764
806
  >>> import matplotlib.pyplot as plt
765
807
  >>> rng = np.random.default_rng()
766
-
767
- Generate two test signals with some common features.
768
-
769
- >>> fs = 10e3
770
- >>> N = 1e5
771
- >>> amp = 20
772
- >>> freq = 1234.0
808
+ ...
809
+ ... # Generate two test signals with some common features:
810
+ >>> N, fs = 100_000, 10e3 # number of samples and sampling frequency
811
+ >>> amp, freq = 20, 1234.0 # amplitude and frequency of utilized sine signal
773
812
  >>> noise_power = 0.001 * fs / 2
774
813
  >>> time = np.arange(N) / fs
775
814
  >>> b, a = signal.butter(2, 0.25, 'low')
@@ -777,40 +816,133 @@ def csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
777
816
  >>> y = signal.lfilter(b, a, x)
778
817
  >>> x += amp*np.sin(2*np.pi*freq*time)
779
818
  >>> y += rng.normal(scale=0.1*np.sqrt(noise_power), size=time.shape)
819
+ ...
820
+ ... # Compute and plot the magnitude of the cross spectral density:
821
+ >>> nperseg, noverlap, win = 1024, 512, 'hann'
822
+ >>> f, Pxy = signal.csd(x, y, fs, win, nperseg, noverlap)
823
+ >>> fig0, ax0 = plt.subplots(tight_layout=True)
824
+ >>> ax0.set_title(f"CSD ({win.title()}-window, {nperseg=}, {noverlap=})")
825
+ >>> ax0.set(xlabel="Frequency $f$ in kHz", ylabel="CSD Magnitude in V²/Hz")
826
+ >>> ax0.semilogy(f/1e3, np.abs(Pxy))
827
+ >>> ax0.grid()
828
+ >>> plt.show()
780
829
 
781
- Compute and plot the magnitude of the cross spectral density.
830
+ The cross spectral density is calculated by taking the average over the time slices
831
+ of a spectrogram:
782
832
 
783
- >>> f, Pxy = signal.csd(x, y, fs, nperseg=1024)
784
- >>> plt.semilogy(f, np.abs(Pxy))
785
- >>> plt.xlabel('frequency [Hz]')
786
- >>> plt.ylabel('CSD [V**2/Hz]')
787
- >>> plt.show()
833
+ >>> SFT = signal.ShortTimeFFT.from_window('hann', fs, nperseg, noverlap,
834
+ ... scale_to='psd', fft_mode='onesided2X',
835
+ ... phase_shift=None)
836
+ >>> Sxy1 = SFT.spectrogram(y, x, detr='constant', k_offset=nperseg//2,
837
+ ... p0=0, p1=(N-noverlap) // SFT.hop)
838
+ >>> Pxy1 = Sxy1.mean(axis=-1)
839
+ >>> np.allclose(Pxy, Pxy1) # same result as with csd()
840
+ True
788
841
 
842
+ As discussed in the Notes section, the results of using an approach analogous to
843
+ the code snippet above and the `csd` function may deviate due to implementation
844
+ details.
845
+
846
+ Note that the code snippet above can be easily adapted to determine other
847
+ statistical properties than the mean value.
789
848
  """
790
- freqs, _, Pxy = _spectral_helper(x, y, fs, window, nperseg, noverlap,
791
- nfft, detrend, return_onesided, scaling,
792
- axis, mode='psd')
849
+ # The following lines are resembling the behavior of the originally utilized
850
+ # `_spectral_helper()` function:
851
+ same_data, axis = y is x, int(axis)
852
+ x = np.asarray(x)
853
+
854
+ if not same_data:
855
+ y = np.asarray(y)
856
+ # Check if we can broadcast the outer axes together
857
+ x_outer, y_outer = list(x.shape), list(y.shape)
858
+ x_outer.pop(axis)
859
+ y_outer.pop(axis)
860
+ try:
861
+ outer_shape = np.broadcast_shapes(x_outer, y_outer)
862
+ except ValueError as e:
863
+ raise ValueError('x and y cannot be broadcast together.') from e
864
+ if x.size == 0 or y.size == 0:
865
+ out_shape = outer_shape + (min([x.shape[axis], y.shape[axis]]),)
866
+ empty_out = np.moveaxis(np.empty(out_shape), -1, axis)
867
+ return empty_out, empty_out
868
+ out_dtype = np.result_type(x, y, np.complex64)
869
+ else: # x is y:
870
+ if x.size == 0:
871
+ return np.empty(x.shape), np.empty(x.shape)
872
+ out_dtype = np.result_type(x, np.complex64)
873
+
874
+ n = x.shape[axis] if same_data else max(x.shape[axis], y.shape[axis])
875
+ if isinstance(window, str) or isinstance(window, tuple):
876
+ nperseg = int(nperseg) if nperseg is not None else 256
877
+ if nperseg < 1:
878
+ raise ValueError(f"Parameter {nperseg=} is not a positive integer!")
879
+ elif n < nperseg:
880
+ warnings.warn(f"{nperseg=} is greater than signal length max(len(x), " +
881
+ f"len(y)) = {n}, using nperseg = {n}", stacklevel=3)
882
+ nperseg = n
883
+ win = get_window(window, nperseg)
884
+ else:
885
+ win = np.asarray(window)
886
+ if nperseg is None:
887
+ nperseg = len(win)
888
+ if nperseg != len(win):
889
+ raise ValueError(f"{nperseg=} does not equal {len(win)=}")
890
+
891
+ nfft = int(nfft) if nfft is not None else nperseg
892
+ if nfft < nperseg:
893
+ raise ValueError(f"{nfft=} must be greater than or equal to {nperseg=}!")
894
+ noverlap = int(noverlap) if noverlap is not None else nperseg // 2
895
+ if noverlap >= nperseg:
896
+ raise ValueError(f"{noverlap=} must be less than {nperseg=}!")
897
+ if np.iscomplexobj(x) and return_onesided:
898
+ return_onesided = False
899
+
900
+ # using cast() to make mypy happy:
901
+ fft_mode = cast(FFT_MODE_TYPE, 'onesided' if return_onesided else 'twosided')
902
+ if scaling not in (scales := {'spectrum': 'magnitude', 'density': 'psd'}):
903
+ raise ValueError(f"Parameter {scaling=} not in {scales}!")
904
+
905
+ SFT = ShortTimeFFT(win, nperseg - noverlap, fs, fft_mode=fft_mode, mfft=nfft,
906
+ scale_to=scales[scaling], phase_shift=None)
907
+ # csd() calculates X.conj()*Y instead of X*Y.conj():
908
+ Pxy = SFT.spectrogram(y, x, detr=None if detrend is False else detrend,
909
+ p0=0, p1=(n - noverlap) // SFT.hop, k_offset=nperseg // 2,
910
+ axis=axis)
911
+
912
+ # Note:
913
+ # 'onesided2X' scaling of ShortTimeFFT conflicts with the
914
+ # scaling='spectrum' parameter, since it doubles the squared magnitude,
915
+ # which in the view of the ShortTimeFFT implementation does not make sense.
916
+ # Hence, the doubling of the square is implemented here:
917
+ if return_onesided:
918
+ f_axis = Pxy.ndim - 1 + axis if axis < 0 else axis
919
+ Pxy = np.moveaxis(Pxy, f_axis, -1)
920
+ Pxy[..., 1:-1 if SFT.mfft % 2 == 0 else None] *= 2
921
+ Pxy = np.moveaxis(Pxy, -1, f_axis)
793
922
 
794
923
  # Average over windows.
795
- if len(Pxy.shape) >= 2 and Pxy.size > 0:
796
- if Pxy.shape[-1] > 1:
797
- if average == 'median':
798
- # np.median must be passed real arrays for the desired result
799
- bias = _median_bias(Pxy.shape[-1])
800
- if np.iscomplexobj(Pxy):
801
- Pxy = (np.median(np.real(Pxy), axis=-1)
802
- + 1j * np.median(np.imag(Pxy), axis=-1))
803
- else:
804
- Pxy = np.median(Pxy, axis=-1)
805
- Pxy /= bias
806
- elif average == 'mean':
807
- Pxy = Pxy.mean(axis=-1)
924
+ if Pxy.shape[-1] > 1:
925
+ if average == 'median':
926
+ # np.median must be passed real arrays for the desired result
927
+ bias = _median_bias(Pxy.shape[-1])
928
+ if np.iscomplexobj(Pxy):
929
+ Pxy = (np.median(np.real(Pxy), axis=-1) +
930
+ np.median(np.imag(Pxy), axis=-1) * 1j)
808
931
  else:
809
- raise ValueError(f'average must be "median" or "mean", got {average}')
932
+ Pxy = np.median(Pxy, axis=-1)
933
+ Pxy /= bias
934
+ elif average == 'mean':
935
+ Pxy = Pxy.mean(axis=-1)
810
936
  else:
811
- Pxy = np.reshape(Pxy, Pxy.shape[:-1])
937
+ raise ValueError(f"Parameter {average=} must be 'median' or 'mean'!")
938
+ else:
939
+ Pxy = np.reshape(Pxy, Pxy.shape[:-1])
812
940
 
813
- return freqs, Pxy
941
+ # cast output type;
942
+ Pxy = Pxy.astype(out_dtype)
943
+ if same_data:
944
+ Pxy = Pxy.real
945
+ return SFT.f, Pxy
814
946
 
815
947
 
816
948
  def spectrogram(x, fs=1.0, window=('tukey', .25), nperseg=None, noverlap=None,
@@ -997,7 +1129,26 @@ def spectrogram(x, fs=1.0, window=('tukey', .25), nperseg=None, noverlap=None,
997
1129
 
998
1130
 
999
1131
  def check_COLA(window, nperseg, noverlap, tol=1e-10):
1000
- r"""Check whether the Constant OverLap Add (COLA) constraint is met.
1132
+ r"""Check whether the Constant OverLap Add (COLA) constraint is met
1133
+ (legacy function).
1134
+
1135
+ .. legacy:: function
1136
+
1137
+ The COLA constraint is equivalent of having a constant dual window, i.e.,
1138
+ ``all(ShortTimeFFT.dual_win == ShortTimeFFT.dual_win[0])``. Hence,
1139
+ `closest_STFT_dual_window` generalizes this function, as the following
1140
+ example shows:
1141
+
1142
+ >>> import numpy as np
1143
+ >>> from scipy.signal import check_COLA, closest_STFT_dual_window, windows
1144
+ ...
1145
+ >>> w, w_rect, hop = windows.hann(12, sym=False), np.ones(12), 6
1146
+ >>> dual_win, alpha = closest_STFT_dual_window(w, hop, w_rect, scaled=True)
1147
+ >>> np.allclose(dual_win/alpha, w_rect, atol=1e-10, rtol=0)
1148
+ True
1149
+ >>> check_COLA(w, len(w), len(w) - hop) # equivalent legacy function call
1150
+ True
1151
+
1001
1152
 
1002
1153
  Parameters
1003
1154
  ----------
@@ -1023,17 +1174,22 @@ def check_COLA(window, nperseg, noverlap, tol=1e-10):
1023
1174
 
1024
1175
  See Also
1025
1176
  --------
1177
+ closest_STFT_dual_window: Allows determining the closest window meeting the
1178
+ COLA constraint for a given window
1026
1179
  check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
1027
- stft: Short Time Fourier Transform
1028
- istft: Inverse Short Time Fourier Transform
1180
+ ShortTimeFFT: Provide short-time Fourier transform and its inverse
1181
+ stft: Short-time Fourier transform (legacy)
1182
+ istft: Inverse Short-time Fourier transform (legacy)
1029
1183
 
1030
1184
  Notes
1031
1185
  -----
1032
- In order to enable inversion of an STFT via the inverse STFT in
1033
- `istft`, it is sufficient that the signal windowing obeys the constraint of
1186
+ In order to invert a short-time Fourier transfrom (STFT) with the so-called
1187
+ "overlap-add method", the signal windowing must obey the constraint of
1034
1188
  "Constant OverLap Add" (COLA). This ensures that every point in the input
1035
1189
  data is equally weighted, thereby avoiding aliasing and allowing full
1036
- reconstruction.
1190
+ reconstruction. Note that the algorithms implemented in `ShortTimeFFT.istft`
1191
+ and in `istft` (legacy) only require that the weaker "nonzero overlap-add"
1192
+ condition (as in `check_NOLA`) is met.
1037
1193
 
1038
1194
  Some examples of windows that satisfy COLA:
1039
1195
  - Rectangular window at overlap of 0, 1/2, 2/3, 3/4, ...
@@ -1802,7 +1958,7 @@ def coherence(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
1802
1958
  -----
1803
1959
  An appropriate amount of overlap will depend on the choice of window
1804
1960
  and on your requirements. For the default Hann window an overlap of
1805
- 50% is a reasonable trade off between accurately estimating the
1961
+ 50% is a reasonable trade-off between accurately estimating the
1806
1962
  signal power, while not over counting any of the data. Narrower
1807
1963
  windows may require a larger overlap.
1808
1964
 
@@ -1866,6 +2022,11 @@ def _spectral_helper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
1866
2022
  padded=False):
1867
2023
  """Calculate various forms of windowed FFTs for PSD, CSD, etc.
1868
2024
 
2025
+ .. legacy:: function
2026
+
2027
+ This function is soley used by the legacy functions `spectrogram` and `stft`
2028
+ (which are also in this same source file `scipy/signal/_spectral_py.py`).
2029
+
1869
2030
  This is a helper function that implements the commonality between
1870
2031
  the stft, psd, csd, and spectrogram functions. It is not designed to
1871
2032
  be called externally. The windows are not averaged over; the result
@@ -1910,8 +2071,8 @@ def _spectral_helper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
1910
2071
  complex data, a two-sided spectrum is always returned.
1911
2072
  scaling : { 'density', 'spectrum' }, optional
1912
2073
  Selects between computing the cross spectral density ('density')
1913
- where `Pxy` has units of V**2/Hz and computing the cross
1914
- spectrum ('spectrum') where `Pxy` has units of V**2, if `x`
2074
+ where `Pxy` has units of V²/Hz and computing the cross
2075
+ spectrum ('spectrum') where `Pxy` has units of V², if `x`
1915
2076
  and `y` are measured in V and `fs` is measured in Hz.
1916
2077
  Defaults to 'density'
1917
2078
  axis : int, optional
@@ -2160,6 +2321,11 @@ def _fft_helper(x, win, detrend_func, nperseg, noverlap, nfft, sides):
2160
2321
  Calculate windowed FFT, for internal use by
2161
2322
  `scipy.signal._spectral_helper`.
2162
2323
 
2324
+ .. legacy:: function
2325
+
2326
+ This function is solely used by the legacy `_spectral_helper` function,
2327
+ which is located also in this file.
2328
+
2163
2329
  This is a helper function that does the main FFT calculation for
2164
2330
  `_spectral helper`. All input validation is performed there, and the
2165
2331
  data axis is assumed to be the last axis of x. It is not designed to
@@ -2209,6 +2375,11 @@ def _triage_segments(window, nperseg, input_length):
2209
2375
  Parses window and nperseg arguments for spectrogram and _spectral_helper.
2210
2376
  This is a helper function, not meant to be called externally.
2211
2377
 
2378
+ .. legacy:: function
2379
+
2380
+ This function is soley used by the legacy functions `spectrogram` and
2381
+ `_spectral_helper` (which are also in this file).
2382
+
2212
2383
  Parameters
2213
2384
  ----------
2214
2385
  window : string, tuple, or ndarray