scipy 1.16.0rc1__cp311-cp311-macosx_10_14_x86_64.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 (1416) hide show
  1. scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. scipy/.dylibs/libgfortran.5.dylib +0 -0
  3. scipy/.dylibs/libquadmath.0.dylib +0 -0
  4. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  5. scipy/__config__.py +161 -0
  6. scipy/__init__.py +138 -0
  7. scipy/_cyutility.cpython-311-darwin.so +0 -0
  8. scipy/_distributor_init.py +18 -0
  9. scipy/_lib/__init__.py +14 -0
  10. scipy/_lib/_array_api.py +931 -0
  11. scipy/_lib/_array_api_compat_vendor.py +9 -0
  12. scipy/_lib/_array_api_no_0d.py +103 -0
  13. scipy/_lib/_bunch.py +229 -0
  14. scipy/_lib/_ccallback.py +251 -0
  15. scipy/_lib/_ccallback_c.cpython-311-darwin.so +0 -0
  16. scipy/_lib/_disjoint_set.py +254 -0
  17. scipy/_lib/_docscrape.py +761 -0
  18. scipy/_lib/_elementwise_iterative_method.py +346 -0
  19. scipy/_lib/_fpumode.cpython-311-darwin.so +0 -0
  20. scipy/_lib/_gcutils.py +105 -0
  21. scipy/_lib/_pep440.py +487 -0
  22. scipy/_lib/_sparse.py +41 -0
  23. scipy/_lib/_test_ccallback.cpython-311-darwin.so +0 -0
  24. scipy/_lib/_test_deprecation_call.cpython-311-darwin.so +0 -0
  25. scipy/_lib/_test_deprecation_def.cpython-311-darwin.so +0 -0
  26. scipy/_lib/_testutils.py +373 -0
  27. scipy/_lib/_threadsafety.py +58 -0
  28. scipy/_lib/_tmpdirs.py +86 -0
  29. scipy/_lib/_uarray/LICENSE +29 -0
  30. scipy/_lib/_uarray/__init__.py +116 -0
  31. scipy/_lib/_uarray/_backend.py +707 -0
  32. scipy/_lib/_uarray/_uarray.cpython-311-darwin.so +0 -0
  33. scipy/_lib/_util.py +1276 -0
  34. scipy/_lib/array_api_compat/__init__.py +22 -0
  35. scipy/_lib/array_api_compat/_internal.py +59 -0
  36. scipy/_lib/array_api_compat/common/__init__.py +1 -0
  37. scipy/_lib/array_api_compat/common/_aliases.py +727 -0
  38. scipy/_lib/array_api_compat/common/_fft.py +213 -0
  39. scipy/_lib/array_api_compat/common/_helpers.py +1058 -0
  40. scipy/_lib/array_api_compat/common/_linalg.py +232 -0
  41. scipy/_lib/array_api_compat/common/_typing.py +192 -0
  42. scipy/_lib/array_api_compat/cupy/__init__.py +13 -0
  43. scipy/_lib/array_api_compat/cupy/_aliases.py +156 -0
  44. scipy/_lib/array_api_compat/cupy/_info.py +336 -0
  45. scipy/_lib/array_api_compat/cupy/_typing.py +31 -0
  46. scipy/_lib/array_api_compat/cupy/fft.py +36 -0
  47. scipy/_lib/array_api_compat/cupy/linalg.py +49 -0
  48. scipy/_lib/array_api_compat/dask/__init__.py +0 -0
  49. scipy/_lib/array_api_compat/dask/array/__init__.py +12 -0
  50. scipy/_lib/array_api_compat/dask/array/_aliases.py +376 -0
  51. scipy/_lib/array_api_compat/dask/array/_info.py +416 -0
  52. scipy/_lib/array_api_compat/dask/array/fft.py +21 -0
  53. scipy/_lib/array_api_compat/dask/array/linalg.py +72 -0
  54. scipy/_lib/array_api_compat/numpy/__init__.py +28 -0
  55. scipy/_lib/array_api_compat/numpy/_aliases.py +190 -0
  56. scipy/_lib/array_api_compat/numpy/_info.py +366 -0
  57. scipy/_lib/array_api_compat/numpy/_typing.py +30 -0
  58. scipy/_lib/array_api_compat/numpy/fft.py +35 -0
  59. scipy/_lib/array_api_compat/numpy/linalg.py +143 -0
  60. scipy/_lib/array_api_compat/torch/__init__.py +22 -0
  61. scipy/_lib/array_api_compat/torch/_aliases.py +855 -0
  62. scipy/_lib/array_api_compat/torch/_info.py +369 -0
  63. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  64. scipy/_lib/array_api_compat/torch/fft.py +85 -0
  65. scipy/_lib/array_api_compat/torch/linalg.py +121 -0
  66. scipy/_lib/array_api_extra/__init__.py +38 -0
  67. scipy/_lib/array_api_extra/_delegation.py +171 -0
  68. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  69. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  70. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  71. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  72. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  73. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  74. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  75. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  76. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  77. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  78. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  79. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  80. scipy/_lib/array_api_extra/testing.py +359 -0
  81. scipy/_lib/cobyqa/__init__.py +20 -0
  82. scipy/_lib/cobyqa/framework.py +1240 -0
  83. scipy/_lib/cobyqa/main.py +1506 -0
  84. scipy/_lib/cobyqa/models.py +1529 -0
  85. scipy/_lib/cobyqa/problem.py +1296 -0
  86. scipy/_lib/cobyqa/settings.py +132 -0
  87. scipy/_lib/cobyqa/subsolvers/__init__.py +14 -0
  88. scipy/_lib/cobyqa/subsolvers/geometry.py +387 -0
  89. scipy/_lib/cobyqa/subsolvers/optim.py +1203 -0
  90. scipy/_lib/cobyqa/utils/__init__.py +18 -0
  91. scipy/_lib/cobyqa/utils/exceptions.py +22 -0
  92. scipy/_lib/cobyqa/utils/math.py +77 -0
  93. scipy/_lib/cobyqa/utils/versions.py +67 -0
  94. scipy/_lib/decorator.py +399 -0
  95. scipy/_lib/deprecation.py +274 -0
  96. scipy/_lib/doccer.py +366 -0
  97. scipy/_lib/messagestream.cpython-311-darwin.so +0 -0
  98. scipy/_lib/pyprima/__init__.py +212 -0
  99. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  100. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  101. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  102. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  103. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  104. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  105. scipy/_lib/pyprima/cobyla/update.py +289 -0
  106. scipy/_lib/pyprima/common/__init__.py +0 -0
  107. scipy/_lib/pyprima/common/_bounds.py +34 -0
  108. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  109. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  110. scipy/_lib/pyprima/common/_project.py +173 -0
  111. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  112. scipy/_lib/pyprima/common/consts.py +47 -0
  113. scipy/_lib/pyprima/common/evaluate.py +99 -0
  114. scipy/_lib/pyprima/common/history.py +38 -0
  115. scipy/_lib/pyprima/common/infos.py +30 -0
  116. scipy/_lib/pyprima/common/linalg.py +435 -0
  117. scipy/_lib/pyprima/common/message.py +290 -0
  118. scipy/_lib/pyprima/common/powalg.py +131 -0
  119. scipy/_lib/pyprima/common/preproc.py +277 -0
  120. scipy/_lib/pyprima/common/present.py +5 -0
  121. scipy/_lib/pyprima/common/ratio.py +54 -0
  122. scipy/_lib/pyprima/common/redrho.py +47 -0
  123. scipy/_lib/pyprima/common/selectx.py +296 -0
  124. scipy/_lib/tests/__init__.py +0 -0
  125. scipy/_lib/tests/test__gcutils.py +110 -0
  126. scipy/_lib/tests/test__pep440.py +67 -0
  127. scipy/_lib/tests/test__testutils.py +32 -0
  128. scipy/_lib/tests/test__threadsafety.py +51 -0
  129. scipy/_lib/tests/test__util.py +641 -0
  130. scipy/_lib/tests/test_array_api.py +322 -0
  131. scipy/_lib/tests/test_bunch.py +169 -0
  132. scipy/_lib/tests/test_ccallback.py +196 -0
  133. scipy/_lib/tests/test_config.py +45 -0
  134. scipy/_lib/tests/test_deprecation.py +10 -0
  135. scipy/_lib/tests/test_doccer.py +143 -0
  136. scipy/_lib/tests/test_import_cycles.py +18 -0
  137. scipy/_lib/tests/test_public_api.py +482 -0
  138. scipy/_lib/tests/test_scipy_version.py +28 -0
  139. scipy/_lib/tests/test_tmpdirs.py +48 -0
  140. scipy/_lib/tests/test_warnings.py +137 -0
  141. scipy/_lib/uarray.py +31 -0
  142. scipy/cluster/__init__.py +31 -0
  143. scipy/cluster/_hierarchy.cpython-311-darwin.so +0 -0
  144. scipy/cluster/_optimal_leaf_ordering.cpython-311-darwin.so +0 -0
  145. scipy/cluster/_vq.cpython-311-darwin.so +0 -0
  146. scipy/cluster/hierarchy.py +4348 -0
  147. scipy/cluster/tests/__init__.py +0 -0
  148. scipy/cluster/tests/hierarchy_test_data.py +145 -0
  149. scipy/cluster/tests/test_disjoint_set.py +202 -0
  150. scipy/cluster/tests/test_hierarchy.py +1238 -0
  151. scipy/cluster/tests/test_vq.py +434 -0
  152. scipy/cluster/vq.py +832 -0
  153. scipy/conftest.py +658 -0
  154. scipy/constants/__init__.py +358 -0
  155. scipy/constants/_codata.py +2266 -0
  156. scipy/constants/_constants.py +369 -0
  157. scipy/constants/codata.py +21 -0
  158. scipy/constants/constants.py +53 -0
  159. scipy/constants/tests/__init__.py +0 -0
  160. scipy/constants/tests/test_codata.py +78 -0
  161. scipy/constants/tests/test_constants.py +83 -0
  162. scipy/datasets/__init__.py +90 -0
  163. scipy/datasets/_download_all.py +71 -0
  164. scipy/datasets/_fetchers.py +225 -0
  165. scipy/datasets/_registry.py +26 -0
  166. scipy/datasets/_utils.py +81 -0
  167. scipy/datasets/tests/__init__.py +0 -0
  168. scipy/datasets/tests/test_data.py +128 -0
  169. scipy/differentiate/__init__.py +27 -0
  170. scipy/differentiate/_differentiate.py +1129 -0
  171. scipy/differentiate/tests/__init__.py +0 -0
  172. scipy/differentiate/tests/test_differentiate.py +694 -0
  173. scipy/fft/__init__.py +114 -0
  174. scipy/fft/_backend.py +196 -0
  175. scipy/fft/_basic.py +1650 -0
  176. scipy/fft/_basic_backend.py +197 -0
  177. scipy/fft/_debug_backends.py +22 -0
  178. scipy/fft/_fftlog.py +223 -0
  179. scipy/fft/_fftlog_backend.py +200 -0
  180. scipy/fft/_helper.py +348 -0
  181. scipy/fft/_pocketfft/LICENSE.md +25 -0
  182. scipy/fft/_pocketfft/__init__.py +9 -0
  183. scipy/fft/_pocketfft/basic.py +251 -0
  184. scipy/fft/_pocketfft/helper.py +249 -0
  185. scipy/fft/_pocketfft/pypocketfft.cpython-311-darwin.so +0 -0
  186. scipy/fft/_pocketfft/realtransforms.py +109 -0
  187. scipy/fft/_pocketfft/tests/__init__.py +0 -0
  188. scipy/fft/_pocketfft/tests/test_basic.py +1011 -0
  189. scipy/fft/_pocketfft/tests/test_real_transforms.py +505 -0
  190. scipy/fft/_realtransforms.py +706 -0
  191. scipy/fft/_realtransforms_backend.py +63 -0
  192. scipy/fft/tests/__init__.py +0 -0
  193. scipy/fft/tests/mock_backend.py +96 -0
  194. scipy/fft/tests/test_backend.py +98 -0
  195. scipy/fft/tests/test_basic.py +504 -0
  196. scipy/fft/tests/test_fftlog.py +215 -0
  197. scipy/fft/tests/test_helper.py +558 -0
  198. scipy/fft/tests/test_multithreading.py +84 -0
  199. scipy/fft/tests/test_real_transforms.py +247 -0
  200. scipy/fftpack/__init__.py +103 -0
  201. scipy/fftpack/_basic.py +428 -0
  202. scipy/fftpack/_helper.py +115 -0
  203. scipy/fftpack/_pseudo_diffs.py +554 -0
  204. scipy/fftpack/_realtransforms.py +598 -0
  205. scipy/fftpack/basic.py +20 -0
  206. scipy/fftpack/convolve.cpython-311-darwin.so +0 -0
  207. scipy/fftpack/helper.py +19 -0
  208. scipy/fftpack/pseudo_diffs.py +22 -0
  209. scipy/fftpack/realtransforms.py +19 -0
  210. scipy/fftpack/tests/__init__.py +0 -0
  211. scipy/fftpack/tests/fftw_double_ref.npz +0 -0
  212. scipy/fftpack/tests/fftw_longdouble_ref.npz +0 -0
  213. scipy/fftpack/tests/fftw_single_ref.npz +0 -0
  214. scipy/fftpack/tests/test.npz +0 -0
  215. scipy/fftpack/tests/test_basic.py +877 -0
  216. scipy/fftpack/tests/test_helper.py +54 -0
  217. scipy/fftpack/tests/test_import.py +33 -0
  218. scipy/fftpack/tests/test_pseudo_diffs.py +388 -0
  219. scipy/fftpack/tests/test_real_transforms.py +836 -0
  220. scipy/integrate/__init__.py +122 -0
  221. scipy/integrate/_bvp.py +1160 -0
  222. scipy/integrate/_cubature.py +729 -0
  223. scipy/integrate/_dop.cpython-311-darwin.so +0 -0
  224. scipy/integrate/_ivp/__init__.py +8 -0
  225. scipy/integrate/_ivp/base.py +290 -0
  226. scipy/integrate/_ivp/bdf.py +478 -0
  227. scipy/integrate/_ivp/common.py +451 -0
  228. scipy/integrate/_ivp/dop853_coefficients.py +193 -0
  229. scipy/integrate/_ivp/ivp.py +755 -0
  230. scipy/integrate/_ivp/lsoda.py +224 -0
  231. scipy/integrate/_ivp/radau.py +572 -0
  232. scipy/integrate/_ivp/rk.py +601 -0
  233. scipy/integrate/_ivp/tests/__init__.py +0 -0
  234. scipy/integrate/_ivp/tests/test_ivp.py +1287 -0
  235. scipy/integrate/_ivp/tests/test_rk.py +37 -0
  236. scipy/integrate/_lebedev.py +5450 -0
  237. scipy/integrate/_lsoda.cpython-311-darwin.so +0 -0
  238. scipy/integrate/_ode.py +1395 -0
  239. scipy/integrate/_odepack.cpython-311-darwin.so +0 -0
  240. scipy/integrate/_odepack_py.py +273 -0
  241. scipy/integrate/_quad_vec.py +674 -0
  242. scipy/integrate/_quadpack.cpython-311-darwin.so +0 -0
  243. scipy/integrate/_quadpack_py.py +1283 -0
  244. scipy/integrate/_quadrature.py +1336 -0
  245. scipy/integrate/_rules/__init__.py +12 -0
  246. scipy/integrate/_rules/_base.py +518 -0
  247. scipy/integrate/_rules/_gauss_kronrod.py +202 -0
  248. scipy/integrate/_rules/_gauss_legendre.py +62 -0
  249. scipy/integrate/_rules/_genz_malik.py +210 -0
  250. scipy/integrate/_tanhsinh.py +1385 -0
  251. scipy/integrate/_test_multivariate.cpython-311-darwin.so +0 -0
  252. scipy/integrate/_test_odeint_banded.cpython-311-darwin.so +0 -0
  253. scipy/integrate/_vode.cpython-311-darwin.so +0 -0
  254. scipy/integrate/dop.py +15 -0
  255. scipy/integrate/lsoda.py +15 -0
  256. scipy/integrate/odepack.py +17 -0
  257. scipy/integrate/quadpack.py +23 -0
  258. scipy/integrate/tests/__init__.py +0 -0
  259. scipy/integrate/tests/test__quad_vec.py +211 -0
  260. scipy/integrate/tests/test_banded_ode_solvers.py +305 -0
  261. scipy/integrate/tests/test_bvp.py +714 -0
  262. scipy/integrate/tests/test_cubature.py +1375 -0
  263. scipy/integrate/tests/test_integrate.py +840 -0
  264. scipy/integrate/tests/test_odeint_jac.py +74 -0
  265. scipy/integrate/tests/test_quadpack.py +680 -0
  266. scipy/integrate/tests/test_quadrature.py +730 -0
  267. scipy/integrate/tests/test_tanhsinh.py +1171 -0
  268. scipy/integrate/vode.py +15 -0
  269. scipy/interpolate/__init__.py +228 -0
  270. scipy/interpolate/_bary_rational.py +715 -0
  271. scipy/interpolate/_bsplines.py +2469 -0
  272. scipy/interpolate/_cubic.py +973 -0
  273. scipy/interpolate/_dfitpack.cpython-311-darwin.so +0 -0
  274. scipy/interpolate/_dierckx.cpython-311-darwin.so +0 -0
  275. scipy/interpolate/_fitpack.cpython-311-darwin.so +0 -0
  276. scipy/interpolate/_fitpack2.py +2397 -0
  277. scipy/interpolate/_fitpack_impl.py +811 -0
  278. scipy/interpolate/_fitpack_py.py +898 -0
  279. scipy/interpolate/_fitpack_repro.py +996 -0
  280. scipy/interpolate/_interpnd.cpython-311-darwin.so +0 -0
  281. scipy/interpolate/_interpolate.py +2266 -0
  282. scipy/interpolate/_ndbspline.py +415 -0
  283. scipy/interpolate/_ndgriddata.py +329 -0
  284. scipy/interpolate/_pade.py +67 -0
  285. scipy/interpolate/_polyint.py +1025 -0
  286. scipy/interpolate/_ppoly.cpython-311-darwin.so +0 -0
  287. scipy/interpolate/_rbf.py +290 -0
  288. scipy/interpolate/_rbfinterp.py +550 -0
  289. scipy/interpolate/_rbfinterp_pythran.cpython-311-darwin.so +0 -0
  290. scipy/interpolate/_rgi.py +764 -0
  291. scipy/interpolate/_rgi_cython.cpython-311-darwin.so +0 -0
  292. scipy/interpolate/dfitpack.py +24 -0
  293. scipy/interpolate/fitpack.py +31 -0
  294. scipy/interpolate/fitpack2.py +29 -0
  295. scipy/interpolate/interpnd.py +24 -0
  296. scipy/interpolate/interpolate.py +30 -0
  297. scipy/interpolate/ndgriddata.py +23 -0
  298. scipy/interpolate/polyint.py +24 -0
  299. scipy/interpolate/rbf.py +18 -0
  300. scipy/interpolate/tests/__init__.py +0 -0
  301. scipy/interpolate/tests/data/bug-1310.npz +0 -0
  302. scipy/interpolate/tests/data/estimate_gradients_hang.npy +0 -0
  303. scipy/interpolate/tests/data/gcvspl.npz +0 -0
  304. scipy/interpolate/tests/test_bary_rational.py +368 -0
  305. scipy/interpolate/tests/test_bsplines.py +3754 -0
  306. scipy/interpolate/tests/test_fitpack.py +519 -0
  307. scipy/interpolate/tests/test_fitpack2.py +1431 -0
  308. scipy/interpolate/tests/test_gil.py +64 -0
  309. scipy/interpolate/tests/test_interpnd.py +452 -0
  310. scipy/interpolate/tests/test_interpolate.py +2630 -0
  311. scipy/interpolate/tests/test_ndgriddata.py +308 -0
  312. scipy/interpolate/tests/test_pade.py +107 -0
  313. scipy/interpolate/tests/test_polyint.py +972 -0
  314. scipy/interpolate/tests/test_rbf.py +246 -0
  315. scipy/interpolate/tests/test_rbfinterp.py +534 -0
  316. scipy/interpolate/tests/test_rgi.py +1151 -0
  317. scipy/io/__init__.py +116 -0
  318. scipy/io/_fast_matrix_market/__init__.py +600 -0
  319. scipy/io/_fast_matrix_market/_fmm_core.cpython-311-darwin.so +0 -0
  320. scipy/io/_fortran.py +354 -0
  321. scipy/io/_harwell_boeing/__init__.py +7 -0
  322. scipy/io/_harwell_boeing/_fortran_format_parser.py +316 -0
  323. scipy/io/_harwell_boeing/hb.py +571 -0
  324. scipy/io/_harwell_boeing/tests/__init__.py +0 -0
  325. scipy/io/_harwell_boeing/tests/test_fortran_format.py +74 -0
  326. scipy/io/_harwell_boeing/tests/test_hb.py +70 -0
  327. scipy/io/_idl.py +917 -0
  328. scipy/io/_mmio.py +968 -0
  329. scipy/io/_netcdf.py +1104 -0
  330. scipy/io/_test_fortran.cpython-311-darwin.so +0 -0
  331. scipy/io/arff/__init__.py +28 -0
  332. scipy/io/arff/_arffread.py +873 -0
  333. scipy/io/arff/arffread.py +19 -0
  334. scipy/io/arff/tests/__init__.py +0 -0
  335. scipy/io/arff/tests/data/iris.arff +225 -0
  336. scipy/io/arff/tests/data/missing.arff +8 -0
  337. scipy/io/arff/tests/data/nodata.arff +11 -0
  338. scipy/io/arff/tests/data/quoted_nominal.arff +13 -0
  339. scipy/io/arff/tests/data/quoted_nominal_spaces.arff +13 -0
  340. scipy/io/arff/tests/data/test1.arff +10 -0
  341. scipy/io/arff/tests/data/test10.arff +8 -0
  342. scipy/io/arff/tests/data/test11.arff +11 -0
  343. scipy/io/arff/tests/data/test2.arff +15 -0
  344. scipy/io/arff/tests/data/test3.arff +6 -0
  345. scipy/io/arff/tests/data/test4.arff +11 -0
  346. scipy/io/arff/tests/data/test5.arff +26 -0
  347. scipy/io/arff/tests/data/test6.arff +12 -0
  348. scipy/io/arff/tests/data/test7.arff +15 -0
  349. scipy/io/arff/tests/data/test8.arff +12 -0
  350. scipy/io/arff/tests/data/test9.arff +14 -0
  351. scipy/io/arff/tests/test_arffread.py +421 -0
  352. scipy/io/harwell_boeing.py +17 -0
  353. scipy/io/idl.py +17 -0
  354. scipy/io/matlab/__init__.py +66 -0
  355. scipy/io/matlab/_byteordercodes.py +75 -0
  356. scipy/io/matlab/_mio.py +375 -0
  357. scipy/io/matlab/_mio4.py +632 -0
  358. scipy/io/matlab/_mio5.py +901 -0
  359. scipy/io/matlab/_mio5_params.py +281 -0
  360. scipy/io/matlab/_mio5_utils.cpython-311-darwin.so +0 -0
  361. scipy/io/matlab/_mio_utils.cpython-311-darwin.so +0 -0
  362. scipy/io/matlab/_miobase.py +435 -0
  363. scipy/io/matlab/_streams.cpython-311-darwin.so +0 -0
  364. scipy/io/matlab/byteordercodes.py +17 -0
  365. scipy/io/matlab/mio.py +16 -0
  366. scipy/io/matlab/mio4.py +17 -0
  367. scipy/io/matlab/mio5.py +19 -0
  368. scipy/io/matlab/mio5_params.py +18 -0
  369. scipy/io/matlab/mio5_utils.py +17 -0
  370. scipy/io/matlab/mio_utils.py +17 -0
  371. scipy/io/matlab/miobase.py +16 -0
  372. scipy/io/matlab/streams.py +16 -0
  373. scipy/io/matlab/tests/__init__.py +0 -0
  374. scipy/io/matlab/tests/data/bad_miuint32.mat +0 -0
  375. scipy/io/matlab/tests/data/bad_miutf8_array_name.mat +0 -0
  376. scipy/io/matlab/tests/data/big_endian.mat +0 -0
  377. scipy/io/matlab/tests/data/broken_utf8.mat +0 -0
  378. scipy/io/matlab/tests/data/corrupted_zlib_checksum.mat +0 -0
  379. scipy/io/matlab/tests/data/corrupted_zlib_data.mat +0 -0
  380. scipy/io/matlab/tests/data/debigged_m4.mat +0 -0
  381. scipy/io/matlab/tests/data/japanese_utf8.txt +5 -0
  382. scipy/io/matlab/tests/data/little_endian.mat +0 -0
  383. scipy/io/matlab/tests/data/logical_sparse.mat +0 -0
  384. scipy/io/matlab/tests/data/malformed1.mat +0 -0
  385. scipy/io/matlab/tests/data/miuint32_for_miint32.mat +0 -0
  386. scipy/io/matlab/tests/data/miutf8_array_name.mat +0 -0
  387. scipy/io/matlab/tests/data/nasty_duplicate_fieldnames.mat +0 -0
  388. scipy/io/matlab/tests/data/one_by_zero_char.mat +0 -0
  389. scipy/io/matlab/tests/data/parabola.mat +0 -0
  390. scipy/io/matlab/tests/data/single_empty_string.mat +0 -0
  391. scipy/io/matlab/tests/data/some_functions.mat +0 -0
  392. scipy/io/matlab/tests/data/sqr.mat +0 -0
  393. scipy/io/matlab/tests/data/test3dmatrix_6.1_SOL2.mat +0 -0
  394. scipy/io/matlab/tests/data/test3dmatrix_6.5.1_GLNX86.mat +0 -0
  395. scipy/io/matlab/tests/data/test3dmatrix_7.1_GLNX86.mat +0 -0
  396. scipy/io/matlab/tests/data/test3dmatrix_7.4_GLNX86.mat +0 -0
  397. scipy/io/matlab/tests/data/test_empty_struct.mat +0 -0
  398. scipy/io/matlab/tests/data/test_mat4_le_floats.mat +0 -0
  399. scipy/io/matlab/tests/data/test_skip_variable.mat +0 -0
  400. scipy/io/matlab/tests/data/testbool_8_WIN64.mat +0 -0
  401. scipy/io/matlab/tests/data/testcell_6.1_SOL2.mat +0 -0
  402. scipy/io/matlab/tests/data/testcell_6.5.1_GLNX86.mat +0 -0
  403. scipy/io/matlab/tests/data/testcell_7.1_GLNX86.mat +0 -0
  404. scipy/io/matlab/tests/data/testcell_7.4_GLNX86.mat +0 -0
  405. scipy/io/matlab/tests/data/testcellnest_6.1_SOL2.mat +0 -0
  406. scipy/io/matlab/tests/data/testcellnest_6.5.1_GLNX86.mat +0 -0
  407. scipy/io/matlab/tests/data/testcellnest_7.1_GLNX86.mat +0 -0
  408. scipy/io/matlab/tests/data/testcellnest_7.4_GLNX86.mat +0 -0
  409. scipy/io/matlab/tests/data/testcomplex_4.2c_SOL2.mat +0 -0
  410. scipy/io/matlab/tests/data/testcomplex_6.1_SOL2.mat +0 -0
  411. scipy/io/matlab/tests/data/testcomplex_6.5.1_GLNX86.mat +0 -0
  412. scipy/io/matlab/tests/data/testcomplex_7.1_GLNX86.mat +0 -0
  413. scipy/io/matlab/tests/data/testcomplex_7.4_GLNX86.mat +0 -0
  414. scipy/io/matlab/tests/data/testdouble_4.2c_SOL2.mat +0 -0
  415. scipy/io/matlab/tests/data/testdouble_6.1_SOL2.mat +0 -0
  416. scipy/io/matlab/tests/data/testdouble_6.5.1_GLNX86.mat +0 -0
  417. scipy/io/matlab/tests/data/testdouble_7.1_GLNX86.mat +0 -0
  418. scipy/io/matlab/tests/data/testdouble_7.4_GLNX86.mat +0 -0
  419. scipy/io/matlab/tests/data/testemptycell_5.3_SOL2.mat +0 -0
  420. scipy/io/matlab/tests/data/testemptycell_6.5.1_GLNX86.mat +0 -0
  421. scipy/io/matlab/tests/data/testemptycell_7.1_GLNX86.mat +0 -0
  422. scipy/io/matlab/tests/data/testemptycell_7.4_GLNX86.mat +0 -0
  423. scipy/io/matlab/tests/data/testfunc_7.4_GLNX86.mat +0 -0
  424. scipy/io/matlab/tests/data/testhdf5_7.4_GLNX86.mat +0 -0
  425. scipy/io/matlab/tests/data/testmatrix_4.2c_SOL2.mat +0 -0
  426. scipy/io/matlab/tests/data/testmatrix_6.1_SOL2.mat +0 -0
  427. scipy/io/matlab/tests/data/testmatrix_6.5.1_GLNX86.mat +0 -0
  428. scipy/io/matlab/tests/data/testmatrix_7.1_GLNX86.mat +0 -0
  429. scipy/io/matlab/tests/data/testmatrix_7.4_GLNX86.mat +0 -0
  430. scipy/io/matlab/tests/data/testminus_4.2c_SOL2.mat +0 -0
  431. scipy/io/matlab/tests/data/testminus_6.1_SOL2.mat +0 -0
  432. scipy/io/matlab/tests/data/testminus_6.5.1_GLNX86.mat +0 -0
  433. scipy/io/matlab/tests/data/testminus_7.1_GLNX86.mat +0 -0
  434. scipy/io/matlab/tests/data/testminus_7.4_GLNX86.mat +0 -0
  435. scipy/io/matlab/tests/data/testmulti_4.2c_SOL2.mat +0 -0
  436. scipy/io/matlab/tests/data/testmulti_7.1_GLNX86.mat +0 -0
  437. scipy/io/matlab/tests/data/testmulti_7.4_GLNX86.mat +0 -0
  438. scipy/io/matlab/tests/data/testobject_6.1_SOL2.mat +0 -0
  439. scipy/io/matlab/tests/data/testobject_6.5.1_GLNX86.mat +0 -0
  440. scipy/io/matlab/tests/data/testobject_7.1_GLNX86.mat +0 -0
  441. scipy/io/matlab/tests/data/testobject_7.4_GLNX86.mat +0 -0
  442. scipy/io/matlab/tests/data/testonechar_4.2c_SOL2.mat +0 -0
  443. scipy/io/matlab/tests/data/testonechar_6.1_SOL2.mat +0 -0
  444. scipy/io/matlab/tests/data/testonechar_6.5.1_GLNX86.mat +0 -0
  445. scipy/io/matlab/tests/data/testonechar_7.1_GLNX86.mat +0 -0
  446. scipy/io/matlab/tests/data/testonechar_7.4_GLNX86.mat +0 -0
  447. scipy/io/matlab/tests/data/testscalarcell_7.4_GLNX86.mat +0 -0
  448. scipy/io/matlab/tests/data/testsimplecell.mat +0 -0
  449. scipy/io/matlab/tests/data/testsparse_4.2c_SOL2.mat +0 -0
  450. scipy/io/matlab/tests/data/testsparse_6.1_SOL2.mat +0 -0
  451. scipy/io/matlab/tests/data/testsparse_6.5.1_GLNX86.mat +0 -0
  452. scipy/io/matlab/tests/data/testsparse_7.1_GLNX86.mat +0 -0
  453. scipy/io/matlab/tests/data/testsparse_7.4_GLNX86.mat +0 -0
  454. scipy/io/matlab/tests/data/testsparsecomplex_4.2c_SOL2.mat +0 -0
  455. scipy/io/matlab/tests/data/testsparsecomplex_6.1_SOL2.mat +0 -0
  456. scipy/io/matlab/tests/data/testsparsecomplex_6.5.1_GLNX86.mat +0 -0
  457. scipy/io/matlab/tests/data/testsparsecomplex_7.1_GLNX86.mat +0 -0
  458. scipy/io/matlab/tests/data/testsparsecomplex_7.4_GLNX86.mat +0 -0
  459. scipy/io/matlab/tests/data/testsparsefloat_7.4_GLNX86.mat +0 -0
  460. scipy/io/matlab/tests/data/teststring_4.2c_SOL2.mat +0 -0
  461. scipy/io/matlab/tests/data/teststring_6.1_SOL2.mat +0 -0
  462. scipy/io/matlab/tests/data/teststring_6.5.1_GLNX86.mat +0 -0
  463. scipy/io/matlab/tests/data/teststring_7.1_GLNX86.mat +0 -0
  464. scipy/io/matlab/tests/data/teststring_7.4_GLNX86.mat +0 -0
  465. scipy/io/matlab/tests/data/teststringarray_4.2c_SOL2.mat +0 -0
  466. scipy/io/matlab/tests/data/teststringarray_6.1_SOL2.mat +0 -0
  467. scipy/io/matlab/tests/data/teststringarray_6.5.1_GLNX86.mat +0 -0
  468. scipy/io/matlab/tests/data/teststringarray_7.1_GLNX86.mat +0 -0
  469. scipy/io/matlab/tests/data/teststringarray_7.4_GLNX86.mat +0 -0
  470. scipy/io/matlab/tests/data/teststruct_6.1_SOL2.mat +0 -0
  471. scipy/io/matlab/tests/data/teststruct_6.5.1_GLNX86.mat +0 -0
  472. scipy/io/matlab/tests/data/teststruct_7.1_GLNX86.mat +0 -0
  473. scipy/io/matlab/tests/data/teststruct_7.4_GLNX86.mat +0 -0
  474. scipy/io/matlab/tests/data/teststructarr_6.1_SOL2.mat +0 -0
  475. scipy/io/matlab/tests/data/teststructarr_6.5.1_GLNX86.mat +0 -0
  476. scipy/io/matlab/tests/data/teststructarr_7.1_GLNX86.mat +0 -0
  477. scipy/io/matlab/tests/data/teststructarr_7.4_GLNX86.mat +0 -0
  478. scipy/io/matlab/tests/data/teststructnest_6.1_SOL2.mat +0 -0
  479. scipy/io/matlab/tests/data/teststructnest_6.5.1_GLNX86.mat +0 -0
  480. scipy/io/matlab/tests/data/teststructnest_7.1_GLNX86.mat +0 -0
  481. scipy/io/matlab/tests/data/teststructnest_7.4_GLNX86.mat +0 -0
  482. scipy/io/matlab/tests/data/testunicode_7.1_GLNX86.mat +0 -0
  483. scipy/io/matlab/tests/data/testunicode_7.4_GLNX86.mat +0 -0
  484. scipy/io/matlab/tests/data/testvec_4_GLNX86.mat +0 -0
  485. scipy/io/matlab/tests/test_byteordercodes.py +29 -0
  486. scipy/io/matlab/tests/test_mio.py +1399 -0
  487. scipy/io/matlab/tests/test_mio5_utils.py +179 -0
  488. scipy/io/matlab/tests/test_mio_funcs.py +51 -0
  489. scipy/io/matlab/tests/test_mio_utils.py +45 -0
  490. scipy/io/matlab/tests/test_miobase.py +32 -0
  491. scipy/io/matlab/tests/test_pathological.py +33 -0
  492. scipy/io/matlab/tests/test_streams.py +232 -0
  493. scipy/io/mmio.py +17 -0
  494. scipy/io/netcdf.py +17 -0
  495. scipy/io/tests/__init__.py +0 -0
  496. scipy/io/tests/data/Transparent Busy.ani +0 -0
  497. scipy/io/tests/data/array_float32_1d.sav +0 -0
  498. scipy/io/tests/data/array_float32_2d.sav +0 -0
  499. scipy/io/tests/data/array_float32_3d.sav +0 -0
  500. scipy/io/tests/data/array_float32_4d.sav +0 -0
  501. scipy/io/tests/data/array_float32_5d.sav +0 -0
  502. scipy/io/tests/data/array_float32_6d.sav +0 -0
  503. scipy/io/tests/data/array_float32_7d.sav +0 -0
  504. scipy/io/tests/data/array_float32_8d.sav +0 -0
  505. scipy/io/tests/data/array_float32_pointer_1d.sav +0 -0
  506. scipy/io/tests/data/array_float32_pointer_2d.sav +0 -0
  507. scipy/io/tests/data/array_float32_pointer_3d.sav +0 -0
  508. scipy/io/tests/data/array_float32_pointer_4d.sav +0 -0
  509. scipy/io/tests/data/array_float32_pointer_5d.sav +0 -0
  510. scipy/io/tests/data/array_float32_pointer_6d.sav +0 -0
  511. scipy/io/tests/data/array_float32_pointer_7d.sav +0 -0
  512. scipy/io/tests/data/array_float32_pointer_8d.sav +0 -0
  513. scipy/io/tests/data/example_1.nc +0 -0
  514. scipy/io/tests/data/example_2.nc +0 -0
  515. scipy/io/tests/data/example_3_maskedvals.nc +0 -0
  516. scipy/io/tests/data/fortran-3x3d-2i.dat +0 -0
  517. scipy/io/tests/data/fortran-mixed.dat +0 -0
  518. scipy/io/tests/data/fortran-sf8-11x1x10.dat +0 -0
  519. scipy/io/tests/data/fortran-sf8-15x10x22.dat +0 -0
  520. scipy/io/tests/data/fortran-sf8-1x1x1.dat +0 -0
  521. scipy/io/tests/data/fortran-sf8-1x1x5.dat +0 -0
  522. scipy/io/tests/data/fortran-sf8-1x1x7.dat +0 -0
  523. scipy/io/tests/data/fortran-sf8-1x3x5.dat +0 -0
  524. scipy/io/tests/data/fortran-si4-11x1x10.dat +0 -0
  525. scipy/io/tests/data/fortran-si4-15x10x22.dat +0 -0
  526. scipy/io/tests/data/fortran-si4-1x1x1.dat +0 -0
  527. scipy/io/tests/data/fortran-si4-1x1x5.dat +0 -0
  528. scipy/io/tests/data/fortran-si4-1x1x7.dat +0 -0
  529. scipy/io/tests/data/fortran-si4-1x3x5.dat +0 -0
  530. scipy/io/tests/data/invalid_pointer.sav +0 -0
  531. scipy/io/tests/data/null_pointer.sav +0 -0
  532. scipy/io/tests/data/scalar_byte.sav +0 -0
  533. scipy/io/tests/data/scalar_byte_descr.sav +0 -0
  534. scipy/io/tests/data/scalar_complex32.sav +0 -0
  535. scipy/io/tests/data/scalar_complex64.sav +0 -0
  536. scipy/io/tests/data/scalar_float32.sav +0 -0
  537. scipy/io/tests/data/scalar_float64.sav +0 -0
  538. scipy/io/tests/data/scalar_heap_pointer.sav +0 -0
  539. scipy/io/tests/data/scalar_int16.sav +0 -0
  540. scipy/io/tests/data/scalar_int32.sav +0 -0
  541. scipy/io/tests/data/scalar_int64.sav +0 -0
  542. scipy/io/tests/data/scalar_string.sav +0 -0
  543. scipy/io/tests/data/scalar_uint16.sav +0 -0
  544. scipy/io/tests/data/scalar_uint32.sav +0 -0
  545. scipy/io/tests/data/scalar_uint64.sav +0 -0
  546. scipy/io/tests/data/struct_arrays.sav +0 -0
  547. scipy/io/tests/data/struct_arrays_byte_idl80.sav +0 -0
  548. scipy/io/tests/data/struct_arrays_replicated.sav +0 -0
  549. scipy/io/tests/data/struct_arrays_replicated_3d.sav +0 -0
  550. scipy/io/tests/data/struct_inherit.sav +0 -0
  551. scipy/io/tests/data/struct_pointer_arrays.sav +0 -0
  552. scipy/io/tests/data/struct_pointer_arrays_replicated.sav +0 -0
  553. scipy/io/tests/data/struct_pointer_arrays_replicated_3d.sav +0 -0
  554. scipy/io/tests/data/struct_pointers.sav +0 -0
  555. scipy/io/tests/data/struct_pointers_replicated.sav +0 -0
  556. scipy/io/tests/data/struct_pointers_replicated_3d.sav +0 -0
  557. scipy/io/tests/data/struct_scalars.sav +0 -0
  558. scipy/io/tests/data/struct_scalars_replicated.sav +0 -0
  559. scipy/io/tests/data/struct_scalars_replicated_3d.sav +0 -0
  560. scipy/io/tests/data/test-1234Hz-le-1ch-10S-20bit-extra.wav +0 -0
  561. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-be.wav +0 -0
  562. scipy/io/tests/data/test-44100Hz-2ch-32bit-float-le.wav +0 -0
  563. scipy/io/tests/data/test-44100Hz-be-1ch-4bytes.wav +0 -0
  564. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof-no-data.wav +0 -0
  565. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof.wav +0 -0
  566. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-incomplete-chunk.wav +0 -0
  567. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-rf64.wav +0 -0
  568. scipy/io/tests/data/test-44100Hz-le-1ch-4bytes.wav +0 -0
  569. scipy/io/tests/data/test-48000Hz-2ch-64bit-float-le-wavex.wav +0 -0
  570. scipy/io/tests/data/test-8000Hz-be-3ch-5S-24bit.wav +0 -0
  571. scipy/io/tests/data/test-8000Hz-le-1ch-1byte-ulaw.wav +0 -0
  572. scipy/io/tests/data/test-8000Hz-le-2ch-1byteu.wav +0 -0
  573. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-inconsistent.wav +0 -0
  574. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-rf64.wav +0 -0
  575. scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit.wav +0 -0
  576. scipy/io/tests/data/test-8000Hz-le-3ch-5S-36bit.wav +0 -0
  577. scipy/io/tests/data/test-8000Hz-le-3ch-5S-45bit.wav +0 -0
  578. scipy/io/tests/data/test-8000Hz-le-3ch-5S-53bit.wav +0 -0
  579. scipy/io/tests/data/test-8000Hz-le-3ch-5S-64bit.wav +0 -0
  580. scipy/io/tests/data/test-8000Hz-le-4ch-9S-12bit.wav +0 -0
  581. scipy/io/tests/data/test-8000Hz-le-5ch-9S-5bit.wav +0 -0
  582. scipy/io/tests/data/various_compressed.sav +0 -0
  583. scipy/io/tests/test_fortran.py +264 -0
  584. scipy/io/tests/test_idl.py +483 -0
  585. scipy/io/tests/test_mmio.py +831 -0
  586. scipy/io/tests/test_netcdf.py +550 -0
  587. scipy/io/tests/test_paths.py +93 -0
  588. scipy/io/tests/test_wavfile.py +501 -0
  589. scipy/io/wavfile.py +938 -0
  590. scipy/linalg/__init__.pxd +1 -0
  591. scipy/linalg/__init__.py +236 -0
  592. scipy/linalg/_basic.py +2146 -0
  593. scipy/linalg/_blas_subroutines.h +164 -0
  594. scipy/linalg/_cythonized_array_utils.cpython-311-darwin.so +0 -0
  595. scipy/linalg/_cythonized_array_utils.pxd +40 -0
  596. scipy/linalg/_cythonized_array_utils.pyi +16 -0
  597. scipy/linalg/_decomp.py +1645 -0
  598. scipy/linalg/_decomp_cholesky.py +413 -0
  599. scipy/linalg/_decomp_cossin.py +236 -0
  600. scipy/linalg/_decomp_interpolative.cpython-311-darwin.so +0 -0
  601. scipy/linalg/_decomp_ldl.py +356 -0
  602. scipy/linalg/_decomp_lu.py +401 -0
  603. scipy/linalg/_decomp_lu_cython.cpython-311-darwin.so +0 -0
  604. scipy/linalg/_decomp_lu_cython.pyi +6 -0
  605. scipy/linalg/_decomp_polar.py +113 -0
  606. scipy/linalg/_decomp_qr.py +494 -0
  607. scipy/linalg/_decomp_qz.py +452 -0
  608. scipy/linalg/_decomp_schur.py +336 -0
  609. scipy/linalg/_decomp_svd.py +545 -0
  610. scipy/linalg/_decomp_update.cpython-311-darwin.so +0 -0
  611. scipy/linalg/_expm_frechet.py +417 -0
  612. scipy/linalg/_fblas.cpython-311-darwin.so +0 -0
  613. scipy/linalg/_flapack.cpython-311-darwin.so +0 -0
  614. scipy/linalg/_lapack_subroutines.h +1521 -0
  615. scipy/linalg/_linalg_pythran.cpython-311-darwin.so +0 -0
  616. scipy/linalg/_matfuncs.py +1050 -0
  617. scipy/linalg/_matfuncs_expm.cpython-311-darwin.so +0 -0
  618. scipy/linalg/_matfuncs_expm.pyi +6 -0
  619. scipy/linalg/_matfuncs_inv_ssq.py +886 -0
  620. scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-darwin.so +0 -0
  621. scipy/linalg/_matfuncs_sqrtm.py +107 -0
  622. scipy/linalg/_matfuncs_sqrtm_triu.cpython-311-darwin.so +0 -0
  623. scipy/linalg/_misc.py +191 -0
  624. scipy/linalg/_procrustes.py +113 -0
  625. scipy/linalg/_sketches.py +189 -0
  626. scipy/linalg/_solve_toeplitz.cpython-311-darwin.so +0 -0
  627. scipy/linalg/_solvers.py +862 -0
  628. scipy/linalg/_special_matrices.py +1322 -0
  629. scipy/linalg/_testutils.py +65 -0
  630. scipy/linalg/basic.py +23 -0
  631. scipy/linalg/blas.py +484 -0
  632. scipy/linalg/cython_blas.cpython-311-darwin.so +0 -0
  633. scipy/linalg/cython_blas.pxd +169 -0
  634. scipy/linalg/cython_blas.pyx +1432 -0
  635. scipy/linalg/cython_lapack.cpython-311-darwin.so +0 -0
  636. scipy/linalg/cython_lapack.pxd +1528 -0
  637. scipy/linalg/cython_lapack.pyx +12045 -0
  638. scipy/linalg/decomp.py +23 -0
  639. scipy/linalg/decomp_cholesky.py +21 -0
  640. scipy/linalg/decomp_lu.py +21 -0
  641. scipy/linalg/decomp_qr.py +20 -0
  642. scipy/linalg/decomp_schur.py +21 -0
  643. scipy/linalg/decomp_svd.py +21 -0
  644. scipy/linalg/interpolative.py +989 -0
  645. scipy/linalg/lapack.py +1081 -0
  646. scipy/linalg/matfuncs.py +23 -0
  647. scipy/linalg/misc.py +21 -0
  648. scipy/linalg/special_matrices.py +22 -0
  649. scipy/linalg/tests/__init__.py +0 -0
  650. scipy/linalg/tests/_cython_examples/extending.pyx +23 -0
  651. scipy/linalg/tests/_cython_examples/meson.build +34 -0
  652. scipy/linalg/tests/data/carex_15_data.npz +0 -0
  653. scipy/linalg/tests/data/carex_18_data.npz +0 -0
  654. scipy/linalg/tests/data/carex_19_data.npz +0 -0
  655. scipy/linalg/tests/data/carex_20_data.npz +0 -0
  656. scipy/linalg/tests/data/carex_6_data.npz +0 -0
  657. scipy/linalg/tests/data/gendare_20170120_data.npz +0 -0
  658. scipy/linalg/tests/test_basic.py +2074 -0
  659. scipy/linalg/tests/test_batch.py +588 -0
  660. scipy/linalg/tests/test_blas.py +1127 -0
  661. scipy/linalg/tests/test_cython_blas.py +118 -0
  662. scipy/linalg/tests/test_cython_lapack.py +22 -0
  663. scipy/linalg/tests/test_cythonized_array_utils.py +130 -0
  664. scipy/linalg/tests/test_decomp.py +3189 -0
  665. scipy/linalg/tests/test_decomp_cholesky.py +268 -0
  666. scipy/linalg/tests/test_decomp_cossin.py +314 -0
  667. scipy/linalg/tests/test_decomp_ldl.py +137 -0
  668. scipy/linalg/tests/test_decomp_lu.py +308 -0
  669. scipy/linalg/tests/test_decomp_polar.py +110 -0
  670. scipy/linalg/tests/test_decomp_update.py +1701 -0
  671. scipy/linalg/tests/test_extending.py +46 -0
  672. scipy/linalg/tests/test_fblas.py +607 -0
  673. scipy/linalg/tests/test_interpolative.py +232 -0
  674. scipy/linalg/tests/test_lapack.py +3616 -0
  675. scipy/linalg/tests/test_matfuncs.py +1118 -0
  676. scipy/linalg/tests/test_matmul_toeplitz.py +136 -0
  677. scipy/linalg/tests/test_procrustes.py +214 -0
  678. scipy/linalg/tests/test_sketches.py +118 -0
  679. scipy/linalg/tests/test_solve_toeplitz.py +150 -0
  680. scipy/linalg/tests/test_solvers.py +844 -0
  681. scipy/linalg/tests/test_special_matrices.py +636 -0
  682. scipy/misc/__init__.py +6 -0
  683. scipy/misc/common.py +6 -0
  684. scipy/misc/doccer.py +6 -0
  685. scipy/ndimage/__init__.py +174 -0
  686. scipy/ndimage/_ctest.cpython-311-darwin.so +0 -0
  687. scipy/ndimage/_cytest.cpython-311-darwin.so +0 -0
  688. scipy/ndimage/_delegators.py +303 -0
  689. scipy/ndimage/_filters.py +2393 -0
  690. scipy/ndimage/_fourier.py +306 -0
  691. scipy/ndimage/_interpolation.py +1033 -0
  692. scipy/ndimage/_measurements.py +1689 -0
  693. scipy/ndimage/_morphology.py +2634 -0
  694. scipy/ndimage/_nd_image.cpython-311-darwin.so +0 -0
  695. scipy/ndimage/_ndimage_api.py +16 -0
  696. scipy/ndimage/_ni_docstrings.py +214 -0
  697. scipy/ndimage/_ni_label.cpython-311-darwin.so +0 -0
  698. scipy/ndimage/_ni_support.py +139 -0
  699. scipy/ndimage/_rank_filter_1d.cpython-311-darwin.so +0 -0
  700. scipy/ndimage/_support_alternative_backends.py +84 -0
  701. scipy/ndimage/filters.py +27 -0
  702. scipy/ndimage/fourier.py +21 -0
  703. scipy/ndimage/interpolation.py +22 -0
  704. scipy/ndimage/measurements.py +24 -0
  705. scipy/ndimage/morphology.py +27 -0
  706. scipy/ndimage/tests/__init__.py +12 -0
  707. scipy/ndimage/tests/data/label_inputs.txt +21 -0
  708. scipy/ndimage/tests/data/label_results.txt +294 -0
  709. scipy/ndimage/tests/data/label_strels.txt +42 -0
  710. scipy/ndimage/tests/dots.png +0 -0
  711. scipy/ndimage/tests/test_c_api.py +102 -0
  712. scipy/ndimage/tests/test_datatypes.py +67 -0
  713. scipy/ndimage/tests/test_filters.py +2998 -0
  714. scipy/ndimage/tests/test_fourier.py +187 -0
  715. scipy/ndimage/tests/test_interpolation.py +1491 -0
  716. scipy/ndimage/tests/test_measurements.py +1592 -0
  717. scipy/ndimage/tests/test_morphology.py +2950 -0
  718. scipy/ndimage/tests/test_ni_support.py +78 -0
  719. scipy/ndimage/tests/test_splines.py +70 -0
  720. scipy/odr/__init__.py +131 -0
  721. scipy/odr/__odrpack.cpython-311-darwin.so +0 -0
  722. scipy/odr/_add_newdocs.py +34 -0
  723. scipy/odr/_models.py +315 -0
  724. scipy/odr/_odrpack.py +1154 -0
  725. scipy/odr/models.py +20 -0
  726. scipy/odr/odrpack.py +21 -0
  727. scipy/odr/tests/__init__.py +0 -0
  728. scipy/odr/tests/test_odr.py +607 -0
  729. scipy/optimize/__init__.pxd +1 -0
  730. scipy/optimize/__init__.py +460 -0
  731. scipy/optimize/_basinhopping.py +741 -0
  732. scipy/optimize/_bglu_dense.cpython-311-darwin.so +0 -0
  733. scipy/optimize/_bracket.py +706 -0
  734. scipy/optimize/_chandrupatla.py +551 -0
  735. scipy/optimize/_cobyla_py.py +297 -0
  736. scipy/optimize/_cobyqa_py.py +72 -0
  737. scipy/optimize/_constraints.py +598 -0
  738. scipy/optimize/_dcsrch.py +728 -0
  739. scipy/optimize/_differentiable_functions.py +835 -0
  740. scipy/optimize/_differentialevolution.py +1970 -0
  741. scipy/optimize/_direct.cpython-311-darwin.so +0 -0
  742. scipy/optimize/_direct_py.py +280 -0
  743. scipy/optimize/_dual_annealing.py +732 -0
  744. scipy/optimize/_elementwise.py +798 -0
  745. scipy/optimize/_group_columns.cpython-311-darwin.so +0 -0
  746. scipy/optimize/_hessian_update_strategy.py +479 -0
  747. scipy/optimize/_highspy/__init__.py +0 -0
  748. scipy/optimize/_highspy/_core.cpython-311-darwin.so +0 -0
  749. scipy/optimize/_highspy/_highs_options.cpython-311-darwin.so +0 -0
  750. scipy/optimize/_highspy/_highs_wrapper.py +338 -0
  751. scipy/optimize/_isotonic.py +157 -0
  752. scipy/optimize/_lbfgsb.cpython-311-darwin.so +0 -0
  753. scipy/optimize/_lbfgsb_py.py +619 -0
  754. scipy/optimize/_linesearch.py +896 -0
  755. scipy/optimize/_linprog.py +733 -0
  756. scipy/optimize/_linprog_doc.py +1434 -0
  757. scipy/optimize/_linprog_highs.py +422 -0
  758. scipy/optimize/_linprog_ip.py +1141 -0
  759. scipy/optimize/_linprog_rs.py +572 -0
  760. scipy/optimize/_linprog_simplex.py +663 -0
  761. scipy/optimize/_linprog_util.py +1521 -0
  762. scipy/optimize/_lsap.cpython-311-darwin.so +0 -0
  763. scipy/optimize/_lsq/__init__.py +5 -0
  764. scipy/optimize/_lsq/bvls.py +183 -0
  765. scipy/optimize/_lsq/common.py +731 -0
  766. scipy/optimize/_lsq/dogbox.py +345 -0
  767. scipy/optimize/_lsq/givens_elimination.cpython-311-darwin.so +0 -0
  768. scipy/optimize/_lsq/least_squares.py +1044 -0
  769. scipy/optimize/_lsq/lsq_linear.py +361 -0
  770. scipy/optimize/_lsq/trf.py +587 -0
  771. scipy/optimize/_lsq/trf_linear.py +249 -0
  772. scipy/optimize/_milp.py +394 -0
  773. scipy/optimize/_minimize.py +1200 -0
  774. scipy/optimize/_minpack.cpython-311-darwin.so +0 -0
  775. scipy/optimize/_minpack_py.py +1178 -0
  776. scipy/optimize/_moduleTNC.cpython-311-darwin.so +0 -0
  777. scipy/optimize/_nnls.py +96 -0
  778. scipy/optimize/_nonlin.py +1634 -0
  779. scipy/optimize/_numdiff.py +963 -0
  780. scipy/optimize/_optimize.py +4169 -0
  781. scipy/optimize/_pava_pybind.cpython-311-darwin.so +0 -0
  782. scipy/optimize/_qap.py +760 -0
  783. scipy/optimize/_remove_redundancy.py +522 -0
  784. scipy/optimize/_root.py +732 -0
  785. scipy/optimize/_root_scalar.py +538 -0
  786. scipy/optimize/_shgo.py +1606 -0
  787. scipy/optimize/_shgo_lib/__init__.py +0 -0
  788. scipy/optimize/_shgo_lib/_complex.py +1225 -0
  789. scipy/optimize/_shgo_lib/_vertex.py +460 -0
  790. scipy/optimize/_slsqp_py.py +603 -0
  791. scipy/optimize/_slsqplib.cpython-311-darwin.so +0 -0
  792. scipy/optimize/_spectral.py +260 -0
  793. scipy/optimize/_tnc.py +438 -0
  794. scipy/optimize/_trlib/__init__.py +12 -0
  795. scipy/optimize/_trlib/_trlib.cpython-311-darwin.so +0 -0
  796. scipy/optimize/_trustregion.py +318 -0
  797. scipy/optimize/_trustregion_constr/__init__.py +6 -0
  798. scipy/optimize/_trustregion_constr/canonical_constraint.py +390 -0
  799. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +231 -0
  800. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +584 -0
  801. scipy/optimize/_trustregion_constr/projections.py +411 -0
  802. scipy/optimize/_trustregion_constr/qp_subproblem.py +637 -0
  803. scipy/optimize/_trustregion_constr/report.py +49 -0
  804. scipy/optimize/_trustregion_constr/tests/__init__.py +0 -0
  805. scipy/optimize/_trustregion_constr/tests/test_canonical_constraint.py +296 -0
  806. scipy/optimize/_trustregion_constr/tests/test_nested_minimize.py +39 -0
  807. scipy/optimize/_trustregion_constr/tests/test_projections.py +214 -0
  808. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +645 -0
  809. scipy/optimize/_trustregion_constr/tests/test_report.py +34 -0
  810. scipy/optimize/_trustregion_constr/tr_interior_point.py +361 -0
  811. scipy/optimize/_trustregion_dogleg.py +122 -0
  812. scipy/optimize/_trustregion_exact.py +437 -0
  813. scipy/optimize/_trustregion_krylov.py +65 -0
  814. scipy/optimize/_trustregion_ncg.py +126 -0
  815. scipy/optimize/_tstutils.py +972 -0
  816. scipy/optimize/_zeros.cpython-311-darwin.so +0 -0
  817. scipy/optimize/_zeros_py.py +1475 -0
  818. scipy/optimize/cobyla.py +19 -0
  819. scipy/optimize/cython_optimize/__init__.py +133 -0
  820. scipy/optimize/cython_optimize/_zeros.cpython-311-darwin.so +0 -0
  821. scipy/optimize/cython_optimize/_zeros.pxd +33 -0
  822. scipy/optimize/cython_optimize/c_zeros.pxd +26 -0
  823. scipy/optimize/cython_optimize.pxd +11 -0
  824. scipy/optimize/elementwise.py +38 -0
  825. scipy/optimize/lbfgsb.py +23 -0
  826. scipy/optimize/linesearch.py +18 -0
  827. scipy/optimize/minpack.py +27 -0
  828. scipy/optimize/minpack2.py +17 -0
  829. scipy/optimize/moduleTNC.py +19 -0
  830. scipy/optimize/nonlin.py +29 -0
  831. scipy/optimize/optimize.py +40 -0
  832. scipy/optimize/slsqp.py +22 -0
  833. scipy/optimize/tests/__init__.py +0 -0
  834. scipy/optimize/tests/_cython_examples/extending.pyx +43 -0
  835. scipy/optimize/tests/_cython_examples/meson.build +32 -0
  836. scipy/optimize/tests/test__basinhopping.py +535 -0
  837. scipy/optimize/tests/test__differential_evolution.py +1703 -0
  838. scipy/optimize/tests/test__dual_annealing.py +416 -0
  839. scipy/optimize/tests/test__linprog_clean_inputs.py +312 -0
  840. scipy/optimize/tests/test__numdiff.py +885 -0
  841. scipy/optimize/tests/test__remove_redundancy.py +228 -0
  842. scipy/optimize/tests/test__root.py +124 -0
  843. scipy/optimize/tests/test__shgo.py +1164 -0
  844. scipy/optimize/tests/test__spectral.py +226 -0
  845. scipy/optimize/tests/test_bracket.py +896 -0
  846. scipy/optimize/tests/test_chandrupatla.py +982 -0
  847. scipy/optimize/tests/test_cobyla.py +195 -0
  848. scipy/optimize/tests/test_cobyqa.py +252 -0
  849. scipy/optimize/tests/test_constraint_conversion.py +286 -0
  850. scipy/optimize/tests/test_constraints.py +255 -0
  851. scipy/optimize/tests/test_cython_optimize.py +92 -0
  852. scipy/optimize/tests/test_differentiable_functions.py +1025 -0
  853. scipy/optimize/tests/test_direct.py +321 -0
  854. scipy/optimize/tests/test_extending.py +28 -0
  855. scipy/optimize/tests/test_hessian_update_strategy.py +300 -0
  856. scipy/optimize/tests/test_isotonic_regression.py +167 -0
  857. scipy/optimize/tests/test_lbfgsb_hessinv.py +65 -0
  858. scipy/optimize/tests/test_lbfgsb_setulb.py +122 -0
  859. scipy/optimize/tests/test_least_squares.py +986 -0
  860. scipy/optimize/tests/test_linear_assignment.py +116 -0
  861. scipy/optimize/tests/test_linesearch.py +328 -0
  862. scipy/optimize/tests/test_linprog.py +2577 -0
  863. scipy/optimize/tests/test_lsq_common.py +297 -0
  864. scipy/optimize/tests/test_lsq_linear.py +287 -0
  865. scipy/optimize/tests/test_milp.py +459 -0
  866. scipy/optimize/tests/test_minimize_constrained.py +845 -0
  867. scipy/optimize/tests/test_minpack.py +1194 -0
  868. scipy/optimize/tests/test_nnls.py +469 -0
  869. scipy/optimize/tests/test_nonlin.py +572 -0
  870. scipy/optimize/tests/test_optimize.py +3335 -0
  871. scipy/optimize/tests/test_quadratic_assignment.py +455 -0
  872. scipy/optimize/tests/test_regression.py +40 -0
  873. scipy/optimize/tests/test_slsqp.py +645 -0
  874. scipy/optimize/tests/test_tnc.py +345 -0
  875. scipy/optimize/tests/test_trustregion.py +110 -0
  876. scipy/optimize/tests/test_trustregion_exact.py +351 -0
  877. scipy/optimize/tests/test_trustregion_krylov.py +170 -0
  878. scipy/optimize/tests/test_zeros.py +998 -0
  879. scipy/optimize/tnc.py +22 -0
  880. scipy/optimize/zeros.py +26 -0
  881. scipy/signal/__init__.py +316 -0
  882. scipy/signal/_arraytools.py +264 -0
  883. scipy/signal/_czt.py +575 -0
  884. scipy/signal/_delegators.py +568 -0
  885. scipy/signal/_filter_design.py +5881 -0
  886. scipy/signal/_fir_filter_design.py +1458 -0
  887. scipy/signal/_lti_conversion.py +534 -0
  888. scipy/signal/_ltisys.py +3546 -0
  889. scipy/signal/_max_len_seq.py +139 -0
  890. scipy/signal/_max_len_seq_inner.cpython-311-darwin.so +0 -0
  891. scipy/signal/_peak_finding.py +1310 -0
  892. scipy/signal/_peak_finding_utils.cpython-311-darwin.so +0 -0
  893. scipy/signal/_polyutils.py +172 -0
  894. scipy/signal/_savitzky_golay.py +357 -0
  895. scipy/signal/_short_time_fft.py +2187 -0
  896. scipy/signal/_signal_api.py +30 -0
  897. scipy/signal/_signaltools.py +5309 -0
  898. scipy/signal/_sigtools.cpython-311-darwin.so +0 -0
  899. scipy/signal/_sosfilt.cpython-311-darwin.so +0 -0
  900. scipy/signal/_spectral_py.py +2462 -0
  901. scipy/signal/_spline.cpython-311-darwin.so +0 -0
  902. scipy/signal/_spline.pyi +34 -0
  903. scipy/signal/_spline_filters.py +848 -0
  904. scipy/signal/_support_alternative_backends.py +73 -0
  905. scipy/signal/_upfirdn.py +219 -0
  906. scipy/signal/_upfirdn_apply.cpython-311-darwin.so +0 -0
  907. scipy/signal/_waveforms.py +687 -0
  908. scipy/signal/_wavelets.py +29 -0
  909. scipy/signal/bsplines.py +21 -0
  910. scipy/signal/filter_design.py +28 -0
  911. scipy/signal/fir_filter_design.py +21 -0
  912. scipy/signal/lti_conversion.py +20 -0
  913. scipy/signal/ltisys.py +25 -0
  914. scipy/signal/signaltools.py +27 -0
  915. scipy/signal/spectral.py +21 -0
  916. scipy/signal/spline.py +18 -0
  917. scipy/signal/tests/__init__.py +0 -0
  918. scipy/signal/tests/_scipy_spectral_test_shim.py +311 -0
  919. scipy/signal/tests/mpsig.py +122 -0
  920. scipy/signal/tests/test_array_tools.py +111 -0
  921. scipy/signal/tests/test_bsplines.py +365 -0
  922. scipy/signal/tests/test_cont2discrete.py +424 -0
  923. scipy/signal/tests/test_czt.py +221 -0
  924. scipy/signal/tests/test_dltisys.py +599 -0
  925. scipy/signal/tests/test_filter_design.py +4725 -0
  926. scipy/signal/tests/test_fir_filter_design.py +846 -0
  927. scipy/signal/tests/test_ltisys.py +1225 -0
  928. scipy/signal/tests/test_max_len_seq.py +71 -0
  929. scipy/signal/tests/test_peak_finding.py +915 -0
  930. scipy/signal/tests/test_result_type.py +51 -0
  931. scipy/signal/tests/test_savitzky_golay.py +363 -0
  932. scipy/signal/tests/test_short_time_fft.py +1098 -0
  933. scipy/signal/tests/test_signaltools.py +4729 -0
  934. scipy/signal/tests/test_spectral.py +2072 -0
  935. scipy/signal/tests/test_splines.py +427 -0
  936. scipy/signal/tests/test_upfirdn.py +322 -0
  937. scipy/signal/tests/test_waveforms.py +400 -0
  938. scipy/signal/tests/test_wavelets.py +59 -0
  939. scipy/signal/tests/test_windows.py +987 -0
  940. scipy/signal/waveforms.py +20 -0
  941. scipy/signal/wavelets.py +17 -0
  942. scipy/signal/windows/__init__.py +52 -0
  943. scipy/signal/windows/_windows.py +2513 -0
  944. scipy/signal/windows/windows.py +23 -0
  945. scipy/sparse/__init__.py +350 -0
  946. scipy/sparse/_base.py +1610 -0
  947. scipy/sparse/_bsr.py +880 -0
  948. scipy/sparse/_compressed.py +1328 -0
  949. scipy/sparse/_construct.py +1454 -0
  950. scipy/sparse/_coo.py +1581 -0
  951. scipy/sparse/_csc.py +367 -0
  952. scipy/sparse/_csparsetools.cpython-311-darwin.so +0 -0
  953. scipy/sparse/_csr.py +558 -0
  954. scipy/sparse/_data.py +569 -0
  955. scipy/sparse/_dia.py +677 -0
  956. scipy/sparse/_dok.py +669 -0
  957. scipy/sparse/_extract.py +178 -0
  958. scipy/sparse/_index.py +444 -0
  959. scipy/sparse/_lil.py +632 -0
  960. scipy/sparse/_matrix.py +169 -0
  961. scipy/sparse/_matrix_io.py +167 -0
  962. scipy/sparse/_sparsetools.cpython-311-darwin.so +0 -0
  963. scipy/sparse/_spfuncs.py +76 -0
  964. scipy/sparse/_sputils.py +632 -0
  965. scipy/sparse/base.py +24 -0
  966. scipy/sparse/bsr.py +22 -0
  967. scipy/sparse/compressed.py +20 -0
  968. scipy/sparse/construct.py +38 -0
  969. scipy/sparse/coo.py +23 -0
  970. scipy/sparse/csc.py +22 -0
  971. scipy/sparse/csgraph/__init__.py +210 -0
  972. scipy/sparse/csgraph/_flow.cpython-311-darwin.so +0 -0
  973. scipy/sparse/csgraph/_laplacian.py +563 -0
  974. scipy/sparse/csgraph/_matching.cpython-311-darwin.so +0 -0
  975. scipy/sparse/csgraph/_min_spanning_tree.cpython-311-darwin.so +0 -0
  976. scipy/sparse/csgraph/_reordering.cpython-311-darwin.so +0 -0
  977. scipy/sparse/csgraph/_shortest_path.cpython-311-darwin.so +0 -0
  978. scipy/sparse/csgraph/_tools.cpython-311-darwin.so +0 -0
  979. scipy/sparse/csgraph/_traversal.cpython-311-darwin.so +0 -0
  980. scipy/sparse/csgraph/_validation.py +66 -0
  981. scipy/sparse/csgraph/tests/__init__.py +0 -0
  982. scipy/sparse/csgraph/tests/test_connected_components.py +119 -0
  983. scipy/sparse/csgraph/tests/test_conversions.py +61 -0
  984. scipy/sparse/csgraph/tests/test_flow.py +209 -0
  985. scipy/sparse/csgraph/tests/test_graph_laplacian.py +368 -0
  986. scipy/sparse/csgraph/tests/test_matching.py +307 -0
  987. scipy/sparse/csgraph/tests/test_pydata_sparse.py +197 -0
  988. scipy/sparse/csgraph/tests/test_reordering.py +70 -0
  989. scipy/sparse/csgraph/tests/test_shortest_path.py +540 -0
  990. scipy/sparse/csgraph/tests/test_spanning_tree.py +66 -0
  991. scipy/sparse/csgraph/tests/test_traversal.py +148 -0
  992. scipy/sparse/csr.py +22 -0
  993. scipy/sparse/data.py +18 -0
  994. scipy/sparse/dia.py +22 -0
  995. scipy/sparse/dok.py +22 -0
  996. scipy/sparse/extract.py +23 -0
  997. scipy/sparse/lil.py +22 -0
  998. scipy/sparse/linalg/__init__.py +148 -0
  999. scipy/sparse/linalg/_dsolve/__init__.py +71 -0
  1000. scipy/sparse/linalg/_dsolve/_add_newdocs.py +147 -0
  1001. scipy/sparse/linalg/_dsolve/_superlu.cpython-311-darwin.so +0 -0
  1002. scipy/sparse/linalg/_dsolve/linsolve.py +882 -0
  1003. scipy/sparse/linalg/_dsolve/tests/__init__.py +0 -0
  1004. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +928 -0
  1005. scipy/sparse/linalg/_eigen/__init__.py +22 -0
  1006. scipy/sparse/linalg/_eigen/_svds.py +540 -0
  1007. scipy/sparse/linalg/_eigen/_svds_doc.py +382 -0
  1008. scipy/sparse/linalg/_eigen/arpack/COPYING +45 -0
  1009. scipy/sparse/linalg/_eigen/arpack/__init__.py +20 -0
  1010. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-311-darwin.so +0 -0
  1011. scipy/sparse/linalg/_eigen/arpack/arpack.py +1706 -0
  1012. scipy/sparse/linalg/_eigen/arpack/tests/__init__.py +0 -0
  1013. scipy/sparse/linalg/_eigen/arpack/tests/test_arpack.py +717 -0
  1014. scipy/sparse/linalg/_eigen/lobpcg/__init__.py +16 -0
  1015. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +1110 -0
  1016. scipy/sparse/linalg/_eigen/lobpcg/tests/__init__.py +0 -0
  1017. scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py +725 -0
  1018. scipy/sparse/linalg/_eigen/tests/__init__.py +0 -0
  1019. scipy/sparse/linalg/_eigen/tests/test_svds.py +886 -0
  1020. scipy/sparse/linalg/_expm_multiply.py +816 -0
  1021. scipy/sparse/linalg/_interface.py +920 -0
  1022. scipy/sparse/linalg/_isolve/__init__.py +20 -0
  1023. scipy/sparse/linalg/_isolve/_gcrotmk.py +503 -0
  1024. scipy/sparse/linalg/_isolve/iterative.py +1051 -0
  1025. scipy/sparse/linalg/_isolve/lgmres.py +230 -0
  1026. scipy/sparse/linalg/_isolve/lsmr.py +486 -0
  1027. scipy/sparse/linalg/_isolve/lsqr.py +589 -0
  1028. scipy/sparse/linalg/_isolve/minres.py +372 -0
  1029. scipy/sparse/linalg/_isolve/tests/__init__.py +0 -0
  1030. scipy/sparse/linalg/_isolve/tests/test_gcrotmk.py +183 -0
  1031. scipy/sparse/linalg/_isolve/tests/test_iterative.py +809 -0
  1032. scipy/sparse/linalg/_isolve/tests/test_lgmres.py +225 -0
  1033. scipy/sparse/linalg/_isolve/tests/test_lsmr.py +185 -0
  1034. scipy/sparse/linalg/_isolve/tests/test_lsqr.py +120 -0
  1035. scipy/sparse/linalg/_isolve/tests/test_minres.py +97 -0
  1036. scipy/sparse/linalg/_isolve/tests/test_utils.py +9 -0
  1037. scipy/sparse/linalg/_isolve/tfqmr.py +179 -0
  1038. scipy/sparse/linalg/_isolve/utils.py +121 -0
  1039. scipy/sparse/linalg/_matfuncs.py +940 -0
  1040. scipy/sparse/linalg/_norm.py +195 -0
  1041. scipy/sparse/linalg/_onenormest.py +467 -0
  1042. scipy/sparse/linalg/_propack/_cpropack.cpython-311-darwin.so +0 -0
  1043. scipy/sparse/linalg/_propack/_dpropack.cpython-311-darwin.so +0 -0
  1044. scipy/sparse/linalg/_propack/_spropack.cpython-311-darwin.so +0 -0
  1045. scipy/sparse/linalg/_propack/_zpropack.cpython-311-darwin.so +0 -0
  1046. scipy/sparse/linalg/_special_sparse_arrays.py +949 -0
  1047. scipy/sparse/linalg/_svdp.py +309 -0
  1048. scipy/sparse/linalg/dsolve.py +22 -0
  1049. scipy/sparse/linalg/eigen.py +21 -0
  1050. scipy/sparse/linalg/interface.py +20 -0
  1051. scipy/sparse/linalg/isolve.py +22 -0
  1052. scipy/sparse/linalg/matfuncs.py +18 -0
  1053. scipy/sparse/linalg/tests/__init__.py +0 -0
  1054. scipy/sparse/linalg/tests/propack_test_data.npz +0 -0
  1055. scipy/sparse/linalg/tests/test_expm_multiply.py +367 -0
  1056. scipy/sparse/linalg/tests/test_interface.py +561 -0
  1057. scipy/sparse/linalg/tests/test_matfuncs.py +592 -0
  1058. scipy/sparse/linalg/tests/test_norm.py +154 -0
  1059. scipy/sparse/linalg/tests/test_onenormest.py +252 -0
  1060. scipy/sparse/linalg/tests/test_propack.py +165 -0
  1061. scipy/sparse/linalg/tests/test_pydata_sparse.py +272 -0
  1062. scipy/sparse/linalg/tests/test_special_sparse_arrays.py +337 -0
  1063. scipy/sparse/sparsetools.py +17 -0
  1064. scipy/sparse/spfuncs.py +17 -0
  1065. scipy/sparse/sputils.py +17 -0
  1066. scipy/sparse/tests/__init__.py +0 -0
  1067. scipy/sparse/tests/data/csc_py2.npz +0 -0
  1068. scipy/sparse/tests/data/csc_py3.npz +0 -0
  1069. scipy/sparse/tests/test_arithmetic1d.py +341 -0
  1070. scipy/sparse/tests/test_array_api.py +561 -0
  1071. scipy/sparse/tests/test_base.py +5860 -0
  1072. scipy/sparse/tests/test_common1d.py +447 -0
  1073. scipy/sparse/tests/test_construct.py +872 -0
  1074. scipy/sparse/tests/test_coo.py +1119 -0
  1075. scipy/sparse/tests/test_csc.py +98 -0
  1076. scipy/sparse/tests/test_csr.py +214 -0
  1077. scipy/sparse/tests/test_dok.py +209 -0
  1078. scipy/sparse/tests/test_extract.py +51 -0
  1079. scipy/sparse/tests/test_indexing1d.py +603 -0
  1080. scipy/sparse/tests/test_matrix_io.py +109 -0
  1081. scipy/sparse/tests/test_minmax1d.py +128 -0
  1082. scipy/sparse/tests/test_sparsetools.py +344 -0
  1083. scipy/sparse/tests/test_spfuncs.py +97 -0
  1084. scipy/sparse/tests/test_sputils.py +424 -0
  1085. scipy/spatial/__init__.py +129 -0
  1086. scipy/spatial/_ckdtree.cpython-311-darwin.so +0 -0
  1087. scipy/spatial/_distance_pybind.cpython-311-darwin.so +0 -0
  1088. scipy/spatial/_distance_wrap.cpython-311-darwin.so +0 -0
  1089. scipy/spatial/_geometric_slerp.py +238 -0
  1090. scipy/spatial/_hausdorff.cpython-311-darwin.so +0 -0
  1091. scipy/spatial/_kdtree.py +920 -0
  1092. scipy/spatial/_plotutils.py +274 -0
  1093. scipy/spatial/_procrustes.py +132 -0
  1094. scipy/spatial/_qhull.cpython-311-darwin.so +0 -0
  1095. scipy/spatial/_qhull.pyi +213 -0
  1096. scipy/spatial/_spherical_voronoi.py +341 -0
  1097. scipy/spatial/_voronoi.cpython-311-darwin.so +0 -0
  1098. scipy/spatial/_voronoi.pyi +4 -0
  1099. scipy/spatial/ckdtree.py +18 -0
  1100. scipy/spatial/distance.py +3147 -0
  1101. scipy/spatial/distance.pyi +210 -0
  1102. scipy/spatial/kdtree.py +25 -0
  1103. scipy/spatial/qhull.py +25 -0
  1104. scipy/spatial/tests/__init__.py +0 -0
  1105. scipy/spatial/tests/data/cdist-X1.txt +10 -0
  1106. scipy/spatial/tests/data/cdist-X2.txt +20 -0
  1107. scipy/spatial/tests/data/degenerate_pointset.npz +0 -0
  1108. scipy/spatial/tests/data/iris.txt +150 -0
  1109. scipy/spatial/tests/data/pdist-boolean-inp.txt +20 -0
  1110. scipy/spatial/tests/data/pdist-chebyshev-ml-iris.txt +1 -0
  1111. scipy/spatial/tests/data/pdist-chebyshev-ml.txt +1 -0
  1112. scipy/spatial/tests/data/pdist-cityblock-ml-iris.txt +1 -0
  1113. scipy/spatial/tests/data/pdist-cityblock-ml.txt +1 -0
  1114. scipy/spatial/tests/data/pdist-correlation-ml-iris.txt +1 -0
  1115. scipy/spatial/tests/data/pdist-correlation-ml.txt +1 -0
  1116. scipy/spatial/tests/data/pdist-cosine-ml-iris.txt +1 -0
  1117. scipy/spatial/tests/data/pdist-cosine-ml.txt +1 -0
  1118. scipy/spatial/tests/data/pdist-double-inp.txt +20 -0
  1119. scipy/spatial/tests/data/pdist-euclidean-ml-iris.txt +1 -0
  1120. scipy/spatial/tests/data/pdist-euclidean-ml.txt +1 -0
  1121. scipy/spatial/tests/data/pdist-hamming-ml.txt +1 -0
  1122. scipy/spatial/tests/data/pdist-jaccard-ml.txt +1 -0
  1123. scipy/spatial/tests/data/pdist-jensenshannon-ml-iris.txt +1 -0
  1124. scipy/spatial/tests/data/pdist-jensenshannon-ml.txt +1 -0
  1125. scipy/spatial/tests/data/pdist-minkowski-3.2-ml-iris.txt +1 -0
  1126. scipy/spatial/tests/data/pdist-minkowski-3.2-ml.txt +1 -0
  1127. scipy/spatial/tests/data/pdist-minkowski-5.8-ml-iris.txt +1 -0
  1128. scipy/spatial/tests/data/pdist-seuclidean-ml-iris.txt +1 -0
  1129. scipy/spatial/tests/data/pdist-seuclidean-ml.txt +1 -0
  1130. scipy/spatial/tests/data/pdist-spearman-ml.txt +1 -0
  1131. scipy/spatial/tests/data/random-bool-data.txt +100 -0
  1132. scipy/spatial/tests/data/random-double-data.txt +100 -0
  1133. scipy/spatial/tests/data/random-int-data.txt +100 -0
  1134. scipy/spatial/tests/data/random-uint-data.txt +100 -0
  1135. scipy/spatial/tests/data/selfdual-4d-polytope.txt +27 -0
  1136. scipy/spatial/tests/test__plotutils.py +91 -0
  1137. scipy/spatial/tests/test__procrustes.py +116 -0
  1138. scipy/spatial/tests/test_distance.py +2376 -0
  1139. scipy/spatial/tests/test_hausdorff.py +199 -0
  1140. scipy/spatial/tests/test_kdtree.py +1536 -0
  1141. scipy/spatial/tests/test_qhull.py +1313 -0
  1142. scipy/spatial/tests/test_slerp.py +417 -0
  1143. scipy/spatial/tests/test_spherical_voronoi.py +358 -0
  1144. scipy/spatial/transform/__init__.py +31 -0
  1145. scipy/spatial/transform/_rigid_transform.cpython-311-darwin.so +0 -0
  1146. scipy/spatial/transform/_rotation.cpython-311-darwin.so +0 -0
  1147. scipy/spatial/transform/_rotation_groups.py +140 -0
  1148. scipy/spatial/transform/_rotation_spline.py +460 -0
  1149. scipy/spatial/transform/rotation.py +21 -0
  1150. scipy/spatial/transform/tests/__init__.py +0 -0
  1151. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  1152. scipy/spatial/transform/tests/test_rotation.py +2569 -0
  1153. scipy/spatial/transform/tests/test_rotation_groups.py +169 -0
  1154. scipy/spatial/transform/tests/test_rotation_spline.py +183 -0
  1155. scipy/special/__init__.pxd +1 -0
  1156. scipy/special/__init__.py +841 -0
  1157. scipy/special/_add_newdocs.py +9961 -0
  1158. scipy/special/_basic.py +3576 -0
  1159. scipy/special/_comb.cpython-311-darwin.so +0 -0
  1160. scipy/special/_ellip_harm.py +214 -0
  1161. scipy/special/_ellip_harm_2.cpython-311-darwin.so +0 -0
  1162. scipy/special/_gufuncs.cpython-311-darwin.so +0 -0
  1163. scipy/special/_input_validation.py +17 -0
  1164. scipy/special/_lambertw.py +149 -0
  1165. scipy/special/_logsumexp.py +426 -0
  1166. scipy/special/_mptestutils.py +453 -0
  1167. scipy/special/_multiufuncs.py +610 -0
  1168. scipy/special/_orthogonal.py +2592 -0
  1169. scipy/special/_orthogonal.pyi +330 -0
  1170. scipy/special/_precompute/__init__.py +0 -0
  1171. scipy/special/_precompute/cosine_cdf.py +17 -0
  1172. scipy/special/_precompute/expn_asy.py +54 -0
  1173. scipy/special/_precompute/gammainc_asy.py +116 -0
  1174. scipy/special/_precompute/gammainc_data.py +124 -0
  1175. scipy/special/_precompute/hyp2f1_data.py +484 -0
  1176. scipy/special/_precompute/lambertw.py +68 -0
  1177. scipy/special/_precompute/loggamma.py +43 -0
  1178. scipy/special/_precompute/struve_convergence.py +131 -0
  1179. scipy/special/_precompute/utils.py +38 -0
  1180. scipy/special/_precompute/wright_bessel.py +342 -0
  1181. scipy/special/_precompute/wright_bessel_data.py +152 -0
  1182. scipy/special/_precompute/wrightomega.py +41 -0
  1183. scipy/special/_precompute/zetac.py +27 -0
  1184. scipy/special/_sf_error.py +15 -0
  1185. scipy/special/_specfun.cpython-311-darwin.so +0 -0
  1186. scipy/special/_special_ufuncs.cpython-311-darwin.so +0 -0
  1187. scipy/special/_spfun_stats.py +106 -0
  1188. scipy/special/_spherical_bessel.py +397 -0
  1189. scipy/special/_support_alternative_backends.py +295 -0
  1190. scipy/special/_test_internal.cpython-311-darwin.so +0 -0
  1191. scipy/special/_test_internal.pyi +9 -0
  1192. scipy/special/_testutils.py +321 -0
  1193. scipy/special/_ufuncs.cpython-311-darwin.so +0 -0
  1194. scipy/special/_ufuncs.pyi +522 -0
  1195. scipy/special/_ufuncs.pyx +13173 -0
  1196. scipy/special/_ufuncs_cxx.cpython-311-darwin.so +0 -0
  1197. scipy/special/_ufuncs_cxx.pxd +142 -0
  1198. scipy/special/_ufuncs_cxx.pyx +427 -0
  1199. scipy/special/_ufuncs_cxx_defs.h +147 -0
  1200. scipy/special/_ufuncs_defs.h +57 -0
  1201. scipy/special/add_newdocs.py +15 -0
  1202. scipy/special/basic.py +87 -0
  1203. scipy/special/cython_special.cpython-311-darwin.so +0 -0
  1204. scipy/special/cython_special.pxd +259 -0
  1205. scipy/special/cython_special.pyi +3 -0
  1206. scipy/special/orthogonal.py +45 -0
  1207. scipy/special/sf_error.py +20 -0
  1208. scipy/special/specfun.py +24 -0
  1209. scipy/special/spfun_stats.py +17 -0
  1210. scipy/special/tests/__init__.py +0 -0
  1211. scipy/special/tests/_cython_examples/extending.pyx +12 -0
  1212. scipy/special/tests/_cython_examples/meson.build +34 -0
  1213. scipy/special/tests/data/__init__.py +0 -0
  1214. scipy/special/tests/data/boost.npz +0 -0
  1215. scipy/special/tests/data/gsl.npz +0 -0
  1216. scipy/special/tests/data/local.npz +0 -0
  1217. scipy/special/tests/test_basic.py +4815 -0
  1218. scipy/special/tests/test_bdtr.py +112 -0
  1219. scipy/special/tests/test_boost_ufuncs.py +64 -0
  1220. scipy/special/tests/test_boxcox.py +125 -0
  1221. scipy/special/tests/test_cdflib.py +712 -0
  1222. scipy/special/tests/test_cdft_asymptotic.py +49 -0
  1223. scipy/special/tests/test_cephes_intp_cast.py +29 -0
  1224. scipy/special/tests/test_cosine_distr.py +83 -0
  1225. scipy/special/tests/test_cython_special.py +363 -0
  1226. scipy/special/tests/test_data.py +719 -0
  1227. scipy/special/tests/test_dd.py +42 -0
  1228. scipy/special/tests/test_digamma.py +45 -0
  1229. scipy/special/tests/test_ellip_harm.py +278 -0
  1230. scipy/special/tests/test_erfinv.py +89 -0
  1231. scipy/special/tests/test_exponential_integrals.py +118 -0
  1232. scipy/special/tests/test_extending.py +28 -0
  1233. scipy/special/tests/test_faddeeva.py +85 -0
  1234. scipy/special/tests/test_gamma.py +12 -0
  1235. scipy/special/tests/test_gammainc.py +152 -0
  1236. scipy/special/tests/test_hyp2f1.py +2566 -0
  1237. scipy/special/tests/test_hypergeometric.py +234 -0
  1238. scipy/special/tests/test_iv_ratio.py +249 -0
  1239. scipy/special/tests/test_kolmogorov.py +491 -0
  1240. scipy/special/tests/test_lambertw.py +109 -0
  1241. scipy/special/tests/test_legendre.py +1518 -0
  1242. scipy/special/tests/test_log1mexp.py +85 -0
  1243. scipy/special/tests/test_loggamma.py +70 -0
  1244. scipy/special/tests/test_logit.py +162 -0
  1245. scipy/special/tests/test_logsumexp.py +469 -0
  1246. scipy/special/tests/test_mpmath.py +2293 -0
  1247. scipy/special/tests/test_nan_inputs.py +65 -0
  1248. scipy/special/tests/test_ndtr.py +77 -0
  1249. scipy/special/tests/test_ndtri_exp.py +94 -0
  1250. scipy/special/tests/test_orthogonal.py +821 -0
  1251. scipy/special/tests/test_orthogonal_eval.py +275 -0
  1252. scipy/special/tests/test_owens_t.py +53 -0
  1253. scipy/special/tests/test_pcf.py +24 -0
  1254. scipy/special/tests/test_pdtr.py +48 -0
  1255. scipy/special/tests/test_powm1.py +65 -0
  1256. scipy/special/tests/test_precompute_expn_asy.py +24 -0
  1257. scipy/special/tests/test_precompute_gammainc.py +108 -0
  1258. scipy/special/tests/test_precompute_utils.py +36 -0
  1259. scipy/special/tests/test_round.py +18 -0
  1260. scipy/special/tests/test_sf_error.py +146 -0
  1261. scipy/special/tests/test_sici.py +36 -0
  1262. scipy/special/tests/test_specfun.py +48 -0
  1263. scipy/special/tests/test_spence.py +32 -0
  1264. scipy/special/tests/test_spfun_stats.py +61 -0
  1265. scipy/special/tests/test_sph_harm.py +85 -0
  1266. scipy/special/tests/test_spherical_bessel.py +400 -0
  1267. scipy/special/tests/test_support_alternative_backends.py +248 -0
  1268. scipy/special/tests/test_trig.py +72 -0
  1269. scipy/special/tests/test_ufunc_signatures.py +46 -0
  1270. scipy/special/tests/test_wright_bessel.py +205 -0
  1271. scipy/special/tests/test_wrightomega.py +117 -0
  1272. scipy/special/tests/test_zeta.py +301 -0
  1273. scipy/stats/__init__.py +670 -0
  1274. scipy/stats/_ansari_swilk_statistics.cpython-311-darwin.so +0 -0
  1275. scipy/stats/_axis_nan_policy.py +700 -0
  1276. scipy/stats/_biasedurn.cpython-311-darwin.so +0 -0
  1277. scipy/stats/_biasedurn.pxd +27 -0
  1278. scipy/stats/_binned_statistic.py +795 -0
  1279. scipy/stats/_binomtest.py +375 -0
  1280. scipy/stats/_bws_test.py +177 -0
  1281. scipy/stats/_censored_data.py +459 -0
  1282. scipy/stats/_common.py +5 -0
  1283. scipy/stats/_constants.py +42 -0
  1284. scipy/stats/_continued_fraction.py +387 -0
  1285. scipy/stats/_continuous_distns.py +12483 -0
  1286. scipy/stats/_correlation.py +210 -0
  1287. scipy/stats/_covariance.py +636 -0
  1288. scipy/stats/_crosstab.py +204 -0
  1289. scipy/stats/_discrete_distns.py +2098 -0
  1290. scipy/stats/_distn_infrastructure.py +4201 -0
  1291. scipy/stats/_distr_params.py +299 -0
  1292. scipy/stats/_distribution_infrastructure.py +5730 -0
  1293. scipy/stats/_entropy.py +428 -0
  1294. scipy/stats/_finite_differences.py +145 -0
  1295. scipy/stats/_fit.py +1351 -0
  1296. scipy/stats/_hypotests.py +2060 -0
  1297. scipy/stats/_kde.py +732 -0
  1298. scipy/stats/_ksstats.py +600 -0
  1299. scipy/stats/_levy_stable/__init__.py +1231 -0
  1300. scipy/stats/_levy_stable/levyst.cpython-311-darwin.so +0 -0
  1301. scipy/stats/_mannwhitneyu.py +492 -0
  1302. scipy/stats/_mgc.py +550 -0
  1303. scipy/stats/_morestats.py +4626 -0
  1304. scipy/stats/_mstats_basic.py +3658 -0
  1305. scipy/stats/_mstats_extras.py +521 -0
  1306. scipy/stats/_multicomp.py +449 -0
  1307. scipy/stats/_multivariate.py +7281 -0
  1308. scipy/stats/_new_distributions.py +452 -0
  1309. scipy/stats/_odds_ratio.py +466 -0
  1310. scipy/stats/_page_trend_test.py +486 -0
  1311. scipy/stats/_probability_distribution.py +1964 -0
  1312. scipy/stats/_qmc.py +2956 -0
  1313. scipy/stats/_qmc_cy.cpython-311-darwin.so +0 -0
  1314. scipy/stats/_qmc_cy.pyi +54 -0
  1315. scipy/stats/_qmvnt.py +454 -0
  1316. scipy/stats/_qmvnt_cy.cpython-311-darwin.so +0 -0
  1317. scipy/stats/_quantile.py +335 -0
  1318. scipy/stats/_rcont/__init__.py +4 -0
  1319. scipy/stats/_rcont/rcont.cpython-311-darwin.so +0 -0
  1320. scipy/stats/_relative_risk.py +263 -0
  1321. scipy/stats/_resampling.py +2352 -0
  1322. scipy/stats/_result_classes.py +40 -0
  1323. scipy/stats/_sampling.py +1314 -0
  1324. scipy/stats/_sensitivity_analysis.py +713 -0
  1325. scipy/stats/_sobol.cpython-311-darwin.so +0 -0
  1326. scipy/stats/_sobol.pyi +54 -0
  1327. scipy/stats/_sobol_direction_numbers.npz +0 -0
  1328. scipy/stats/_stats.cpython-311-darwin.so +0 -0
  1329. scipy/stats/_stats.pxd +10 -0
  1330. scipy/stats/_stats_mstats_common.py +320 -0
  1331. scipy/stats/_stats_py.py +11089 -0
  1332. scipy/stats/_stats_pythran.cpython-311-darwin.so +0 -0
  1333. scipy/stats/_survival.py +683 -0
  1334. scipy/stats/_tukeylambda_stats.py +199 -0
  1335. scipy/stats/_unuran/__init__.py +0 -0
  1336. scipy/stats/_unuran/unuran_wrapper.cpython-311-darwin.so +0 -0
  1337. scipy/stats/_unuran/unuran_wrapper.pyi +179 -0
  1338. scipy/stats/_variation.py +126 -0
  1339. scipy/stats/_warnings_errors.py +38 -0
  1340. scipy/stats/_wilcoxon.py +265 -0
  1341. scipy/stats/biasedurn.py +16 -0
  1342. scipy/stats/contingency.py +521 -0
  1343. scipy/stats/distributions.py +24 -0
  1344. scipy/stats/kde.py +18 -0
  1345. scipy/stats/morestats.py +27 -0
  1346. scipy/stats/mstats.py +140 -0
  1347. scipy/stats/mstats_basic.py +42 -0
  1348. scipy/stats/mstats_extras.py +25 -0
  1349. scipy/stats/mvn.py +17 -0
  1350. scipy/stats/qmc.py +236 -0
  1351. scipy/stats/sampling.py +73 -0
  1352. scipy/stats/stats.py +41 -0
  1353. scipy/stats/tests/__init__.py +0 -0
  1354. scipy/stats/tests/common_tests.py +356 -0
  1355. scipy/stats/tests/data/_mvt.py +171 -0
  1356. scipy/stats/tests/data/fisher_exact_results_from_r.py +607 -0
  1357. scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy +0 -0
  1358. scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy +0 -0
  1359. scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy +0 -0
  1360. scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy +0 -0
  1361. scipy/stats/tests/data/nist_anova/AtmWtAg.dat +108 -0
  1362. scipy/stats/tests/data/nist_anova/SiRstv.dat +85 -0
  1363. scipy/stats/tests/data/nist_anova/SmLs01.dat +249 -0
  1364. scipy/stats/tests/data/nist_anova/SmLs02.dat +1869 -0
  1365. scipy/stats/tests/data/nist_anova/SmLs03.dat +18069 -0
  1366. scipy/stats/tests/data/nist_anova/SmLs04.dat +249 -0
  1367. scipy/stats/tests/data/nist_anova/SmLs05.dat +1869 -0
  1368. scipy/stats/tests/data/nist_anova/SmLs06.dat +18069 -0
  1369. scipy/stats/tests/data/nist_anova/SmLs07.dat +249 -0
  1370. scipy/stats/tests/data/nist_anova/SmLs08.dat +1869 -0
  1371. scipy/stats/tests/data/nist_anova/SmLs09.dat +18069 -0
  1372. scipy/stats/tests/data/nist_linregress/Norris.dat +97 -0
  1373. scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy +0 -0
  1374. scipy/stats/tests/data/studentized_range_mpmath_ref.json +1499 -0
  1375. scipy/stats/tests/test_axis_nan_policy.py +1388 -0
  1376. scipy/stats/tests/test_binned_statistic.py +568 -0
  1377. scipy/stats/tests/test_censored_data.py +152 -0
  1378. scipy/stats/tests/test_contingency.py +294 -0
  1379. scipy/stats/tests/test_continued_fraction.py +173 -0
  1380. scipy/stats/tests/test_continuous.py +2198 -0
  1381. scipy/stats/tests/test_continuous_basic.py +1053 -0
  1382. scipy/stats/tests/test_continuous_fit_censored.py +683 -0
  1383. scipy/stats/tests/test_correlation.py +80 -0
  1384. scipy/stats/tests/test_crosstab.py +115 -0
  1385. scipy/stats/tests/test_discrete_basic.py +580 -0
  1386. scipy/stats/tests/test_discrete_distns.py +700 -0
  1387. scipy/stats/tests/test_distributions.py +10400 -0
  1388. scipy/stats/tests/test_entropy.py +322 -0
  1389. scipy/stats/tests/test_fast_gen_inversion.py +433 -0
  1390. scipy/stats/tests/test_fit.py +1090 -0
  1391. scipy/stats/tests/test_hypotests.py +1991 -0
  1392. scipy/stats/tests/test_kdeoth.py +676 -0
  1393. scipy/stats/tests/test_marray.py +289 -0
  1394. scipy/stats/tests/test_mgc.py +217 -0
  1395. scipy/stats/tests/test_morestats.py +3259 -0
  1396. scipy/stats/tests/test_mstats_basic.py +2071 -0
  1397. scipy/stats/tests/test_mstats_extras.py +172 -0
  1398. scipy/stats/tests/test_multicomp.py +405 -0
  1399. scipy/stats/tests/test_multivariate.py +4381 -0
  1400. scipy/stats/tests/test_odds_ratio.py +148 -0
  1401. scipy/stats/tests/test_qmc.py +1492 -0
  1402. scipy/stats/tests/test_quantile.py +199 -0
  1403. scipy/stats/tests/test_rank.py +345 -0
  1404. scipy/stats/tests/test_relative_risk.py +95 -0
  1405. scipy/stats/tests/test_resampling.py +2000 -0
  1406. scipy/stats/tests/test_sampling.py +1450 -0
  1407. scipy/stats/tests/test_sensitivity_analysis.py +310 -0
  1408. scipy/stats/tests/test_stats.py +9707 -0
  1409. scipy/stats/tests/test_survival.py +466 -0
  1410. scipy/stats/tests/test_tukeylambda_stats.py +85 -0
  1411. scipy/stats/tests/test_variation.py +216 -0
  1412. scipy/version.py +12 -0
  1413. scipy-1.16.0rc1.dist-info/LICENSE.txt +934 -0
  1414. scipy-1.16.0rc1.dist-info/METADATA +1082 -0
  1415. scipy-1.16.0rc1.dist-info/RECORD +1416 -0
  1416. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
@@ -0,0 +1,2462 @@
1
+ """Tools for spectral analysis.
2
+ """
3
+ import numpy as np
4
+ import numpy.typing as npt
5
+ from scipy import fft as sp_fft
6
+ from . import _signaltools
7
+ from ._short_time_fft import ShortTimeFFT, FFT_MODE_TYPE
8
+ from .windows import get_window
9
+ from ._arraytools import const_ext, even_ext, odd_ext, zero_ext
10
+ import warnings
11
+ from typing import cast, Literal
12
+
13
+
14
+ __all__ = ['periodogram', 'welch', 'lombscargle', 'csd', 'coherence',
15
+ 'spectrogram', 'stft', 'istft', 'check_COLA', 'check_NOLA']
16
+
17
+
18
+ def lombscargle(
19
+ x: npt.ArrayLike,
20
+ y: npt.ArrayLike,
21
+ freqs: npt.ArrayLike,
22
+ precenter: bool = False,
23
+ normalize: bool | Literal["power", "normalize", "amplitude"] = False,
24
+ *,
25
+ weights: npt.NDArray | None = None,
26
+ floating_mean: bool = False,
27
+ ) -> npt.NDArray:
28
+ """
29
+ Compute the generalized Lomb-Scargle periodogram.
30
+
31
+ The Lomb-Scargle periodogram was developed by Lomb [1]_ and further
32
+ extended by Scargle [2]_ to find, and test the significance of weak
33
+ periodic signals with uneven temporal sampling. The algorithm used
34
+ here is based on a weighted least-squares fit of the form
35
+ ``y(ω) = a*cos(ω*x) + b*sin(ω*x) + c``, where the fit is calculated for
36
+ each frequency independently. This algorithm was developed by Zechmeister
37
+ and Kürster which improves the Lomb-Scargle periodogram by enabling
38
+ the weighting of individual samples and calculating an unknown y offset
39
+ (also called a "floating-mean" model) [3]_. For more details, and practical
40
+ considerations, see the excellent reference on the Lomb-Scargle periodogram [4]_.
41
+
42
+ When *normalize* is False (or "power") (default) the computed periodogram
43
+ is unnormalized, it takes the value ``(A**2) * N/4`` for a harmonic
44
+ signal with amplitude A for sufficiently large N. Where N is the length of x or y.
45
+
46
+ When *normalize* is True (or "normalize") the computed periodogram is normalized
47
+ by the residuals of the data around a constant reference model (at zero).
48
+
49
+ When *normalize* is "amplitude" the computed periodogram is the complex
50
+ representation of the amplitude and phase.
51
+
52
+ Input arrays should be 1-D of a real floating data type, which are converted into
53
+ float64 arrays before processing.
54
+
55
+ Parameters
56
+ ----------
57
+ x : array_like
58
+ Sample times.
59
+ y : array_like
60
+ Measurement values. Values are assumed to have a baseline of ``y = 0``. If
61
+ there is a possibility of a y offset, it is recommended to set `floating_mean`
62
+ to True.
63
+ freqs : array_like
64
+ Angular frequencies (e.g., having unit rad/s=2π/s for `x` having unit s) for
65
+ output periodogram. Frequencies are normally >= 0, as any peak at ``-freq`` will
66
+ also exist at ``+freq``.
67
+ precenter : bool, optional
68
+ Pre-center measurement values by subtracting the mean, if True. This is
69
+ a legacy parameter and unnecessary if `floating_mean` is True.
70
+ normalize : bool | str, optional
71
+ Compute normalized or complex (amplitude + phase) periodogram.
72
+ Valid options are: ``False``/``"power"``, ``True``/``"normalize"``, or
73
+ ``"amplitude"``.
74
+ weights : array_like, optional
75
+ Weights for each sample. Weights must be nonnegative.
76
+ floating_mean : bool, optional
77
+ Determines a y offset for each frequency independently, if True.
78
+ Else the y offset is assumed to be `0`.
79
+
80
+ Returns
81
+ -------
82
+ pgram : array_like
83
+ Lomb-Scargle periodogram.
84
+
85
+ Raises
86
+ ------
87
+ ValueError
88
+ If any of the input arrays x, y, freqs, or weights are not 1D, or if any are
89
+ zero length. Or, if the input arrays x, y, and weights do not have the same
90
+ shape as each other.
91
+ ValueError
92
+ If any weight is < 0, or the sum of the weights is <= 0.
93
+ ValueError
94
+ If the normalize parameter is not one of the allowed options.
95
+
96
+ See Also
97
+ --------
98
+ periodogram: Power spectral density using a periodogram
99
+ welch: Power spectral density by Welch's method
100
+ csd: Cross spectral density by Welch's method
101
+
102
+ Notes
103
+ -----
104
+ The algorithm used will not automatically account for any unknown y offset, unless
105
+ floating_mean is True. Therefore, for most use cases, if there is a possibility of
106
+ a y offset, it is recommended to set floating_mean to True. If precenter is True,
107
+ it performs the operation ``y -= y.mean()``. However, precenter is a legacy
108
+ parameter, and unnecessary when floating_mean is True. Furthermore, the mean
109
+ removed by precenter does not account for sample weights, nor will it correct for
110
+ any bias due to consistently missing observations at peaks and/or troughs. When the
111
+ normalize parameter is "amplitude", for any frequency in freqs that is below
112
+ ``(2*pi)/(x.max() - x.min())``, the predicted amplitude will tend towards infinity.
113
+ The concept of a "Nyquist frequency" limit (see Nyquist-Shannon sampling theorem)
114
+ is not generally applicable to unevenly sampled data. Therefore, with unevenly
115
+ sampled data, valid frequencies in freqs can often be much higher than expected.
116
+
117
+ References
118
+ ----------
119
+ .. [1] N.R. Lomb "Least-squares frequency analysis of unequally spaced
120
+ data", Astrophysics and Space Science, vol 39, pp. 447-462, 1976
121
+ :doi:`10.1007/bf00648343`
122
+
123
+ .. [2] J.D. Scargle "Studies in astronomical time series analysis. II -
124
+ Statistical aspects of spectral analysis of unevenly spaced data",
125
+ The Astrophysical Journal, vol 263, pp. 835-853, 1982
126
+ :doi:`10.1086/160554`
127
+
128
+ .. [3] M. Zechmeister and M. Kürster, "The generalised Lomb-Scargle periodogram.
129
+ A new formalism for the floating-mean and Keplerian periodograms,"
130
+ Astronomy and Astrophysics, vol. 496, pp. 577-584, 2009
131
+ :doi:`10.1051/0004-6361:200811296`
132
+
133
+ .. [4] J.T. VanderPlas, "Understanding the Lomb-Scargle Periodogram,"
134
+ The Astrophysical Journal Supplement Series, vol. 236, no. 1, p. 16,
135
+ May 2018
136
+ :doi:`10.3847/1538-4365/aab766`
137
+
138
+
139
+ Examples
140
+ --------
141
+ >>> import numpy as np
142
+ >>> rng = np.random.default_rng()
143
+
144
+ First define some input parameters for the signal:
145
+
146
+ >>> A = 2. # amplitude
147
+ >>> c = 2. # offset
148
+ >>> w0 = 1. # rad/sec
149
+ >>> nin = 150
150
+ >>> nout = 1002
151
+
152
+ Randomly generate sample times:
153
+
154
+ >>> x = rng.uniform(0, 10*np.pi, nin)
155
+
156
+ Plot a sine wave for the selected times:
157
+
158
+ >>> y = A * np.cos(w0*x) + c
159
+
160
+ Define the array of frequencies for which to compute the periodogram:
161
+
162
+ >>> w = np.linspace(0.25, 10, nout)
163
+
164
+ Calculate Lomb-Scargle periodogram for each of the normalize options:
165
+
166
+ >>> from scipy.signal import lombscargle
167
+ >>> pgram_power = lombscargle(x, y, w, normalize=False)
168
+ >>> pgram_norm = lombscargle(x, y, w, normalize=True)
169
+ >>> pgram_amp = lombscargle(x, y, w, normalize='amplitude')
170
+ ...
171
+ >>> pgram_power_f = lombscargle(x, y, w, normalize=False, floating_mean=True)
172
+ >>> pgram_norm_f = lombscargle(x, y, w, normalize=True, floating_mean=True)
173
+ >>> pgram_amp_f = lombscargle(x, y, w, normalize='amplitude', floating_mean=True)
174
+
175
+ Now make a plot of the input data:
176
+
177
+ >>> import matplotlib.pyplot as plt
178
+ >>> fig, (ax_t, ax_p, ax_n, ax_a) = plt.subplots(4, 1, figsize=(5, 6))
179
+ >>> ax_t.plot(x, y, 'b+')
180
+ >>> ax_t.set_xlabel('Time [s]')
181
+ >>> ax_t.set_ylabel('Amplitude')
182
+
183
+ Then plot the periodogram for each of the normalize options, as well as with and
184
+ without floating_mean=True:
185
+
186
+ >>> ax_p.plot(w, pgram_power, label='default')
187
+ >>> ax_p.plot(w, pgram_power_f, label='floating_mean=True')
188
+ >>> ax_p.set_xlabel('Angular frequency [rad/s]')
189
+ >>> ax_p.set_ylabel('Power')
190
+ >>> ax_p.legend(prop={'size': 7})
191
+ ...
192
+ >>> ax_n.plot(w, pgram_norm, label='default')
193
+ >>> ax_n.plot(w, pgram_norm_f, label='floating_mean=True')
194
+ >>> ax_n.set_xlabel('Angular frequency [rad/s]')
195
+ >>> ax_n.set_ylabel('Normalized')
196
+ >>> ax_n.legend(prop={'size': 7})
197
+ ...
198
+ >>> ax_a.plot(w, np.abs(pgram_amp), label='default')
199
+ >>> ax_a.plot(w, np.abs(pgram_amp_f), label='floating_mean=True')
200
+ >>> ax_a.set_xlabel('Angular frequency [rad/s]')
201
+ >>> ax_a.set_ylabel('Amplitude')
202
+ >>> ax_a.legend(prop={'size': 7})
203
+ ...
204
+ >>> plt.tight_layout()
205
+ >>> plt.show()
206
+
207
+ """
208
+
209
+ # if no weights are provided, assume all data points are equally important
210
+ if weights is None:
211
+ weights = np.ones_like(y, dtype=np.float64)
212
+ else:
213
+ # if provided, make sure weights is an array and cast to float64
214
+ weights = np.asarray(weights, dtype=np.float64)
215
+
216
+ # make sure other inputs are arrays and cast to float64
217
+ # done before validation, in case they were not arrays
218
+ x = np.asarray(x, dtype=np.float64)
219
+ y = np.asarray(y, dtype=np.float64)
220
+ freqs = np.asarray(freqs, dtype=np.float64)
221
+
222
+ # validate input shapes
223
+ if not (x.ndim == 1 and x.size > 0 and x.shape == y.shape == weights.shape):
224
+ raise ValueError("Parameters x, y, weights must be 1-D arrays of "
225
+ "equal non-zero length!")
226
+ if not (freqs.ndim == 1 and freqs.size > 0):
227
+ raise ValueError("Parameter freqs must be a 1-D array of non-zero length!")
228
+
229
+ # validate weights
230
+ if not (np.all(weights >= 0) and np.sum(weights) > 0):
231
+ raise ValueError("Parameter weights must have only non-negative entries "
232
+ "which sum to a positive value!")
233
+
234
+ # validate normalize parameter
235
+ if isinstance(normalize, bool):
236
+ # if bool, convert to str literal
237
+ normalize = "normalize" if normalize else "power"
238
+
239
+ if normalize not in ["power", "normalize", "amplitude"]:
240
+ raise ValueError(
241
+ "Normalize must be: False (or 'power'), True (or 'normalize'), "
242
+ "or 'amplitude'."
243
+ )
244
+
245
+ # weight vector must sum to 1
246
+ weights *= 1.0 / weights.sum()
247
+
248
+ # if requested, perform precenter
249
+ if precenter:
250
+ y -= y.mean()
251
+
252
+ # transform arrays
253
+ # row vector
254
+ freqs = freqs.reshape(1, -1)
255
+ # column vectors
256
+ x = x.reshape(-1, 1)
257
+ y = y.reshape(-1, 1)
258
+ weights = weights.reshape(-1, 1)
259
+
260
+ # store frequent intermediates
261
+ weights_y = weights * y
262
+ freqst = freqs * x
263
+ coswt = np.cos(freqst)
264
+ sinwt = np.sin(freqst)
265
+
266
+ Y = np.dot(weights.T, y) # Eq. 7
267
+ CC = np.dot(weights.T, coswt * coswt) # Eq. 13
268
+ SS = 1.0 - CC # trig identity: S^2 = 1 - C^2 Eq.14
269
+ CS = np.dot(weights.T, coswt * sinwt) # Eq. 15
270
+
271
+ if floating_mean:
272
+ C = np.dot(weights.T, coswt) # Eq. 8
273
+ S = np.dot(weights.T, sinwt) # Eq. 9
274
+ CC -= C * C # Eq. 13
275
+ SS -= S * S # Eq. 14
276
+ CS -= C * S # Eq. 15
277
+
278
+ # calculate tau (phase offset to eliminate CS variable)
279
+ tau = 0.5 * np.arctan2(2.0 * CS, CC - SS) # Eq. 19
280
+ freqst_tau = freqst - tau
281
+
282
+ # coswt and sinwt are now offset by tau, which eliminates CS
283
+ coswt_tau = np.cos(freqst_tau)
284
+ sinwt_tau = np.sin(freqst_tau)
285
+
286
+ YC = np.dot(weights_y.T, coswt_tau) # Eq. 11
287
+ YS = np.dot(weights_y.T, sinwt_tau) # Eq. 12
288
+ CC = np.dot(weights.T, coswt_tau * coswt_tau) # Eq. 13, CC range is [0.5, 1.0]
289
+ SS = 1.0 - CC # trig identity: S^2 = 1 - C^2 Eq. 14, SS range is [0.0, 0.5]
290
+
291
+ if floating_mean:
292
+ C = np.dot(weights.T, coswt_tau) # Eq. 8
293
+ S = np.dot(weights.T, sinwt_tau) # Eq. 9
294
+ YC -= Y * C # Eq. 11
295
+ YS -= Y * S # Eq. 12
296
+ CC -= C * C # Eq. 13, CC range is now [0.0, 1.0]
297
+ SS -= S * S # Eq. 14, SS range is now [0.0, 0.5]
298
+
299
+ # to prevent division by zero errors with a and b, as well as correcting for
300
+ # numerical precision errors that lead to CC or SS being approximately -0.0,
301
+ # make sure CC and SS are both > 0
302
+ epsneg = np.finfo(dtype=y.dtype).epsneg
303
+ CC[CC < epsneg] = epsneg
304
+ SS[SS < epsneg] = epsneg
305
+
306
+ # calculate a and b
307
+ # where: y(w) = a*cos(w) + b*sin(w) + c
308
+ a = YC / CC # Eq. A.4 and 6, eliminating CS
309
+ b = YS / SS # Eq. A.4 and 6, eliminating CS
310
+ # c = Y - a * C - b * S
311
+
312
+ # store final value as power in A^2 (i.e., (y units)^2)
313
+ pgram = 2.0 * (a * YC + b * YS)
314
+
315
+ # squeeze back to a vector
316
+ pgram = np.squeeze(pgram)
317
+
318
+ if normalize == "power": # (default)
319
+ # return the legacy power units ((A**2) * N/4)
320
+
321
+ pgram *= float(x.shape[0]) / 4.0
322
+
323
+ elif normalize == "normalize":
324
+ # return the normalized power (power at current frequency wrt the entire signal)
325
+ # range will be [0, 1]
326
+
327
+ YY = np.dot(weights_y.T, y) # Eq. 10
328
+ if floating_mean:
329
+ YY -= Y * Y # Eq. 10
330
+
331
+ pgram *= 0.5 / np.squeeze(YY) # Eq. 20
332
+
333
+ else: # normalize == "amplitude":
334
+ # return the complex representation of the best-fit amplitude and phase
335
+
336
+ # squeeze back to vectors
337
+ a = np.squeeze(a)
338
+ b = np.squeeze(b)
339
+ tau = np.squeeze(tau)
340
+
341
+ # calculate the complex representation, and correct for tau rotation
342
+ pgram = (a + 1j * b) * np.exp(1j * tau)
343
+
344
+ return pgram
345
+
346
+
347
+ def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant',
348
+ return_onesided=True, scaling='density', axis=-1):
349
+ """
350
+ Estimate power spectral density using a periodogram.
351
+
352
+ Parameters
353
+ ----------
354
+ x : array_like
355
+ Time series of measurement values
356
+ fs : float, optional
357
+ Sampling frequency of the `x` time series. Defaults to 1.0.
358
+ window : str or tuple or array_like, optional
359
+ Desired window to use. If `window` is a string or tuple, it is
360
+ passed to `get_window` to generate the window values, which are
361
+ DFT-even by default. See `get_window` for a list of windows and
362
+ required parameters. If `window` is array_like it will be used
363
+ directly as the window and its length must be equal to the length
364
+ of the axis over which the periodogram is computed. Defaults
365
+ to 'boxcar'.
366
+ nfft : int, optional
367
+ Length of the FFT used. If `None` the length of `x` will be
368
+ used.
369
+ detrend : str or function or `False`, optional
370
+ Specifies how to detrend each segment. If `detrend` is a
371
+ string, it is passed as the `type` argument to the `detrend`
372
+ function. If it is a function, it takes a segment and returns a
373
+ detrended segment. If `detrend` is `False`, no detrending is
374
+ done. Defaults to 'constant'.
375
+ return_onesided : bool, optional
376
+ If `True`, return a one-sided spectrum for real data. If
377
+ `False` return a two-sided spectrum. Defaults to `True`, but for
378
+ complex data, a two-sided spectrum is always returned.
379
+ scaling : { 'density', 'spectrum' }, optional
380
+ Selects between computing the power spectral density ('density')
381
+ where `Pxx` has units of V²/Hz and computing the squared magnitude
382
+ spectrum ('spectrum') where `Pxx` has units of V², if `x`
383
+ is measured in V and `fs` is measured in Hz. Defaults to
384
+ 'density'
385
+ axis : int, optional
386
+ Axis along which the periodogram is computed; the default is
387
+ over the last axis (i.e. ``axis=-1``).
388
+
389
+ Returns
390
+ -------
391
+ f : ndarray
392
+ Array of sample frequencies.
393
+ Pxx : ndarray
394
+ Power spectral density or power spectrum of `x`.
395
+
396
+ See Also
397
+ --------
398
+ welch: Estimate power spectral density using Welch's method
399
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
400
+
401
+ Notes
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
+
409
+ Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
410
+ for a discussion of the scalings of the power spectral density and
411
+ the magnitude (squared) spectrum.
412
+
413
+ .. versionadded:: 0.12.0
414
+
415
+ Examples
416
+ --------
417
+ >>> import numpy as np
418
+ >>> from scipy import signal
419
+ >>> import matplotlib.pyplot as plt
420
+ >>> rng = np.random.default_rng()
421
+
422
+ Generate a test signal, a 2 Vrms sine wave at 1234 Hz, corrupted by
423
+ 0.001 V**2/Hz of white noise sampled at 10 kHz.
424
+
425
+ >>> fs = 10e3
426
+ >>> N = 1e5
427
+ >>> amp = 2*np.sqrt(2)
428
+ >>> freq = 1234.0
429
+ >>> noise_power = 0.001 * fs / 2
430
+ >>> time = np.arange(N) / fs
431
+ >>> x = amp*np.sin(2*np.pi*freq*time)
432
+ >>> x += rng.normal(scale=np.sqrt(noise_power), size=time.shape)
433
+
434
+ Compute and plot the power spectral density.
435
+
436
+ >>> f, Pxx_den = signal.periodogram(x, fs)
437
+ >>> plt.semilogy(f, Pxx_den)
438
+ >>> plt.ylim([1e-7, 1e2])
439
+ >>> plt.xlabel('frequency [Hz]')
440
+ >>> plt.ylabel('PSD [V**2/Hz]')
441
+ >>> plt.show()
442
+
443
+ If we average the last half of the spectral density, to exclude the
444
+ peak, we can recover the noise power on the signal.
445
+
446
+ >>> np.mean(Pxx_den[25000:])
447
+ 0.000985320699252543
448
+
449
+ Now compute and plot the power spectrum.
450
+
451
+ >>> f, Pxx_spec = signal.periodogram(x, fs, 'flattop', scaling='spectrum')
452
+ >>> plt.figure()
453
+ >>> plt.semilogy(f, np.sqrt(Pxx_spec))
454
+ >>> plt.ylim([1e-4, 1e1])
455
+ >>> plt.xlabel('frequency [Hz]')
456
+ >>> plt.ylabel('Linear spectrum [V RMS]')
457
+ >>> plt.show()
458
+
459
+ The peak height in the power spectrum is an estimate of the RMS
460
+ amplitude.
461
+
462
+ >>> np.sqrt(Pxx_spec.max())
463
+ 2.0077340678640727
464
+
465
+ """
466
+ x = np.asarray(x)
467
+
468
+ if x.size == 0:
469
+ return np.empty(x.shape), np.empty(x.shape)
470
+
471
+ if window is None:
472
+ window = 'boxcar'
473
+
474
+ if nfft is None:
475
+ nperseg = x.shape[axis]
476
+ elif nfft == x.shape[axis]:
477
+ nperseg = nfft
478
+ elif nfft > x.shape[axis]:
479
+ nperseg = x.shape[axis]
480
+ elif nfft < x.shape[axis]:
481
+ s = [np.s_[:]]*len(x.shape)
482
+ s[axis] = np.s_[:nfft]
483
+ x = x[tuple(s)]
484
+ nperseg = nfft
485
+ nfft = None
486
+
487
+ if hasattr(window, 'size'):
488
+ if window.size != nperseg:
489
+ raise ValueError('the size of the window must be the same size '
490
+ 'of the input on the specified axis')
491
+
492
+ return welch(x, fs=fs, window=window, nperseg=nperseg, noverlap=0,
493
+ nfft=nfft, detrend=detrend, return_onesided=return_onesided,
494
+ scaling=scaling, axis=axis)
495
+
496
+
497
+ def welch(x, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
498
+ detrend='constant', return_onesided=True, scaling='density',
499
+ axis=-1, average='mean'):
500
+ r"""
501
+ Estimate power spectral density using Welch's method.
502
+
503
+ Welch's method [1]_ computes an estimate of the power spectral
504
+ density by dividing the data into overlapping segments, computing a
505
+ modified periodogram for each segment and averaging the
506
+ periodograms.
507
+
508
+ Parameters
509
+ ----------
510
+ x : array_like
511
+ Time series of measurement values
512
+ fs : float, optional
513
+ Sampling frequency of the `x` time series. Defaults to 1.0.
514
+ window : str or tuple or array_like, optional
515
+ Desired window to use. If `window` is a string or tuple, it is
516
+ passed to `get_window` to generate the window values, which are
517
+ DFT-even by default. See `get_window` for a list of windows and
518
+ required parameters. If `window` is array_like it will be used
519
+ directly as the window and its length must be nperseg. Defaults
520
+ to a Hann window.
521
+ nperseg : int, optional
522
+ Length of each segment. Defaults to None, but if window is str or
523
+ tuple, is set to 256, and if window is array_like, is set to the
524
+ length of the window.
525
+ noverlap : int, optional
526
+ Number of points to overlap between segments. If `None`,
527
+ ``noverlap = nperseg // 2``. Defaults to `None`.
528
+ nfft : int, optional
529
+ Length of the FFT used, if a zero padded FFT is desired. If
530
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
531
+ detrend : str or function or `False`, optional
532
+ Specifies how to detrend each segment. If `detrend` is a
533
+ string, it is passed as the `type` argument to the `detrend`
534
+ function. If it is a function, it takes a segment and returns a
535
+ detrended segment. If `detrend` is `False`, no detrending is
536
+ done. Defaults to 'constant'.
537
+ return_onesided : bool, optional
538
+ If `True`, return a one-sided spectrum for real data. If
539
+ `False` return a two-sided spectrum. Defaults to `True`, but for
540
+ complex data, a two-sided spectrum is always returned.
541
+ scaling : { 'density', 'spectrum' }, optional
542
+ Selects between computing the power spectral density ('density')
543
+ where `Pxx` has units of V**2/Hz and computing the squared magnitude
544
+ spectrum ('spectrum') where `Pxx` has units of V**2, if `x`
545
+ is measured in V and `fs` is measured in Hz. Defaults to
546
+ 'density'
547
+ axis : int, optional
548
+ Axis along which the periodogram is computed; the default is
549
+ over the last axis (i.e. ``axis=-1``).
550
+ average : { 'mean', 'median' }, optional
551
+ Method to use when averaging periodograms. Defaults to 'mean'.
552
+
553
+ .. versionadded:: 1.2.0
554
+
555
+ Returns
556
+ -------
557
+ f : ndarray
558
+ Array of sample frequencies.
559
+ Pxx : ndarray
560
+ Power spectral density or power spectrum of x.
561
+
562
+ See Also
563
+ --------
564
+ csd: Cross power spectral density using Welch's method
565
+ periodogram: Simple, optionally modified periodogram
566
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
567
+
568
+ Notes
569
+ -----
570
+ An appropriate amount of overlap will depend on the choice of window
571
+ and on your requirements. For the default Hann window an overlap of
572
+ 50% is a reasonable trade-off between accurately estimating the
573
+ signal power, while not over counting any of the data. Narrower
574
+ windows may require a larger overlap. If `noverlap` is 0, this
575
+ method is equivalent to Bartlett's method [2]_.
576
+
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.
582
+
583
+ Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
584
+ for a discussion of the scalings of the power spectral density and
585
+ the (squared) magnitude spectrum.
586
+
587
+ .. versionadded:: 0.12.0
588
+
589
+ References
590
+ ----------
591
+ .. [1] P. Welch, "The use of the fast Fourier transform for the
592
+ estimation of power spectra: A method based on time averaging
593
+ over short, modified periodograms", IEEE Trans. Audio
594
+ Electroacoust. vol. 15, pp. 70-73, 1967.
595
+ .. [2] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
596
+ Biometrika, vol. 37, pp. 1-16, 1950.
597
+
598
+ Examples
599
+ --------
600
+ >>> import numpy as np
601
+ >>> from scipy import signal
602
+ >>> import matplotlib.pyplot as plt
603
+ >>> rng = np.random.default_rng()
604
+
605
+ Generate a test signal, a 2 Vrms sine wave at 1234 Hz, corrupted by
606
+ 0.001 V**2/Hz of white noise sampled at 10 kHz.
607
+
608
+ >>> fs = 10e3
609
+ >>> N = 1e5
610
+ >>> amp = 2*np.sqrt(2)
611
+ >>> freq = 1234.0
612
+ >>> noise_power = 0.001 * fs / 2
613
+ >>> time = np.arange(N) / fs
614
+ >>> x = amp*np.sin(2*np.pi*freq*time)
615
+ >>> x += rng.normal(scale=np.sqrt(noise_power), size=time.shape)
616
+
617
+ Compute and plot the power spectral density.
618
+
619
+ >>> f, Pxx_den = signal.welch(x, fs, nperseg=1024)
620
+ >>> plt.semilogy(f, Pxx_den)
621
+ >>> plt.ylim([0.5e-3, 1])
622
+ >>> plt.xlabel('frequency [Hz]')
623
+ >>> plt.ylabel('PSD [V**2/Hz]')
624
+ >>> plt.show()
625
+
626
+ If we average the last half of the spectral density, to exclude the
627
+ peak, we can recover the noise power on the signal.
628
+
629
+ >>> np.mean(Pxx_den[256:])
630
+ 0.0009924865443739191
631
+
632
+ Now compute and plot the power spectrum.
633
+
634
+ >>> f, Pxx_spec = signal.welch(x, fs, 'flattop', 1024, scaling='spectrum')
635
+ >>> plt.figure()
636
+ >>> plt.semilogy(f, np.sqrt(Pxx_spec))
637
+ >>> plt.xlabel('frequency [Hz]')
638
+ >>> plt.ylabel('Linear spectrum [V RMS]')
639
+ >>> plt.show()
640
+
641
+ The peak height in the power spectrum is an estimate of the RMS
642
+ amplitude.
643
+
644
+ >>> np.sqrt(Pxx_spec.max())
645
+ 2.0077340678640727
646
+
647
+ If we now introduce a discontinuity in the signal, by increasing the
648
+ amplitude of a small portion of the signal by 50, we can see the
649
+ corruption of the mean average power spectral density, but using a
650
+ median average better estimates the normal behaviour.
651
+
652
+ >>> x[int(N//2):int(N//2)+10] *= 50.
653
+ >>> f, Pxx_den = signal.welch(x, fs, nperseg=1024)
654
+ >>> f_med, Pxx_den_med = signal.welch(x, fs, nperseg=1024, average='median')
655
+ >>> plt.semilogy(f, Pxx_den, label='mean')
656
+ >>> plt.semilogy(f_med, Pxx_den_med, label='median')
657
+ >>> plt.ylim([0.5e-3, 1])
658
+ >>> plt.xlabel('frequency [Hz]')
659
+ >>> plt.ylabel('PSD [V**2/Hz]')
660
+ >>> plt.legend()
661
+ >>> plt.show()
662
+
663
+ """
664
+ freqs, Pxx = csd(x, x, fs=fs, window=window, nperseg=nperseg,
665
+ noverlap=noverlap, nfft=nfft, detrend=detrend,
666
+ return_onesided=return_onesided, scaling=scaling,
667
+ axis=axis, average=average)
668
+
669
+ return freqs, Pxx.real
670
+
671
+
672
+ def csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
673
+ detrend='constant', return_onesided=True, scaling='density',
674
+ axis=-1, average='mean'):
675
+ r"""
676
+ Estimate the cross power spectral density, Pxy, using Welch's method.
677
+
678
+ Parameters
679
+ ----------
680
+ x : array_like
681
+ Time series of measurement values
682
+ y : array_like
683
+ Time series of measurement values
684
+ fs : float, optional
685
+ Sampling frequency of the `x` and `y` time series. Defaults
686
+ to 1.0.
687
+ window : str or tuple or array_like, optional
688
+ Desired window to use. If `window` is a string or tuple, it is
689
+ passed to `get_window` to generate the window values, which are
690
+ DFT-even by default. See `get_window` for a list of windows and
691
+ required parameters. If `window` is array_like it will be used
692
+ directly as the window and its length must be nperseg. Defaults
693
+ to a Hann window.
694
+ nperseg : int, optional
695
+ Length of each segment. Defaults to None, but if window is str or
696
+ tuple, is set to 256, and if window is array_like, is set to the
697
+ length of the window.
698
+ noverlap: int, optional
699
+ Number of points to overlap between segments. If `None`,
700
+ ``noverlap = nperseg // 2``. Defaults to `None` and may
701
+ not be greater than `nperseg`.
702
+ nfft : int, optional
703
+ Length of the FFT used, if a zero padded FFT is desired. If
704
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
705
+ detrend : str or function or `False`, optional
706
+ Specifies how to detrend each segment. If `detrend` is a
707
+ string, it is passed as the `type` argument to the `detrend`
708
+ function. If it is a function, it takes a segment and returns a
709
+ detrended segment. If `detrend` is `False`, no detrending is
710
+ done. Defaults to 'constant'.
711
+ return_onesided : bool, optional
712
+ If `True`, return a one-sided spectrum for real data. If
713
+ `False` return a two-sided spectrum. Defaults to `True`, but for
714
+ complex data, a two-sided spectrum is always returned.
715
+ scaling : { 'density', 'spectrum' }, optional
716
+ Selects between computing the cross spectral density ('density')
717
+ where `Pxy` has units of V**2/Hz and computing the cross spectrum
718
+ ('spectrum') where `Pxy` has units of V**2, if `x` and `y` are
719
+ measured in V and `fs` is measured in Hz. Defaults to 'density'
720
+ axis : int, optional
721
+ Axis along which the CSD is computed for both inputs; the
722
+ default is over the last axis (i.e. ``axis=-1``).
723
+ average : { 'mean', 'median' }, optional
724
+ Method to use when averaging periodograms. If the spectrum is
725
+ complex, the average is computed separately for the real and
726
+ imaginary parts. Defaults to 'mean'.
727
+
728
+ .. versionadded:: 1.2.0
729
+
730
+ Returns
731
+ -------
732
+ f : ndarray
733
+ Array of sample frequencies.
734
+ Pxy : ndarray
735
+ Cross spectral density or cross power spectrum of x,y.
736
+
737
+ See Also
738
+ --------
739
+ periodogram: Simple, optionally modified periodogram
740
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
741
+ welch: Power spectral density by Welch's method. [Equivalent to
742
+ csd(x,x)]
743
+ coherence: Magnitude squared coherence by Welch's method.
744
+
745
+ Notes
746
+ -----
747
+ By convention, Pxy is computed with the conjugate FFT of X
748
+ multiplied by the FFT of Y.
749
+
750
+ If the input series differ in length, the shorter series will be
751
+ zero-padded to match.
752
+
753
+ An appropriate amount of overlap will depend on the choice of window
754
+ and on your requirements. For the default Hann window an overlap of
755
+ 50% is a reasonable trade-off between accurately estimating the
756
+ signal power, while not over counting any of the data. Narrower
757
+ windows may require a larger overlap.
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
+
765
+ Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
766
+ for a discussion of the scalings of a spectral density and an (amplitude) spectrum.
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
+
788
+ .. versionadded:: 0.16.0
789
+
790
+ References
791
+ ----------
792
+ .. [1] P. Welch, "The use of the fast Fourier transform for the
793
+ estimation of power spectra: A method based on time averaging
794
+ over short, modified periodograms", IEEE Trans. Audio
795
+ Electroacoust. vol. 15, pp. 70-73, 1967.
796
+ .. [2] Rabiner, Lawrence R., and B. Gold. "Theory and Application of
797
+ Digital Signal Processing" Prentice-Hall, pp. 414-419, 1975
798
+
799
+ Examples
800
+ --------
801
+ The following example plots the cross power spectral density of two signals with
802
+ some common features:
803
+
804
+ >>> import numpy as np
805
+ >>> from scipy import signal
806
+ >>> import matplotlib.pyplot as plt
807
+ >>> rng = np.random.default_rng()
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
812
+ >>> noise_power = 0.001 * fs / 2
813
+ >>> time = np.arange(N) / fs
814
+ >>> b, a = signal.butter(2, 0.25, 'low')
815
+ >>> x = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
816
+ >>> y = signal.lfilter(b, a, x)
817
+ >>> x += amp*np.sin(2*np.pi*freq*time)
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()
829
+
830
+ The cross spectral density is calculated by taking the average over the time slices
831
+ of a spectrogram:
832
+
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
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.
848
+ """
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)
922
+
923
+ # Average over windows.
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)
931
+ else:
932
+ Pxy = np.median(Pxy, axis=-1)
933
+ Pxy /= bias
934
+ elif average == 'mean':
935
+ Pxy = Pxy.mean(axis=-1)
936
+ else:
937
+ raise ValueError(f"Parameter {average=} must be 'median' or 'mean'!")
938
+ else:
939
+ Pxy = np.reshape(Pxy, Pxy.shape[:-1])
940
+
941
+ # cast output type;
942
+ Pxy = Pxy.astype(out_dtype)
943
+ if same_data:
944
+ Pxy = Pxy.real
945
+ return SFT.f, Pxy
946
+
947
+
948
+ def spectrogram(x, fs=1.0, window=('tukey', .25), nperseg=None, noverlap=None,
949
+ nfft=None, detrend='constant', return_onesided=True,
950
+ scaling='density', axis=-1, mode='psd'):
951
+ """Compute a spectrogram with consecutive Fourier transforms (legacy function).
952
+
953
+ Spectrograms can be used as a way of visualizing the change of a
954
+ nonstationary signal's frequency content over time.
955
+
956
+ .. legacy:: function
957
+
958
+ :class:`ShortTimeFFT` is a newer STFT / ISTFT implementation with more
959
+ features also including a :meth:`~ShortTimeFFT.spectrogram` method.
960
+ A :ref:`comparison <tutorial_stft_legacy_stft>` between the
961
+ implementations can be found in the :ref:`tutorial_stft` section of
962
+ the :ref:`user_guide`.
963
+
964
+ Parameters
965
+ ----------
966
+ x : array_like
967
+ Time series of measurement values
968
+ fs : float, optional
969
+ Sampling frequency of the `x` time series. Defaults to 1.0.
970
+ window : str or tuple or array_like, optional
971
+ Desired window to use. If `window` is a string or tuple, it is
972
+ passed to `get_window` to generate the window values, which are
973
+ DFT-even by default. See `get_window` for a list of windows and
974
+ required parameters. If `window` is array_like it will be used
975
+ directly as the window and its length must be nperseg.
976
+ Defaults to a Tukey window with shape parameter of 0.25.
977
+ nperseg : int, optional
978
+ Length of each segment. Defaults to None, but if window is str or
979
+ tuple, is set to 256, and if window is array_like, is set to the
980
+ length of the window.
981
+ noverlap : int, optional
982
+ Number of points to overlap between segments. If `None`,
983
+ ``noverlap = nperseg // 8``. Defaults to `None`.
984
+ nfft : int, optional
985
+ Length of the FFT used, if a zero padded FFT is desired. If
986
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
987
+ detrend : str or function or `False`, optional
988
+ Specifies how to detrend each segment. If `detrend` is a
989
+ string, it is passed as the `type` argument to the `detrend`
990
+ function. If it is a function, it takes a segment and returns a
991
+ detrended segment. If `detrend` is `False`, no detrending is
992
+ done. Defaults to 'constant'.
993
+ return_onesided : bool, optional
994
+ If `True`, return a one-sided spectrum for real data. If
995
+ `False` return a two-sided spectrum. Defaults to `True`, but for
996
+ complex data, a two-sided spectrum is always returned.
997
+ scaling : { 'density', 'spectrum' }, optional
998
+ Selects between computing the power spectral density ('density')
999
+ where `Sxx` has units of V**2/Hz and computing the power
1000
+ spectrum ('spectrum') where `Sxx` has units of V**2, if `x`
1001
+ is measured in V and `fs` is measured in Hz. Defaults to
1002
+ 'density'.
1003
+ axis : int, optional
1004
+ Axis along which the spectrogram is computed; the default is over
1005
+ the last axis (i.e. ``axis=-1``).
1006
+ mode : str, optional
1007
+ Defines what kind of return values are expected. Options are
1008
+ ['psd', 'complex', 'magnitude', 'angle', 'phase']. 'complex' is
1009
+ equivalent to the output of `stft` with no padding or boundary
1010
+ extension. 'magnitude' returns the absolute magnitude of the
1011
+ STFT. 'angle' and 'phase' return the complex angle of the STFT,
1012
+ with and without unwrapping, respectively.
1013
+
1014
+ Returns
1015
+ -------
1016
+ f : ndarray
1017
+ Array of sample frequencies.
1018
+ t : ndarray
1019
+ Array of segment times.
1020
+ Sxx : ndarray
1021
+ Spectrogram of x. By default, the last axis of Sxx corresponds
1022
+ to the segment times.
1023
+
1024
+ See Also
1025
+ --------
1026
+ periodogram: Simple, optionally modified periodogram
1027
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
1028
+ welch: Power spectral density by Welch's method.
1029
+ csd: Cross spectral density by Welch's method.
1030
+ ShortTimeFFT: Newer STFT/ISTFT implementation providing more features,
1031
+ which also includes a :meth:`~ShortTimeFFT.spectrogram`
1032
+ method.
1033
+
1034
+ Notes
1035
+ -----
1036
+ An appropriate amount of overlap will depend on the choice of window
1037
+ and on your requirements. In contrast to welch's method, where the
1038
+ entire data stream is averaged over, one may wish to use a smaller
1039
+ overlap (or perhaps none at all) when computing a spectrogram, to
1040
+ maintain some statistical independence between individual segments.
1041
+ It is for this reason that the default window is a Tukey window with
1042
+ 1/8th of a window's length overlap at each end.
1043
+
1044
+
1045
+ .. versionadded:: 0.16.0
1046
+
1047
+ References
1048
+ ----------
1049
+ .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
1050
+ "Discrete-Time Signal Processing", Prentice Hall, 1999.
1051
+
1052
+ Examples
1053
+ --------
1054
+ >>> import numpy as np
1055
+ >>> from scipy import signal
1056
+ >>> from scipy.fft import fftshift
1057
+ >>> import matplotlib.pyplot as plt
1058
+ >>> rng = np.random.default_rng()
1059
+
1060
+ Generate a test signal, a 2 Vrms sine wave whose frequency is slowly
1061
+ modulated around 3kHz, corrupted by white noise of exponentially
1062
+ decreasing magnitude sampled at 10 kHz.
1063
+
1064
+ >>> fs = 10e3
1065
+ >>> N = 1e5
1066
+ >>> amp = 2 * np.sqrt(2)
1067
+ >>> noise_power = 0.01 * fs / 2
1068
+ >>> time = np.arange(N) / float(fs)
1069
+ >>> mod = 500*np.cos(2*np.pi*0.25*time)
1070
+ >>> carrier = amp * np.sin(2*np.pi*3e3*time + mod)
1071
+ >>> noise = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
1072
+ >>> noise *= np.exp(-time/5)
1073
+ >>> x = carrier + noise
1074
+
1075
+ Compute and plot the spectrogram.
1076
+
1077
+ >>> f, t, Sxx = signal.spectrogram(x, fs)
1078
+ >>> plt.pcolormesh(t, f, Sxx, shading='gouraud')
1079
+ >>> plt.ylabel('Frequency [Hz]')
1080
+ >>> plt.xlabel('Time [sec]')
1081
+ >>> plt.show()
1082
+
1083
+ Note, if using output that is not one sided, then use the following:
1084
+
1085
+ >>> f, t, Sxx = signal.spectrogram(x, fs, return_onesided=False)
1086
+ >>> plt.pcolormesh(t, fftshift(f), fftshift(Sxx, axes=0), shading='gouraud')
1087
+ >>> plt.ylabel('Frequency [Hz]')
1088
+ >>> plt.xlabel('Time [sec]')
1089
+ >>> plt.show()
1090
+
1091
+ """
1092
+ modelist = ['psd', 'complex', 'magnitude', 'angle', 'phase']
1093
+ if mode not in modelist:
1094
+ raise ValueError(f'unknown value for mode {mode}, must be one of {modelist}')
1095
+
1096
+ # need to set default for nperseg before setting default for noverlap below
1097
+ window, nperseg = _triage_segments(window, nperseg,
1098
+ input_length=x.shape[axis])
1099
+
1100
+ # Less overlap than welch, so samples are more statistically independent
1101
+ if noverlap is None:
1102
+ noverlap = nperseg // 8
1103
+
1104
+ if mode == 'psd':
1105
+ freqs, time, Sxx = _spectral_helper(x, x, fs, window, nperseg,
1106
+ noverlap, nfft, detrend,
1107
+ return_onesided, scaling, axis,
1108
+ mode='psd')
1109
+
1110
+ else:
1111
+ freqs, time, Sxx = _spectral_helper(x, x, fs, window, nperseg,
1112
+ noverlap, nfft, detrend,
1113
+ return_onesided, scaling, axis,
1114
+ mode='stft')
1115
+
1116
+ if mode == 'magnitude':
1117
+ Sxx = np.abs(Sxx)
1118
+ elif mode in ['angle', 'phase']:
1119
+ Sxx = np.angle(Sxx)
1120
+ if mode == 'phase':
1121
+ # Sxx has one additional dimension for time strides
1122
+ if axis < 0:
1123
+ axis -= 1
1124
+ Sxx = np.unwrap(Sxx, axis=axis)
1125
+
1126
+ # mode =='complex' is same as `stft`, doesn't need modification
1127
+
1128
+ return freqs, time, Sxx
1129
+
1130
+
1131
+ def check_COLA(window, nperseg, noverlap, tol=1e-10):
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
+
1152
+
1153
+ Parameters
1154
+ ----------
1155
+ window : str or tuple or array_like
1156
+ Desired window to use. If `window` is a string or tuple, it is
1157
+ passed to `get_window` to generate the window values, which are
1158
+ DFT-even by default. See `get_window` for a list of windows and
1159
+ required parameters. If `window` is array_like it will be used
1160
+ directly as the window and its length must be nperseg.
1161
+ nperseg : int
1162
+ Length of each segment.
1163
+ noverlap : int
1164
+ Number of points to overlap between segments.
1165
+ tol : float, optional
1166
+ The allowed variance of a bin's weighted sum from the median bin
1167
+ sum.
1168
+
1169
+ Returns
1170
+ -------
1171
+ verdict : bool
1172
+ `True` if chosen combination satisfies COLA within `tol`,
1173
+ `False` otherwise
1174
+
1175
+ See Also
1176
+ --------
1177
+ closest_STFT_dual_window: Allows determining the closest window meeting the
1178
+ COLA constraint for a given window
1179
+ check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
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)
1183
+
1184
+ Notes
1185
+ -----
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
1188
+ "Constant OverLap Add" (COLA). This ensures that every point in the input
1189
+ data is equally weighted, thereby avoiding aliasing and allowing full
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.
1193
+
1194
+ Some examples of windows that satisfy COLA:
1195
+ - Rectangular window at overlap of 0, 1/2, 2/3, 3/4, ...
1196
+ - Bartlett window at overlap of 1/2, 3/4, 5/6, ...
1197
+ - Hann window at 1/2, 2/3, 3/4, ...
1198
+ - Any Blackman family window at 2/3 overlap
1199
+ - Any window with ``noverlap = nperseg-1``
1200
+
1201
+ A very comprehensive list of other windows may be found in [2]_,
1202
+ wherein the COLA condition is satisfied when the "Amplitude
1203
+ Flatness" is unity.
1204
+
1205
+ .. versionadded:: 0.19.0
1206
+
1207
+ References
1208
+ ----------
1209
+ .. [1] Julius O. Smith III, "Spectral Audio Signal Processing", W3K
1210
+ Publishing, 2011,ISBN 978-0-9745607-3-1.
1211
+ .. [2] G. Heinzel, A. Ruediger and R. Schilling, "Spectrum and
1212
+ spectral density estimation by the Discrete Fourier transform
1213
+ (DFT), including a comprehensive list of window functions and
1214
+ some new at-top windows", 2002,
1215
+ http://hdl.handle.net/11858/00-001M-0000-0013-557A-5
1216
+
1217
+ Examples
1218
+ --------
1219
+ >>> from scipy import signal
1220
+
1221
+ Confirm COLA condition for rectangular window of 75% (3/4) overlap:
1222
+
1223
+ >>> signal.check_COLA(signal.windows.boxcar(100), 100, 75)
1224
+ True
1225
+
1226
+ COLA is not true for 25% (1/4) overlap, though:
1227
+
1228
+ >>> signal.check_COLA(signal.windows.boxcar(100), 100, 25)
1229
+ False
1230
+
1231
+ "Symmetrical" Hann window (for filter design) is not COLA:
1232
+
1233
+ >>> signal.check_COLA(signal.windows.hann(120, sym=True), 120, 60)
1234
+ False
1235
+
1236
+ "Periodic" or "DFT-even" Hann window (for FFT analysis) is COLA for
1237
+ overlap of 1/2, 2/3, 3/4, etc.:
1238
+
1239
+ >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 60)
1240
+ True
1241
+
1242
+ >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 80)
1243
+ True
1244
+
1245
+ >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 90)
1246
+ True
1247
+
1248
+ """
1249
+ nperseg = int(nperseg)
1250
+
1251
+ if nperseg < 1:
1252
+ raise ValueError('nperseg must be a positive integer')
1253
+
1254
+ if noverlap >= nperseg:
1255
+ raise ValueError('noverlap must be less than nperseg.')
1256
+ noverlap = int(noverlap)
1257
+
1258
+ if isinstance(window, str) or type(window) is tuple:
1259
+ win = get_window(window, nperseg)
1260
+ else:
1261
+ win = np.asarray(window)
1262
+ if len(win.shape) != 1:
1263
+ raise ValueError('window must be 1-D')
1264
+ if win.shape[0] != nperseg:
1265
+ raise ValueError('window must have length of nperseg')
1266
+
1267
+ step = nperseg - noverlap
1268
+ binsums = sum(win[ii*step:(ii+1)*step] for ii in range(nperseg//step))
1269
+
1270
+ if nperseg % step != 0:
1271
+ binsums[:nperseg % step] += win[-(nperseg % step):]
1272
+
1273
+ deviation = binsums - np.median(binsums)
1274
+ return np.max(np.abs(deviation)) < tol
1275
+
1276
+
1277
+ def check_NOLA(window, nperseg, noverlap, tol=1e-10):
1278
+ r"""Check whether the Nonzero Overlap Add (NOLA) constraint is met.
1279
+
1280
+ Parameters
1281
+ ----------
1282
+ window : str or tuple or array_like
1283
+ Desired window to use. If `window` is a string or tuple, it is
1284
+ passed to `get_window` to generate the window values, which are
1285
+ DFT-even by default. See `get_window` for a list of windows and
1286
+ required parameters. If `window` is array_like it will be used
1287
+ directly as the window and its length must be nperseg.
1288
+ nperseg : int
1289
+ Length of each segment.
1290
+ noverlap : int
1291
+ Number of points to overlap between segments.
1292
+ tol : float, optional
1293
+ The allowed variance of a bin's weighted sum from the median bin
1294
+ sum.
1295
+
1296
+ Returns
1297
+ -------
1298
+ verdict : bool
1299
+ `True` if chosen combination satisfies the NOLA constraint within
1300
+ `tol`, `False` otherwise
1301
+
1302
+ See Also
1303
+ --------
1304
+ check_COLA: Check whether the Constant OverLap Add (COLA) constraint is met
1305
+ stft: Short Time Fourier Transform
1306
+ istft: Inverse Short Time Fourier Transform
1307
+
1308
+ Notes
1309
+ -----
1310
+ In order to enable inversion of an STFT via the inverse STFT in
1311
+ `istft`, the signal windowing must obey the constraint of "nonzero
1312
+ overlap add" (NOLA):
1313
+
1314
+ .. math:: \sum_{t}w^{2}[n-tH] \ne 0
1315
+
1316
+ for all :math:`n`, where :math:`w` is the window function, :math:`t` is the
1317
+ frame index, and :math:`H` is the hop size (:math:`H` = `nperseg` -
1318
+ `noverlap`).
1319
+
1320
+ This ensures that the normalization factors in the denominator of the
1321
+ overlap-add inversion equation are not zero. Only very pathological windows
1322
+ will fail the NOLA constraint.
1323
+
1324
+ .. versionadded:: 1.2.0
1325
+
1326
+ References
1327
+ ----------
1328
+ .. [1] Julius O. Smith III, "Spectral Audio Signal Processing", W3K
1329
+ Publishing, 2011,ISBN 978-0-9745607-3-1.
1330
+ .. [2] G. Heinzel, A. Ruediger and R. Schilling, "Spectrum and
1331
+ spectral density estimation by the Discrete Fourier transform
1332
+ (DFT), including a comprehensive list of window functions and
1333
+ some new at-top windows", 2002,
1334
+ http://hdl.handle.net/11858/00-001M-0000-0013-557A-5
1335
+
1336
+ Examples
1337
+ --------
1338
+ >>> import numpy as np
1339
+ >>> from scipy import signal
1340
+
1341
+ Confirm NOLA condition for rectangular window of 75% (3/4) overlap:
1342
+
1343
+ >>> signal.check_NOLA(signal.windows.boxcar(100), 100, 75)
1344
+ True
1345
+
1346
+ NOLA is also true for 25% (1/4) overlap:
1347
+
1348
+ >>> signal.check_NOLA(signal.windows.boxcar(100), 100, 25)
1349
+ True
1350
+
1351
+ "Symmetrical" Hann window (for filter design) is also NOLA:
1352
+
1353
+ >>> signal.check_NOLA(signal.windows.hann(120, sym=True), 120, 60)
1354
+ True
1355
+
1356
+ As long as there is overlap, it takes quite a pathological window to fail
1357
+ NOLA:
1358
+
1359
+ >>> w = np.ones(64, dtype="float")
1360
+ >>> w[::2] = 0
1361
+ >>> signal.check_NOLA(w, 64, 32)
1362
+ False
1363
+
1364
+ If there is not enough overlap, a window with zeros at the ends will not
1365
+ work:
1366
+
1367
+ >>> signal.check_NOLA(signal.windows.hann(64), 64, 0)
1368
+ False
1369
+ >>> signal.check_NOLA(signal.windows.hann(64), 64, 1)
1370
+ False
1371
+ >>> signal.check_NOLA(signal.windows.hann(64), 64, 2)
1372
+ True
1373
+
1374
+ """
1375
+ nperseg = int(nperseg)
1376
+
1377
+ if nperseg < 1:
1378
+ raise ValueError('nperseg must be a positive integer')
1379
+
1380
+ if noverlap >= nperseg:
1381
+ raise ValueError('noverlap must be less than nperseg')
1382
+ if noverlap < 0:
1383
+ raise ValueError('noverlap must be a nonnegative integer')
1384
+ noverlap = int(noverlap)
1385
+
1386
+ if isinstance(window, str) or type(window) is tuple:
1387
+ win = get_window(window, nperseg)
1388
+ else:
1389
+ win = np.asarray(window)
1390
+ if len(win.shape) != 1:
1391
+ raise ValueError('window must be 1-D')
1392
+ if win.shape[0] != nperseg:
1393
+ raise ValueError('window must have length of nperseg')
1394
+
1395
+ step = nperseg - noverlap
1396
+ binsums = sum(win[ii*step:(ii+1)*step]**2 for ii in range(nperseg//step))
1397
+
1398
+ if nperseg % step != 0:
1399
+ binsums[:nperseg % step] += win[-(nperseg % step):]**2
1400
+
1401
+ return np.min(binsums) > tol
1402
+
1403
+
1404
+ def stft(x, fs=1.0, window='hann', nperseg=256, noverlap=None, nfft=None,
1405
+ detrend=False, return_onesided=True, boundary='zeros', padded=True,
1406
+ axis=-1, scaling='spectrum'):
1407
+ r"""Compute the Short Time Fourier Transform (legacy function).
1408
+
1409
+ STFTs can be used as a way of quantifying the change of a
1410
+ nonstationary signal's frequency and phase content over time.
1411
+
1412
+ .. legacy:: function
1413
+
1414
+ `ShortTimeFFT` is a newer STFT / ISTFT implementation with more
1415
+ features. A :ref:`comparison <tutorial_stft_legacy_stft>` between the
1416
+ implementations can be found in the :ref:`tutorial_stft` section of the
1417
+ :ref:`user_guide`.
1418
+
1419
+ Parameters
1420
+ ----------
1421
+ x : array_like
1422
+ Time series of measurement values
1423
+ fs : float, optional
1424
+ Sampling frequency of the `x` time series. Defaults to 1.0.
1425
+ window : str or tuple or array_like, optional
1426
+ Desired window to use. If `window` is a string or tuple, it is
1427
+ passed to `get_window` to generate the window values, which are
1428
+ DFT-even by default. See `get_window` for a list of windows and
1429
+ required parameters. If `window` is array_like it will be used
1430
+ directly as the window and its length must be nperseg. Defaults
1431
+ to a Hann window.
1432
+ nperseg : int, optional
1433
+ Length of each segment. Defaults to 256.
1434
+ noverlap : int, optional
1435
+ Number of points to overlap between segments. If `None`,
1436
+ ``noverlap = nperseg // 2``. Defaults to `None`. When
1437
+ specified, the COLA constraint must be met (see Notes below).
1438
+ nfft : int, optional
1439
+ Length of the FFT used, if a zero padded FFT is desired. If
1440
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
1441
+ detrend : str or function or `False`, optional
1442
+ Specifies how to detrend each segment. If `detrend` is a
1443
+ string, it is passed as the `type` argument to the `detrend`
1444
+ function. If it is a function, it takes a segment and returns a
1445
+ detrended segment. If `detrend` is `False`, no detrending is
1446
+ done. Defaults to `False`.
1447
+ return_onesided : bool, optional
1448
+ If `True`, return a one-sided spectrum for real data. If
1449
+ `False` return a two-sided spectrum. Defaults to `True`, but for
1450
+ complex data, a two-sided spectrum is always returned.
1451
+ boundary : str or None, optional
1452
+ Specifies whether the input signal is extended at both ends, and
1453
+ how to generate the new values, in order to center the first
1454
+ windowed segment on the first input point. This has the benefit
1455
+ of enabling reconstruction of the first input point when the
1456
+ employed window function starts at zero. Valid options are
1457
+ ``['even', 'odd', 'constant', 'zeros', None]``. Defaults to
1458
+ 'zeros', for zero padding extension. I.e. ``[1, 2, 3, 4]`` is
1459
+ extended to ``[0, 1, 2, 3, 4, 0]`` for ``nperseg=3``.
1460
+ padded : bool, optional
1461
+ Specifies whether the input signal is zero-padded at the end to
1462
+ make the signal fit exactly into an integer number of window
1463
+ segments, so that all of the signal is included in the output.
1464
+ Defaults to `True`. Padding occurs after boundary extension, if
1465
+ `boundary` is not `None`, and `padded` is `True`, as is the
1466
+ default.
1467
+ axis : int, optional
1468
+ Axis along which the STFT is computed; the default is over the
1469
+ last axis (i.e. ``axis=-1``).
1470
+ scaling: {'spectrum', 'psd'}
1471
+ The default 'spectrum' scaling allows each frequency line of `Zxx` to
1472
+ be interpreted as a magnitude spectrum. The 'psd' option scales each
1473
+ line to a power spectral density - it allows to calculate the signal's
1474
+ energy by numerically integrating over ``abs(Zxx)**2``.
1475
+
1476
+ .. versionadded:: 1.9.0
1477
+
1478
+ Returns
1479
+ -------
1480
+ f : ndarray
1481
+ Array of sample frequencies.
1482
+ t : ndarray
1483
+ Array of segment times.
1484
+ Zxx : ndarray
1485
+ STFT of `x`. By default, the last axis of `Zxx` corresponds
1486
+ to the segment times.
1487
+
1488
+ See Also
1489
+ --------
1490
+ istft: Inverse Short Time Fourier Transform
1491
+ ShortTimeFFT: Newer STFT/ISTFT implementation providing more features.
1492
+ check_COLA: Check whether the Constant OverLap Add (COLA) constraint
1493
+ is met
1494
+ check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
1495
+ welch: Power spectral density by Welch's method.
1496
+ spectrogram: Spectrogram by Welch's method.
1497
+ csd: Cross spectral density by Welch's method.
1498
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
1499
+
1500
+ Notes
1501
+ -----
1502
+ In order to enable inversion of an STFT via the inverse STFT in
1503
+ `istft`, the signal windowing must obey the constraint of "Nonzero
1504
+ OverLap Add" (NOLA), and the input signal must have complete
1505
+ windowing coverage (i.e. ``(x.shape[axis] - nperseg) %
1506
+ (nperseg-noverlap) == 0``). The `padded` argument may be used to
1507
+ accomplish this.
1508
+
1509
+ Given a time-domain signal :math:`x[n]`, a window :math:`w[n]`, and a hop
1510
+ size :math:`H` = `nperseg - noverlap`, the windowed frame at time index
1511
+ :math:`t` is given by
1512
+
1513
+ .. math:: x_{t}[n]=x[n]w[n-tH]
1514
+
1515
+ The overlap-add (OLA) reconstruction equation is given by
1516
+
1517
+ .. math:: x[n]=\frac{\sum_{t}x_{t}[n]w[n-tH]}{\sum_{t}w^{2}[n-tH]}
1518
+
1519
+ The NOLA constraint ensures that every normalization term that appears
1520
+ in the denominator of the OLA reconstruction equation is nonzero. Whether a
1521
+ choice of `window`, `nperseg`, and `noverlap` satisfy this constraint can
1522
+ be tested with `check_NOLA`.
1523
+
1524
+
1525
+ .. versionadded:: 0.19.0
1526
+
1527
+ References
1528
+ ----------
1529
+ .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
1530
+ "Discrete-Time Signal Processing", Prentice Hall, 1999.
1531
+ .. [2] Daniel W. Griffin, Jae S. Lim "Signal Estimation from
1532
+ Modified Short-Time Fourier Transform", IEEE 1984,
1533
+ 10.1109/TASSP.1984.1164317
1534
+
1535
+ Examples
1536
+ --------
1537
+ >>> import numpy as np
1538
+ >>> from scipy import signal
1539
+ >>> import matplotlib.pyplot as plt
1540
+ >>> rng = np.random.default_rng()
1541
+
1542
+ Generate a test signal, a 2 Vrms sine wave whose frequency is slowly
1543
+ modulated around 3kHz, corrupted by white noise of exponentially
1544
+ decreasing magnitude sampled at 10 kHz.
1545
+
1546
+ >>> fs = 10e3
1547
+ >>> N = 1e5
1548
+ >>> amp = 2 * np.sqrt(2)
1549
+ >>> noise_power = 0.01 * fs / 2
1550
+ >>> time = np.arange(N) / float(fs)
1551
+ >>> mod = 500*np.cos(2*np.pi*0.25*time)
1552
+ >>> carrier = amp * np.sin(2*np.pi*3e3*time + mod)
1553
+ >>> noise = rng.normal(scale=np.sqrt(noise_power),
1554
+ ... size=time.shape)
1555
+ >>> noise *= np.exp(-time/5)
1556
+ >>> x = carrier + noise
1557
+
1558
+ Compute and plot the STFT's magnitude.
1559
+
1560
+ >>> f, t, Zxx = signal.stft(x, fs, nperseg=1000)
1561
+ >>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud')
1562
+ >>> plt.title('STFT Magnitude')
1563
+ >>> plt.ylabel('Frequency [Hz]')
1564
+ >>> plt.xlabel('Time [sec]')
1565
+ >>> plt.show()
1566
+
1567
+ Compare the energy of the signal `x` with the energy of its STFT:
1568
+
1569
+ >>> E_x = sum(x**2) / fs # Energy of x
1570
+ >>> # Calculate a two-sided STFT with PSD scaling:
1571
+ >>> f, t, Zxx = signal.stft(x, fs, nperseg=1000, return_onesided=False,
1572
+ ... scaling='psd')
1573
+ >>> # Integrate numerically over abs(Zxx)**2:
1574
+ >>> df, dt = f[1] - f[0], t[1] - t[0]
1575
+ >>> E_Zxx = sum(np.sum(Zxx.real**2 + Zxx.imag**2, axis=0) * df) * dt
1576
+ >>> # The energy is the same, but the numerical errors are quite large:
1577
+ >>> np.isclose(E_x, E_Zxx, rtol=1e-2)
1578
+ True
1579
+
1580
+ """
1581
+ if scaling == 'psd':
1582
+ scaling = 'density'
1583
+ elif scaling != 'spectrum':
1584
+ raise ValueError(f"Parameter {scaling=} not in ['spectrum', 'psd']!")
1585
+
1586
+ freqs, time, Zxx = _spectral_helper(x, x, fs, window, nperseg, noverlap,
1587
+ nfft, detrend, return_onesided,
1588
+ scaling=scaling, axis=axis,
1589
+ mode='stft', boundary=boundary,
1590
+ padded=padded)
1591
+
1592
+ return freqs, time, Zxx
1593
+
1594
+
1595
+ def istft(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None,
1596
+ input_onesided=True, boundary=True, time_axis=-1, freq_axis=-2,
1597
+ scaling='spectrum'):
1598
+ r"""Perform the inverse Short Time Fourier transform (legacy function).
1599
+
1600
+ .. legacy:: function
1601
+
1602
+ `ShortTimeFFT` is a newer STFT / ISTFT implementation with more
1603
+ features. A :ref:`comparison <tutorial_stft_legacy_stft>` between the
1604
+ implementations can be found in the :ref:`tutorial_stft` section of the
1605
+ :ref:`user_guide`.
1606
+
1607
+ Parameters
1608
+ ----------
1609
+ Zxx : array_like
1610
+ STFT of the signal to be reconstructed. If a purely real array
1611
+ is passed, it will be cast to a complex data type.
1612
+ fs : float, optional
1613
+ Sampling frequency of the time series. Defaults to 1.0.
1614
+ window : str or tuple or array_like, optional
1615
+ Desired window to use. If `window` is a string or tuple, it is
1616
+ passed to `get_window` to generate the window values, which are
1617
+ DFT-even by default. See `get_window` for a list of windows and
1618
+ required parameters. If `window` is array_like it will be used
1619
+ directly as the window and its length must be nperseg. Defaults
1620
+ to a Hann window. Must match the window used to generate the
1621
+ STFT for faithful inversion.
1622
+ nperseg : int, optional
1623
+ Number of data points corresponding to each STFT segment. This
1624
+ parameter must be specified if the number of data points per
1625
+ segment is odd, or if the STFT was padded via ``nfft >
1626
+ nperseg``. If `None`, the value depends on the shape of
1627
+ `Zxx` and `input_onesided`. If `input_onesided` is `True`,
1628
+ ``nperseg=2*(Zxx.shape[freq_axis] - 1)``. Otherwise,
1629
+ ``nperseg=Zxx.shape[freq_axis]``. Defaults to `None`.
1630
+ noverlap : int, optional
1631
+ Number of points to overlap between segments. If `None`, half
1632
+ of the segment length. Defaults to `None`. When specified, the
1633
+ COLA constraint must be met (see Notes below), and should match
1634
+ the parameter used to generate the STFT. Defaults to `None`.
1635
+ nfft : int, optional
1636
+ Number of FFT points corresponding to each STFT segment. This
1637
+ parameter must be specified if the STFT was padded via ``nfft >
1638
+ nperseg``. If `None`, the default values are the same as for
1639
+ `nperseg`, detailed above, with one exception: if
1640
+ `input_onesided` is True and
1641
+ ``nperseg==2*Zxx.shape[freq_axis] - 1``, `nfft` also takes on
1642
+ that value. This case allows the proper inversion of an
1643
+ odd-length unpadded STFT using ``nfft=None``. Defaults to
1644
+ `None`.
1645
+ input_onesided : bool, optional
1646
+ If `True`, interpret the input array as one-sided FFTs, such
1647
+ as is returned by `stft` with ``return_onesided=True`` and
1648
+ `numpy.fft.rfft`. If `False`, interpret the input as a a
1649
+ two-sided FFT. Defaults to `True`.
1650
+ boundary : bool, optional
1651
+ Specifies whether the input signal was extended at its
1652
+ boundaries by supplying a non-`None` ``boundary`` argument to
1653
+ `stft`. Defaults to `True`.
1654
+ time_axis : int, optional
1655
+ Where the time segments of the STFT is located; the default is
1656
+ the last axis (i.e. ``axis=-1``).
1657
+ freq_axis : int, optional
1658
+ Where the frequency axis of the STFT is located; the default is
1659
+ the penultimate axis (i.e. ``axis=-2``).
1660
+ scaling: {'spectrum', 'psd'}
1661
+ The default 'spectrum' scaling allows each frequency line of `Zxx` to
1662
+ be interpreted as a magnitude spectrum. The 'psd' option scales each
1663
+ line to a power spectral density - it allows to calculate the signal's
1664
+ energy by numerically integrating over ``abs(Zxx)**2``.
1665
+
1666
+ Returns
1667
+ -------
1668
+ t : ndarray
1669
+ Array of output data times.
1670
+ x : ndarray
1671
+ iSTFT of `Zxx`.
1672
+
1673
+ See Also
1674
+ --------
1675
+ stft: Short Time Fourier Transform
1676
+ ShortTimeFFT: Newer STFT/ISTFT implementation providing more features.
1677
+ check_COLA: Check whether the Constant OverLap Add (COLA) constraint
1678
+ is met
1679
+ check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
1680
+
1681
+ Notes
1682
+ -----
1683
+ In order to enable inversion of an STFT via the inverse STFT with
1684
+ `istft`, the signal windowing must obey the constraint of "nonzero
1685
+ overlap add" (NOLA):
1686
+
1687
+ .. math:: \sum_{t}w^{2}[n-tH] \ne 0
1688
+
1689
+ This ensures that the normalization factors that appear in the denominator
1690
+ of the overlap-add reconstruction equation
1691
+
1692
+ .. math:: x[n]=\frac{\sum_{t}x_{t}[n]w[n-tH]}{\sum_{t}w^{2}[n-tH]}
1693
+
1694
+ are not zero. The NOLA constraint can be checked with the `check_NOLA`
1695
+ function.
1696
+
1697
+ An STFT which has been modified (via masking or otherwise) is not
1698
+ guaranteed to correspond to a exactly realizible signal. This
1699
+ function implements the iSTFT via the least-squares estimation
1700
+ algorithm detailed in [2]_, which produces a signal that minimizes
1701
+ the mean squared error between the STFT of the returned signal and
1702
+ the modified STFT.
1703
+
1704
+
1705
+ .. versionadded:: 0.19.0
1706
+
1707
+ References
1708
+ ----------
1709
+ .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
1710
+ "Discrete-Time Signal Processing", Prentice Hall, 1999.
1711
+ .. [2] Daniel W. Griffin, Jae S. Lim "Signal Estimation from
1712
+ Modified Short-Time Fourier Transform", IEEE 1984,
1713
+ 10.1109/TASSP.1984.1164317
1714
+
1715
+ Examples
1716
+ --------
1717
+ >>> import numpy as np
1718
+ >>> from scipy import signal
1719
+ >>> import matplotlib.pyplot as plt
1720
+ >>> rng = np.random.default_rng()
1721
+
1722
+ Generate a test signal, a 2 Vrms sine wave at 50Hz corrupted by
1723
+ 0.001 V**2/Hz of white noise sampled at 1024 Hz.
1724
+
1725
+ >>> fs = 1024
1726
+ >>> N = 10*fs
1727
+ >>> nperseg = 512
1728
+ >>> amp = 2 * np.sqrt(2)
1729
+ >>> noise_power = 0.001 * fs / 2
1730
+ >>> time = np.arange(N) / float(fs)
1731
+ >>> carrier = amp * np.sin(2*np.pi*50*time)
1732
+ >>> noise = rng.normal(scale=np.sqrt(noise_power),
1733
+ ... size=time.shape)
1734
+ >>> x = carrier + noise
1735
+
1736
+ Compute the STFT, and plot its magnitude
1737
+
1738
+ >>> f, t, Zxx = signal.stft(x, fs=fs, nperseg=nperseg)
1739
+ >>> plt.figure()
1740
+ >>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud')
1741
+ >>> plt.ylim([f[1], f[-1]])
1742
+ >>> plt.title('STFT Magnitude')
1743
+ >>> plt.ylabel('Frequency [Hz]')
1744
+ >>> plt.xlabel('Time [sec]')
1745
+ >>> plt.yscale('log')
1746
+ >>> plt.show()
1747
+
1748
+ Zero the components that are 10% or less of the carrier magnitude,
1749
+ then convert back to a time series via inverse STFT
1750
+
1751
+ >>> Zxx = np.where(np.abs(Zxx) >= amp/10, Zxx, 0)
1752
+ >>> _, xrec = signal.istft(Zxx, fs)
1753
+
1754
+ Compare the cleaned signal with the original and true carrier signals.
1755
+
1756
+ >>> plt.figure()
1757
+ >>> plt.plot(time, x, time, xrec, time, carrier)
1758
+ >>> plt.xlim([2, 2.1])
1759
+ >>> plt.xlabel('Time [sec]')
1760
+ >>> plt.ylabel('Signal')
1761
+ >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier'])
1762
+ >>> plt.show()
1763
+
1764
+ Note that the cleaned signal does not start as abruptly as the original,
1765
+ since some of the coefficients of the transient were also removed:
1766
+
1767
+ >>> plt.figure()
1768
+ >>> plt.plot(time, x, time, xrec, time, carrier)
1769
+ >>> plt.xlim([0, 0.1])
1770
+ >>> plt.xlabel('Time [sec]')
1771
+ >>> plt.ylabel('Signal')
1772
+ >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier'])
1773
+ >>> plt.show()
1774
+
1775
+ """
1776
+ # Make sure input is an ndarray of appropriate complex dtype
1777
+ Zxx = np.asarray(Zxx) + 0j
1778
+ freq_axis = int(freq_axis)
1779
+ time_axis = int(time_axis)
1780
+
1781
+ if Zxx.ndim < 2:
1782
+ raise ValueError('Input stft must be at least 2d!')
1783
+
1784
+ if freq_axis == time_axis:
1785
+ raise ValueError('Must specify differing time and frequency axes!')
1786
+
1787
+ nseg = Zxx.shape[time_axis]
1788
+
1789
+ if input_onesided:
1790
+ # Assume even segment length
1791
+ n_default = 2*(Zxx.shape[freq_axis] - 1)
1792
+ else:
1793
+ n_default = Zxx.shape[freq_axis]
1794
+
1795
+ # Check windowing parameters
1796
+ if nperseg is None:
1797
+ nperseg = n_default
1798
+ else:
1799
+ nperseg = int(nperseg)
1800
+ if nperseg < 1:
1801
+ raise ValueError('nperseg must be a positive integer')
1802
+
1803
+ if nfft is None:
1804
+ if (input_onesided) and (nperseg == n_default + 1):
1805
+ # Odd nperseg, no FFT padding
1806
+ nfft = nperseg
1807
+ else:
1808
+ nfft = n_default
1809
+ elif nfft < nperseg:
1810
+ raise ValueError('nfft must be greater than or equal to nperseg.')
1811
+ else:
1812
+ nfft = int(nfft)
1813
+
1814
+ if noverlap is None:
1815
+ noverlap = nperseg//2
1816
+ else:
1817
+ noverlap = int(noverlap)
1818
+ if noverlap >= nperseg:
1819
+ raise ValueError('noverlap must be less than nperseg.')
1820
+ nstep = nperseg - noverlap
1821
+
1822
+ # Rearrange axes if necessary
1823
+ if time_axis != Zxx.ndim-1 or freq_axis != Zxx.ndim-2:
1824
+ # Turn negative indices to positive for the call to transpose
1825
+ if freq_axis < 0:
1826
+ freq_axis = Zxx.ndim + freq_axis
1827
+ if time_axis < 0:
1828
+ time_axis = Zxx.ndim + time_axis
1829
+ zouter = list(range(Zxx.ndim))
1830
+ for ax in sorted([time_axis, freq_axis], reverse=True):
1831
+ zouter.pop(ax)
1832
+ Zxx = np.transpose(Zxx, zouter+[freq_axis, time_axis])
1833
+
1834
+ # Get window as array
1835
+ if isinstance(window, str) or type(window) is tuple:
1836
+ win = get_window(window, nperseg)
1837
+ else:
1838
+ win = np.asarray(window)
1839
+ if len(win.shape) != 1:
1840
+ raise ValueError('window must be 1-D')
1841
+ if win.shape[0] != nperseg:
1842
+ raise ValueError(f'window must have length of {nperseg}')
1843
+
1844
+ ifunc = sp_fft.irfft if input_onesided else sp_fft.ifft
1845
+ xsubs = ifunc(Zxx, axis=-2, n=nfft)[..., :nperseg, :]
1846
+
1847
+ # Initialize output and normalization arrays
1848
+ outputlength = nperseg + (nseg-1)*nstep
1849
+ x = np.zeros(list(Zxx.shape[:-2])+[outputlength], dtype=xsubs.dtype)
1850
+ norm = np.zeros(outputlength, dtype=xsubs.dtype)
1851
+
1852
+ if np.result_type(win, xsubs) != xsubs.dtype:
1853
+ win = win.astype(xsubs.dtype)
1854
+
1855
+ if scaling == 'spectrum':
1856
+ xsubs *= win.sum()
1857
+ elif scaling == 'psd':
1858
+ xsubs *= np.sqrt(fs * sum(win**2))
1859
+ else:
1860
+ raise ValueError(f"Parameter {scaling=} not in ['spectrum', 'psd']!")
1861
+
1862
+ # Construct the output from the ifft segments
1863
+ # This loop could perhaps be vectorized/strided somehow...
1864
+ for ii in range(nseg):
1865
+ # Window the ifft
1866
+ x[..., ii*nstep:ii*nstep+nperseg] += xsubs[..., ii] * win
1867
+ norm[..., ii*nstep:ii*nstep+nperseg] += win**2
1868
+
1869
+ # Remove extension points
1870
+ if boundary:
1871
+ x = x[..., nperseg//2:-(nperseg//2)]
1872
+ norm = norm[..., nperseg//2:-(nperseg//2)]
1873
+
1874
+ # Divide out normalization where non-tiny
1875
+ if np.sum(norm > 1e-10) != len(norm):
1876
+ warnings.warn(
1877
+ "NOLA condition failed, STFT may not be invertible."
1878
+ + (" Possibly due to missing boundary" if not boundary else ""),
1879
+ stacklevel=2
1880
+ )
1881
+ x /= np.where(norm > 1e-10, norm, 1.0)
1882
+
1883
+ if input_onesided:
1884
+ x = x.real
1885
+
1886
+ # Put axes back
1887
+ if x.ndim > 1:
1888
+ if time_axis != Zxx.ndim-1:
1889
+ if freq_axis < time_axis:
1890
+ time_axis -= 1
1891
+ x = np.moveaxis(x, -1, time_axis)
1892
+
1893
+ time = np.arange(x.shape[0])/float(fs)
1894
+ return time, x
1895
+
1896
+
1897
+ def coherence(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
1898
+ nfft=None, detrend='constant', axis=-1):
1899
+ r"""
1900
+ Estimate the magnitude squared coherence estimate, Cxy, of
1901
+ discrete-time signals X and Y using Welch's method.
1902
+
1903
+ ``Cxy = abs(Pxy)**2/(Pxx*Pyy)``, where `Pxx` and `Pyy` are power
1904
+ spectral density estimates of X and Y, and `Pxy` is the cross
1905
+ spectral density estimate of X and Y.
1906
+
1907
+ Parameters
1908
+ ----------
1909
+ x : array_like
1910
+ Time series of measurement values
1911
+ y : array_like
1912
+ Time series of measurement values
1913
+ fs : float, optional
1914
+ Sampling frequency of the `x` and `y` time series. Defaults
1915
+ to 1.0.
1916
+ window : str or tuple or array_like, optional
1917
+ Desired window to use. If `window` is a string or tuple, it is
1918
+ passed to `get_window` to generate the window values, which are
1919
+ DFT-even by default. See `get_window` for a list of windows and
1920
+ required parameters. If `window` is array_like it will be used
1921
+ directly as the window and its length must be nperseg. Defaults
1922
+ to a Hann window.
1923
+ nperseg : int, optional
1924
+ Length of each segment. Defaults to None, but if window is str or
1925
+ tuple, is set to 256, and if window is array_like, is set to the
1926
+ length of the window.
1927
+ noverlap: int, optional
1928
+ Number of points to overlap between segments. If `None`,
1929
+ ``noverlap = nperseg // 2``. Defaults to `None`.
1930
+ nfft : int, optional
1931
+ Length of the FFT used, if a zero padded FFT is desired. If
1932
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
1933
+ detrend : str or function or `False`, optional
1934
+ Specifies how to detrend each segment. If `detrend` is a
1935
+ string, it is passed as the `type` argument to the `detrend`
1936
+ function. If it is a function, it takes a segment and returns a
1937
+ detrended segment. If `detrend` is `False`, no detrending is
1938
+ done. Defaults to 'constant'.
1939
+ axis : int, optional
1940
+ Axis along which the coherence is computed for both inputs; the
1941
+ default is over the last axis (i.e. ``axis=-1``).
1942
+
1943
+ Returns
1944
+ -------
1945
+ f : ndarray
1946
+ Array of sample frequencies.
1947
+ Cxy : ndarray
1948
+ Magnitude squared coherence of x and y.
1949
+
1950
+ See Also
1951
+ --------
1952
+ periodogram: Simple, optionally modified periodogram
1953
+ lombscargle: Lomb-Scargle periodogram for unevenly sampled data
1954
+ welch: Power spectral density by Welch's method.
1955
+ csd: Cross spectral density by Welch's method.
1956
+
1957
+ Notes
1958
+ -----
1959
+ An appropriate amount of overlap will depend on the choice of window
1960
+ and on your requirements. For the default Hann window an overlap of
1961
+ 50% is a reasonable trade-off between accurately estimating the
1962
+ signal power, while not over counting any of the data. Narrower
1963
+ windows may require a larger overlap.
1964
+
1965
+ .. versionadded:: 0.16.0
1966
+
1967
+ References
1968
+ ----------
1969
+ .. [1] P. Welch, "The use of the fast Fourier transform for the
1970
+ estimation of power spectra: A method based on time averaging
1971
+ over short, modified periodograms", IEEE Trans. Audio
1972
+ Electroacoust. vol. 15, pp. 70-73, 1967.
1973
+ .. [2] Stoica, Petre, and Randolph Moses, "Spectral Analysis of
1974
+ Signals" Prentice Hall, 2005
1975
+
1976
+ Examples
1977
+ --------
1978
+ >>> import numpy as np
1979
+ >>> from scipy import signal
1980
+ >>> import matplotlib.pyplot as plt
1981
+ >>> rng = np.random.default_rng()
1982
+
1983
+ Generate two test signals with some common features.
1984
+
1985
+ >>> fs = 10e3
1986
+ >>> N = 1e5
1987
+ >>> amp = 20
1988
+ >>> freq = 1234.0
1989
+ >>> noise_power = 0.001 * fs / 2
1990
+ >>> time = np.arange(N) / fs
1991
+ >>> b, a = signal.butter(2, 0.25, 'low')
1992
+ >>> x = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
1993
+ >>> y = signal.lfilter(b, a, x)
1994
+ >>> x += amp*np.sin(2*np.pi*freq*time)
1995
+ >>> y += rng.normal(scale=0.1*np.sqrt(noise_power), size=time.shape)
1996
+
1997
+ Compute and plot the coherence.
1998
+
1999
+ >>> f, Cxy = signal.coherence(x, y, fs, nperseg=1024)
2000
+ >>> plt.semilogy(f, Cxy)
2001
+ >>> plt.xlabel('frequency [Hz]')
2002
+ >>> plt.ylabel('Coherence')
2003
+ >>> plt.show()
2004
+
2005
+ """
2006
+ freqs, Pxx = welch(x, fs=fs, window=window, nperseg=nperseg,
2007
+ noverlap=noverlap, nfft=nfft, detrend=detrend,
2008
+ axis=axis)
2009
+ _, Pyy = welch(y, fs=fs, window=window, nperseg=nperseg, noverlap=noverlap,
2010
+ nfft=nfft, detrend=detrend, axis=axis)
2011
+ _, Pxy = csd(x, y, fs=fs, window=window, nperseg=nperseg,
2012
+ noverlap=noverlap, nfft=nfft, detrend=detrend, axis=axis)
2013
+
2014
+ Cxy = np.abs(Pxy)**2 / Pxx / Pyy
2015
+
2016
+ return freqs, Cxy
2017
+
2018
+
2019
+ def _spectral_helper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
2020
+ nfft=None, detrend='constant', return_onesided=True,
2021
+ scaling='density', axis=-1, mode='psd', boundary=None,
2022
+ padded=False):
2023
+ """Calculate various forms of windowed FFTs for PSD, CSD, etc.
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
+
2030
+ This is a helper function that implements the commonality between
2031
+ the stft, psd, csd, and spectrogram functions. It is not designed to
2032
+ be called externally. The windows are not averaged over; the result
2033
+ from each window is returned.
2034
+
2035
+ Parameters
2036
+ ----------
2037
+ x : array_like
2038
+ Array or sequence containing the data to be analyzed.
2039
+ y : array_like
2040
+ Array or sequence containing the data to be analyzed. If this is
2041
+ the same object in memory as `x` (i.e. ``_spectral_helper(x,
2042
+ x, ...)``), the extra computations are spared.
2043
+ fs : float, optional
2044
+ Sampling frequency of the time series. Defaults to 1.0.
2045
+ window : str or tuple or array_like, optional
2046
+ Desired window to use. If `window` is a string or tuple, it is
2047
+ passed to `get_window` to generate the window values, which are
2048
+ DFT-even by default. See `get_window` for a list of windows and
2049
+ required parameters. If `window` is array_like it will be used
2050
+ directly as the window and its length must be nperseg. Defaults
2051
+ to a Hann window.
2052
+ nperseg : int, optional
2053
+ Length of each segment. Defaults to None, but if window is str or
2054
+ tuple, is set to 256, and if window is array_like, is set to the
2055
+ length of the window.
2056
+ noverlap : int, optional
2057
+ Number of points to overlap between segments. If `None`,
2058
+ ``noverlap = nperseg // 2``. Defaults to `None`.
2059
+ nfft : int, optional
2060
+ Length of the FFT used, if a zero padded FFT is desired. If
2061
+ `None`, the FFT length is `nperseg`. Defaults to `None`.
2062
+ detrend : str or function or `False`, optional
2063
+ Specifies how to detrend each segment. If `detrend` is a
2064
+ string, it is passed as the `type` argument to the `detrend`
2065
+ function. If it is a function, it takes a segment and returns a
2066
+ detrended segment. If `detrend` is `False`, no detrending is
2067
+ done. Defaults to 'constant'.
2068
+ return_onesided : bool, optional
2069
+ If `True`, return a one-sided spectrum for real data. If
2070
+ `False` return a two-sided spectrum. Defaults to `True`, but for
2071
+ complex data, a two-sided spectrum is always returned.
2072
+ scaling : { 'density', 'spectrum' }, optional
2073
+ Selects between computing the cross spectral density ('density')
2074
+ where `Pxy` has units of V²/Hz and computing the cross
2075
+ spectrum ('spectrum') where `Pxy` has units of V², if `x`
2076
+ and `y` are measured in V and `fs` is measured in Hz.
2077
+ Defaults to 'density'
2078
+ axis : int, optional
2079
+ Axis along which the FFTs are computed; the default is over the
2080
+ last axis (i.e. ``axis=-1``).
2081
+ mode: str {'psd', 'stft'}, optional
2082
+ Defines what kind of return values are expected. Defaults to
2083
+ 'psd'.
2084
+ boundary : str or None, optional
2085
+ Specifies whether the input signal is extended at both ends, and
2086
+ how to generate the new values, in order to center the first
2087
+ windowed segment on the first input point. This has the benefit
2088
+ of enabling reconstruction of the first input point when the
2089
+ employed window function starts at zero. Valid options are
2090
+ ``['even', 'odd', 'constant', 'zeros', None]``. Defaults to
2091
+ `None`.
2092
+ padded : bool, optional
2093
+ Specifies whether the input signal is zero-padded at the end to
2094
+ make the signal fit exactly into an integer number of window
2095
+ segments, so that all of the signal is included in the output.
2096
+ Defaults to `False`. Padding occurs after boundary extension, if
2097
+ `boundary` is not `None`, and `padded` is `True`.
2098
+
2099
+ Returns
2100
+ -------
2101
+ freqs : ndarray
2102
+ Array of sample frequencies.
2103
+ t : ndarray
2104
+ Array of times corresponding to each data segment
2105
+ result : ndarray
2106
+ Array of output data, contents dependent on *mode* kwarg.
2107
+
2108
+ Notes
2109
+ -----
2110
+ Adapted from matplotlib.mlab
2111
+
2112
+ .. versionadded:: 0.16.0
2113
+ """
2114
+ if mode not in ['psd', 'stft']:
2115
+ raise ValueError(f"Unknown value for mode {mode}, must be one of: "
2116
+ "{'psd', 'stft'}")
2117
+
2118
+ boundary_funcs = {'even': even_ext,
2119
+ 'odd': odd_ext,
2120
+ 'constant': const_ext,
2121
+ 'zeros': zero_ext,
2122
+ None: None}
2123
+
2124
+ if boundary not in boundary_funcs:
2125
+ raise ValueError(f"Unknown boundary option '{boundary}', "
2126
+ f"must be one of: {list(boundary_funcs.keys())}")
2127
+
2128
+ # If x and y are the same object we can save ourselves some computation.
2129
+ same_data = y is x
2130
+
2131
+ if not same_data and mode != 'psd':
2132
+ raise ValueError("x and y must be equal if mode is 'stft'")
2133
+
2134
+ axis = int(axis)
2135
+
2136
+ # Ensure we have np.arrays, get outdtype
2137
+ x = np.asarray(x)
2138
+ if not same_data:
2139
+ y = np.asarray(y)
2140
+ outdtype = np.result_type(x, y, np.complex64)
2141
+ else:
2142
+ outdtype = np.result_type(x, np.complex64)
2143
+
2144
+ if not same_data:
2145
+ # Check if we can broadcast the outer axes together
2146
+ xouter = list(x.shape)
2147
+ youter = list(y.shape)
2148
+ xouter.pop(axis)
2149
+ youter.pop(axis)
2150
+ try:
2151
+ outershape = np.broadcast(np.empty(xouter), np.empty(youter)).shape
2152
+ except ValueError as e:
2153
+ raise ValueError('x and y cannot be broadcast together.') from e
2154
+
2155
+ if same_data:
2156
+ if x.size == 0:
2157
+ return np.empty(x.shape), np.empty(x.shape), np.empty(x.shape)
2158
+ else:
2159
+ if x.size == 0 or y.size == 0:
2160
+ outshape = outershape + (min([x.shape[axis], y.shape[axis]]),)
2161
+ emptyout = np.moveaxis(np.empty(outshape), -1, axis)
2162
+ return emptyout, emptyout, emptyout
2163
+
2164
+ if x.ndim > 1:
2165
+ if axis != -1:
2166
+ x = np.moveaxis(x, axis, -1)
2167
+ if not same_data and y.ndim > 1:
2168
+ y = np.moveaxis(y, axis, -1)
2169
+
2170
+ # Check if x and y are the same length, zero-pad if necessary
2171
+ if not same_data:
2172
+ if x.shape[-1] != y.shape[-1]:
2173
+ if x.shape[-1] < y.shape[-1]:
2174
+ pad_shape = list(x.shape)
2175
+ pad_shape[-1] = y.shape[-1] - x.shape[-1]
2176
+ x = np.concatenate((x, np.zeros(pad_shape)), -1)
2177
+ else:
2178
+ pad_shape = list(y.shape)
2179
+ pad_shape[-1] = x.shape[-1] - y.shape[-1]
2180
+ y = np.concatenate((y, np.zeros(pad_shape)), -1)
2181
+
2182
+ if nperseg is not None: # if specified by user
2183
+ nperseg = int(nperseg)
2184
+ if nperseg < 1:
2185
+ raise ValueError('nperseg must be a positive integer')
2186
+
2187
+ # parse window; if array like, then set nperseg = win.shape
2188
+ win, nperseg = _triage_segments(window, nperseg, input_length=x.shape[-1])
2189
+
2190
+ if nfft is None:
2191
+ nfft = nperseg
2192
+ elif nfft < nperseg:
2193
+ raise ValueError('nfft must be greater than or equal to nperseg.')
2194
+ else:
2195
+ nfft = int(nfft)
2196
+
2197
+ if noverlap is None:
2198
+ noverlap = nperseg//2
2199
+ else:
2200
+ noverlap = int(noverlap)
2201
+ if noverlap >= nperseg:
2202
+ raise ValueError('noverlap must be less than nperseg.')
2203
+ nstep = nperseg - noverlap
2204
+
2205
+ # Padding occurs after boundary extension, so that the extended signal ends
2206
+ # in zeros, instead of introducing an impulse at the end.
2207
+ # I.e. if x = [..., 3, 2]
2208
+ # extend then pad -> [..., 3, 2, 2, 3, 0, 0, 0]
2209
+ # pad then extend -> [..., 3, 2, 0, 0, 0, 2, 3]
2210
+
2211
+ if boundary is not None:
2212
+ ext_func = boundary_funcs[boundary]
2213
+ x = ext_func(x, nperseg//2, axis=-1)
2214
+ if not same_data:
2215
+ y = ext_func(y, nperseg//2, axis=-1)
2216
+
2217
+ if padded:
2218
+ # Pad to integer number of windowed segments
2219
+ # I.e. make x.shape[-1] = nperseg + (nseg-1)*nstep, with integer nseg
2220
+ nadd = (-(x.shape[-1]-nperseg) % nstep) % nperseg
2221
+ zeros_shape = list(x.shape[:-1]) + [nadd]
2222
+ x = np.concatenate((x, np.zeros(zeros_shape)), axis=-1)
2223
+ if not same_data:
2224
+ zeros_shape = list(y.shape[:-1]) + [nadd]
2225
+ y = np.concatenate((y, np.zeros(zeros_shape)), axis=-1)
2226
+
2227
+ # Handle detrending and window functions
2228
+ if not detrend:
2229
+ def detrend_func(d):
2230
+ return d
2231
+ elif not hasattr(detrend, '__call__'):
2232
+ def detrend_func(d):
2233
+ return _signaltools.detrend(d, type=detrend, axis=-1)
2234
+ elif axis != -1:
2235
+ # Wrap this function so that it receives a shape that it could
2236
+ # reasonably expect to receive.
2237
+ def detrend_func(d):
2238
+ d = np.moveaxis(d, -1, axis)
2239
+ d = detrend(d)
2240
+ return np.moveaxis(d, axis, -1)
2241
+ else:
2242
+ detrend_func = detrend
2243
+
2244
+ if np.result_type(win, np.complex64) != outdtype:
2245
+ win = win.astype(outdtype)
2246
+
2247
+ if scaling == 'density':
2248
+ scale = 1.0 / (fs * (win*win).sum())
2249
+ elif scaling == 'spectrum':
2250
+ scale = 1.0 / win.sum()**2
2251
+ else:
2252
+ raise ValueError(f'Unknown scaling: {scaling!r}')
2253
+
2254
+ if mode == 'stft':
2255
+ scale = np.sqrt(scale)
2256
+
2257
+ if return_onesided:
2258
+ if np.iscomplexobj(x):
2259
+ sides = 'twosided'
2260
+ warnings.warn('Input data is complex, switching to return_onesided=False',
2261
+ stacklevel=3)
2262
+ else:
2263
+ sides = 'onesided'
2264
+ if not same_data:
2265
+ if np.iscomplexobj(y):
2266
+ sides = 'twosided'
2267
+ warnings.warn('Input data is complex, switching to '
2268
+ 'return_onesided=False',
2269
+ stacklevel=3)
2270
+ else:
2271
+ sides = 'twosided'
2272
+
2273
+ if sides == 'twosided':
2274
+ freqs = sp_fft.fftfreq(nfft, 1/fs)
2275
+ elif sides == 'onesided':
2276
+ freqs = sp_fft.rfftfreq(nfft, 1/fs)
2277
+
2278
+ # Perform the windowed FFTs
2279
+ result = _fft_helper(x, win, detrend_func, nperseg, noverlap, nfft, sides)
2280
+
2281
+ if not same_data:
2282
+ # All the same operations on the y data
2283
+ result_y = _fft_helper(y, win, detrend_func, nperseg, noverlap, nfft,
2284
+ sides)
2285
+ result = np.conjugate(result) * result_y
2286
+ elif mode == 'psd':
2287
+ result = np.conjugate(result) * result
2288
+
2289
+ result *= scale
2290
+ if sides == 'onesided' and mode == 'psd':
2291
+ if nfft % 2:
2292
+ result[..., 1:] *= 2
2293
+ else:
2294
+ # Last point is unpaired Nyquist freq point, don't double
2295
+ result[..., 1:-1] *= 2
2296
+
2297
+ time = np.arange(nperseg/2, x.shape[-1] - nperseg/2 + 1,
2298
+ nperseg - noverlap)/float(fs)
2299
+ if boundary is not None:
2300
+ time -= (nperseg/2) / fs
2301
+
2302
+ result = result.astype(outdtype)
2303
+
2304
+ # All imaginary parts are zero anyways
2305
+ if same_data and mode != 'stft':
2306
+ result = result.real
2307
+
2308
+ # Output is going to have new last axis for time/window index, so a
2309
+ # negative axis index shifts down one
2310
+ if axis < 0:
2311
+ axis -= 1
2312
+
2313
+ # Roll frequency axis back to axis where the data came from
2314
+ result = np.moveaxis(result, -1, axis)
2315
+
2316
+ return freqs, time, result
2317
+
2318
+
2319
+ def _fft_helper(x, win, detrend_func, nperseg, noverlap, nfft, sides):
2320
+ """
2321
+ Calculate windowed FFT, for internal use by
2322
+ `scipy.signal._spectral_helper`.
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
+
2329
+ This is a helper function that does the main FFT calculation for
2330
+ `_spectral helper`. All input validation is performed there, and the
2331
+ data axis is assumed to be the last axis of x. It is not designed to
2332
+ be called externally. The windows are not averaged over; the result
2333
+ from each window is returned.
2334
+
2335
+ Returns
2336
+ -------
2337
+ result : ndarray
2338
+ Array of FFT data
2339
+
2340
+ Notes
2341
+ -----
2342
+ Adapted from matplotlib.mlab
2343
+
2344
+ .. versionadded:: 0.16.0
2345
+ """
2346
+ # Created sliding window view of array
2347
+ if nperseg == 1 and noverlap == 0:
2348
+ result = x[..., np.newaxis]
2349
+ else:
2350
+ step = nperseg - noverlap
2351
+ result = np.lib.stride_tricks.sliding_window_view(
2352
+ x, window_shape=nperseg, axis=-1, writeable=True
2353
+ )
2354
+ result = result[..., 0::step, :]
2355
+
2356
+ # Detrend each data segment individually
2357
+ result = detrend_func(result)
2358
+
2359
+ # Apply window by multiplication
2360
+ result = win * result
2361
+
2362
+ # Perform the fft. Acts on last axis by default. Zero-pads automatically
2363
+ if sides == 'twosided':
2364
+ func = sp_fft.fft
2365
+ else:
2366
+ result = result.real
2367
+ func = sp_fft.rfft
2368
+ result = func(result, n=nfft)
2369
+
2370
+ return result
2371
+
2372
+
2373
+ def _triage_segments(window, nperseg, input_length):
2374
+ """
2375
+ Parses window and nperseg arguments for spectrogram and _spectral_helper.
2376
+ This is a helper function, not meant to be called externally.
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
+
2383
+ Parameters
2384
+ ----------
2385
+ window : string, tuple, or ndarray
2386
+ If window is specified by a string or tuple and nperseg is not
2387
+ specified, nperseg is set to the default of 256 and returns a window of
2388
+ that length.
2389
+ If instead the window is array_like and nperseg is not specified, then
2390
+ nperseg is set to the length of the window. A ValueError is raised if
2391
+ the user supplies both an array_like window and a value for nperseg but
2392
+ nperseg does not equal the length of the window.
2393
+
2394
+ nperseg : int
2395
+ Length of each segment
2396
+
2397
+ input_length: int
2398
+ Length of input signal, i.e. x.shape[-1]. Used to test for errors.
2399
+
2400
+ Returns
2401
+ -------
2402
+ win : ndarray
2403
+ window. If function was called with string or tuple than this will hold
2404
+ the actual array used as a window.
2405
+
2406
+ nperseg : int
2407
+ Length of each segment. If window is str or tuple, nperseg is set to
2408
+ 256. If window is array_like, nperseg is set to the length of the
2409
+ window.
2410
+ """
2411
+ # parse window; if array like, then set nperseg = win.shape
2412
+ if isinstance(window, str) or isinstance(window, tuple):
2413
+ # if nperseg not specified
2414
+ if nperseg is None:
2415
+ nperseg = 256 # then change to default
2416
+ if nperseg > input_length:
2417
+ warnings.warn(f'nperseg = {nperseg:d} is greater than input length '
2418
+ f' = {input_length:d}, using nperseg = {input_length:d}',
2419
+ stacklevel=3)
2420
+ nperseg = input_length
2421
+ win = get_window(window, nperseg)
2422
+ else:
2423
+ win = np.asarray(window)
2424
+ if len(win.shape) != 1:
2425
+ raise ValueError('window must be 1-D')
2426
+ if input_length < win.shape[-1]:
2427
+ raise ValueError('window is longer than input signal')
2428
+ if nperseg is None:
2429
+ nperseg = win.shape[0]
2430
+ elif nperseg is not None:
2431
+ if nperseg != win.shape[0]:
2432
+ raise ValueError("value specified for nperseg is different"
2433
+ " from length of window")
2434
+ return win, nperseg
2435
+
2436
+
2437
+ def _median_bias(n):
2438
+ """
2439
+ Returns the bias of the median of a set of periodograms relative to
2440
+ the mean.
2441
+
2442
+ See Appendix B from [1]_ for details.
2443
+
2444
+ Parameters
2445
+ ----------
2446
+ n : int
2447
+ Numbers of periodograms being averaged.
2448
+
2449
+ Returns
2450
+ -------
2451
+ bias : float
2452
+ Calculated bias.
2453
+
2454
+ References
2455
+ ----------
2456
+ .. [1] B. Allen, W.G. Anderson, P.R. Brady, D.A. Brown, J.D.E. Creighton.
2457
+ "FINDCHIRP: an algorithm for detection of gravitational waves from
2458
+ inspiraling compact binaries", Physical Review D 85, 2012,
2459
+ :arxiv:`gr-qc/0509116`
2460
+ """
2461
+ ii_2 = 2 * np.arange(1., (n-1) // 2 + 1)
2462
+ return 1 + np.sum(1. / (ii_2 + 1) - 1. / ii_2)