scipy 1.15.2__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0__cp312-cp312-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (642) 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/__config__.py +5 -5
  5. scipy/__init__.py +3 -6
  6. scipy/_cyutility.cpython-312-darwin.so +0 -0
  7. scipy/_lib/_array_api.py +497 -161
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_bunch.py +4 -0
  10. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  11. scipy/_lib/_docscrape.py +1 -1
  12. scipy/_lib/_elementwise_iterative_method.py +15 -26
  13. scipy/_lib/_sparse.py +41 -0
  14. scipy/_lib/_test_ccallback.cpython-312-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  16. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  17. scipy/_lib/_testutils.py +6 -2
  18. scipy/_lib/_util.py +222 -125
  19. scipy/_lib/array_api_compat/__init__.py +4 -4
  20. scipy/_lib/array_api_compat/_internal.py +19 -6
  21. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  22. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  23. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  24. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  25. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  26. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  27. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  28. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  29. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  30. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  31. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  32. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  33. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  34. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  35. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  36. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  37. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  38. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  39. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  40. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  41. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  42. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  43. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  44. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  45. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  46. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  47. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  48. scipy/_lib/array_api_extra/__init__.py +26 -3
  49. scipy/_lib/array_api_extra/_delegation.py +171 -0
  50. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  51. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  52. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  53. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  54. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  55. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  61. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  62. scipy/_lib/array_api_extra/testing.py +359 -0
  63. scipy/_lib/decorator.py +2 -2
  64. scipy/_lib/doccer.py +1 -7
  65. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  66. scipy/_lib/pyprima/__init__.py +212 -0
  67. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  68. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  69. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  70. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  71. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  72. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  73. scipy/_lib/pyprima/cobyla/update.py +289 -0
  74. scipy/_lib/pyprima/common/__init__.py +0 -0
  75. scipy/_lib/pyprima/common/_bounds.py +34 -0
  76. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  77. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  78. scipy/_lib/pyprima/common/_project.py +173 -0
  79. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  80. scipy/_lib/pyprima/common/consts.py +47 -0
  81. scipy/_lib/pyprima/common/evaluate.py +99 -0
  82. scipy/_lib/pyprima/common/history.py +38 -0
  83. scipy/_lib/pyprima/common/infos.py +30 -0
  84. scipy/_lib/pyprima/common/linalg.py +435 -0
  85. scipy/_lib/pyprima/common/message.py +290 -0
  86. scipy/_lib/pyprima/common/powalg.py +131 -0
  87. scipy/_lib/pyprima/common/preproc.py +277 -0
  88. scipy/_lib/pyprima/common/present.py +5 -0
  89. scipy/_lib/pyprima/common/ratio.py +54 -0
  90. scipy/_lib/pyprima/common/redrho.py +47 -0
  91. scipy/_lib/pyprima/common/selectx.py +296 -0
  92. scipy/_lib/tests/test__util.py +105 -121
  93. scipy/_lib/tests/test_array_api.py +169 -34
  94. scipy/_lib/tests/test_bunch.py +7 -0
  95. scipy/_lib/tests/test_ccallback.py +2 -10
  96. scipy/_lib/tests/test_public_api.py +13 -0
  97. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  98. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  99. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  100. scipy/cluster/hierarchy.py +393 -223
  101. scipy/cluster/tests/test_hierarchy.py +273 -335
  102. scipy/cluster/tests/test_vq.py +45 -61
  103. scipy/cluster/vq.py +39 -35
  104. scipy/conftest.py +282 -151
  105. scipy/constants/_constants.py +4 -1
  106. scipy/constants/tests/test_codata.py +2 -2
  107. scipy/constants/tests/test_constants.py +11 -18
  108. scipy/datasets/_download_all.py +15 -1
  109. scipy/datasets/_fetchers.py +7 -1
  110. scipy/datasets/_utils.py +1 -1
  111. scipy/differentiate/_differentiate.py +25 -25
  112. scipy/differentiate/tests/test_differentiate.py +24 -25
  113. scipy/fft/_basic.py +20 -0
  114. scipy/fft/_helper.py +3 -34
  115. scipy/fft/_pocketfft/helper.py +29 -1
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_ivp/common.py +3 -3
  130. scipy/integrate/_ivp/ivp.py +9 -2
  131. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  132. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  137. scipy/integrate/_quadpack_py.py +11 -7
  138. scipy/integrate/_quadrature.py +3 -3
  139. scipy/integrate/_rules/_base.py +2 -2
  140. scipy/integrate/_tanhsinh.py +57 -54
  141. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  142. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  143. scipy/integrate/tests/test__quad_vec.py +0 -6
  144. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  145. scipy/integrate/tests/test_cubature.py +21 -35
  146. scipy/integrate/tests/test_quadrature.py +6 -8
  147. scipy/integrate/tests/test_tanhsinh.py +61 -43
  148. scipy/interpolate/__init__.py +70 -58
  149. scipy/interpolate/_bary_rational.py +22 -22
  150. scipy/interpolate/_bsplines.py +119 -66
  151. scipy/interpolate/_cubic.py +65 -50
  152. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  153. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  154. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  155. scipy/interpolate/_fitpack2.py +9 -6
  156. scipy/interpolate/_fitpack_impl.py +32 -26
  157. scipy/interpolate/_fitpack_repro.py +23 -19
  158. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  159. scipy/interpolate/_interpolate.py +30 -12
  160. scipy/interpolate/_ndbspline.py +13 -18
  161. scipy/interpolate/_ndgriddata.py +5 -8
  162. scipy/interpolate/_polyint.py +95 -31
  163. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  164. scipy/interpolate/_rbf.py +2 -2
  165. scipy/interpolate/_rbfinterp.py +1 -1
  166. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  167. scipy/interpolate/_rgi.py +31 -26
  168. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  169. scipy/interpolate/dfitpack.py +0 -20
  170. scipy/interpolate/interpnd.py +1 -2
  171. scipy/interpolate/tests/test_bary_rational.py +2 -2
  172. scipy/interpolate/tests/test_bsplines.py +97 -1
  173. scipy/interpolate/tests/test_fitpack2.py +39 -1
  174. scipy/interpolate/tests/test_interpnd.py +32 -20
  175. scipy/interpolate/tests/test_interpolate.py +48 -4
  176. scipy/interpolate/tests/test_rgi.py +2 -1
  177. scipy/io/_fast_matrix_market/__init__.py +2 -0
  178. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  179. scipy/io/_harwell_boeing/hb.py +7 -11
  180. scipy/io/_idl.py +5 -7
  181. scipy/io/_netcdf.py +15 -5
  182. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  183. scipy/io/arff/tests/test_arffread.py +3 -3
  184. scipy/io/matlab/__init__.py +5 -3
  185. scipy/io/matlab/_mio.py +4 -1
  186. scipy/io/matlab/_mio5.py +19 -13
  187. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  188. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  189. scipy/io/matlab/_miobase.py +4 -1
  190. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  191. scipy/io/matlab/tests/test_mio.py +46 -18
  192. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  193. scipy/io/tests/test_mmio.py +7 -1
  194. scipy/io/tests/test_wavfile.py +41 -0
  195. scipy/io/wavfile.py +57 -10
  196. scipy/linalg/_basic.py +113 -86
  197. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp.py +22 -9
  199. scipy/linalg/_decomp_cholesky.py +28 -13
  200. scipy/linalg/_decomp_cossin.py +45 -30
  201. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  202. scipy/linalg/_decomp_ldl.py +4 -1
  203. scipy/linalg/_decomp_lu.py +18 -6
  204. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_decomp_polar.py +2 -0
  206. scipy/linalg/_decomp_qr.py +6 -2
  207. scipy/linalg/_decomp_qz.py +3 -0
  208. scipy/linalg/_decomp_schur.py +3 -1
  209. scipy/linalg/_decomp_svd.py +13 -2
  210. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_expm_frechet.py +4 -0
  212. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  214. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  215. scipy/linalg/_matfuncs.py +187 -4
  216. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  217. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  218. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  219. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  220. scipy/linalg/_procrustes.py +2 -0
  221. scipy/linalg/_sketches.py +17 -6
  222. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  223. scipy/linalg/_solvers.py +7 -2
  224. scipy/linalg/_special_matrices.py +26 -36
  225. scipy/linalg/blas.py +35 -24
  226. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  227. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  228. scipy/linalg/lapack.py +22 -2
  229. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  230. scipy/linalg/tests/test_basic.py +31 -16
  231. scipy/linalg/tests/test_batch.py +588 -0
  232. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  233. scipy/linalg/tests/test_decomp.py +40 -3
  234. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  235. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  236. scipy/linalg/tests/test_interpolative.py +17 -0
  237. scipy/linalg/tests/test_lapack.py +115 -7
  238. scipy/linalg/tests/test_matfuncs.py +157 -102
  239. scipy/linalg/tests/test_procrustes.py +0 -7
  240. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  241. scipy/linalg/tests/test_special_matrices.py +1 -5
  242. scipy/ndimage/__init__.py +1 -0
  243. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  244. scipy/ndimage/_delegators.py +8 -2
  245. scipy/ndimage/_filters.py +453 -5
  246. scipy/ndimage/_interpolation.py +36 -6
  247. scipy/ndimage/_measurements.py +4 -2
  248. scipy/ndimage/_morphology.py +5 -0
  249. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  250. scipy/ndimage/_ndimage_api.py +2 -1
  251. scipy/ndimage/_ni_docstrings.py +5 -1
  252. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  253. scipy/ndimage/_ni_support.py +1 -5
  254. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  255. scipy/ndimage/_support_alternative_backends.py +18 -6
  256. scipy/ndimage/tests/test_filters.py +384 -259
  257. scipy/ndimage/tests/test_fourier.py +7 -9
  258. scipy/ndimage/tests/test_interpolation.py +68 -61
  259. scipy/ndimage/tests/test_measurements.py +18 -35
  260. scipy/ndimage/tests/test_morphology.py +143 -131
  261. scipy/ndimage/tests/test_splines.py +1 -3
  262. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_basinhopping.py +13 -7
  264. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_bracket.py +46 -26
  266. scipy/optimize/_chandrupatla.py +9 -10
  267. scipy/optimize/_cobyla_py.py +104 -123
  268. scipy/optimize/_constraints.py +14 -10
  269. scipy/optimize/_differentiable_functions.py +371 -230
  270. scipy/optimize/_differentialevolution.py +4 -3
  271. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_dual_annealing.py +1 -1
  273. scipy/optimize/_elementwise.py +1 -4
  274. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  276. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  277. scipy/optimize/_lbfgsb_py.py +80 -24
  278. scipy/optimize/_linprog_doc.py +2 -2
  279. scipy/optimize/_linprog_highs.py +11 -11
  280. scipy/optimize/_linprog_ip.py +25 -10
  281. scipy/optimize/_linprog_util.py +18 -19
  282. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_lsq/common.py +3 -3
  284. scipy/optimize/_lsq/dogbox.py +16 -2
  285. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  286. scipy/optimize/_lsq/least_squares.py +198 -126
  287. scipy/optimize/_lsq/lsq_linear.py +6 -6
  288. scipy/optimize/_lsq/trf.py +35 -8
  289. scipy/optimize/_milp.py +3 -1
  290. scipy/optimize/_minimize.py +105 -36
  291. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  292. scipy/optimize/_minpack_py.py +21 -14
  293. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_nnls.py +20 -21
  295. scipy/optimize/_nonlin.py +34 -3
  296. scipy/optimize/_numdiff.py +288 -110
  297. scipy/optimize/_optimize.py +86 -48
  298. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  299. scipy/optimize/_remove_redundancy.py +5 -5
  300. scipy/optimize/_root_scalar.py +1 -1
  301. scipy/optimize/_shgo.py +6 -0
  302. scipy/optimize/_shgo_lib/_complex.py +1 -1
  303. scipy/optimize/_slsqp_py.py +216 -124
  304. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  305. scipy/optimize/_spectral.py +1 -1
  306. scipy/optimize/_tnc.py +8 -1
  307. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_trustregion.py +20 -6
  309. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  310. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  311. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  312. scipy/optimize/_trustregion_constr/projections.py +12 -8
  313. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  314. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  315. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  316. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  317. scipy/optimize/_trustregion_exact.py +0 -1
  318. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  319. scipy/optimize/_zeros_py.py +97 -17
  320. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  321. scipy/optimize/slsqp.py +0 -1
  322. scipy/optimize/tests/test__basinhopping.py +1 -1
  323. scipy/optimize/tests/test__differential_evolution.py +4 -4
  324. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  325. scipy/optimize/tests/test__numdiff.py +66 -22
  326. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  327. scipy/optimize/tests/test__shgo.py +9 -1
  328. scipy/optimize/tests/test_bracket.py +71 -46
  329. scipy/optimize/tests/test_chandrupatla.py +133 -135
  330. scipy/optimize/tests/test_cobyla.py +74 -45
  331. scipy/optimize/tests/test_constraints.py +1 -1
  332. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  333. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  334. scipy/optimize/tests/test_least_squares.py +125 -13
  335. scipy/optimize/tests/test_linear_assignment.py +3 -3
  336. scipy/optimize/tests/test_linprog.py +3 -3
  337. scipy/optimize/tests/test_lsq_linear.py +6 -6
  338. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  339. scipy/optimize/tests/test_minpack.py +4 -4
  340. scipy/optimize/tests/test_nnls.py +43 -3
  341. scipy/optimize/tests/test_nonlin.py +36 -0
  342. scipy/optimize/tests/test_optimize.py +98 -20
  343. scipy/optimize/tests/test_slsqp.py +36 -4
  344. scipy/optimize/tests/test_zeros.py +34 -1
  345. scipy/signal/__init__.py +12 -23
  346. scipy/signal/_delegators.py +568 -0
  347. scipy/signal/_filter_design.py +459 -241
  348. scipy/signal/_fir_filter_design.py +262 -90
  349. scipy/signal/_lti_conversion.py +3 -2
  350. scipy/signal/_ltisys.py +118 -91
  351. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  352. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  353. scipy/signal/_polyutils.py +172 -0
  354. scipy/signal/_short_time_fft.py +553 -76
  355. scipy/signal/_signal_api.py +30 -0
  356. scipy/signal/_signaltools.py +719 -396
  357. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  358. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  359. scipy/signal/_spectral_py.py +230 -50
  360. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  361. scipy/signal/_spline_filters.py +108 -68
  362. scipy/signal/_support_alternative_backends.py +73 -0
  363. scipy/signal/_upfirdn.py +4 -1
  364. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  365. scipy/signal/_waveforms.py +2 -11
  366. scipy/signal/_wavelets.py +1 -1
  367. scipy/signal/fir_filter_design.py +1 -0
  368. scipy/signal/spline.py +4 -11
  369. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  370. scipy/signal/tests/test_bsplines.py +114 -79
  371. scipy/signal/tests/test_cont2discrete.py +9 -2
  372. scipy/signal/tests/test_filter_design.py +721 -481
  373. scipy/signal/tests/test_fir_filter_design.py +332 -140
  374. scipy/signal/tests/test_savitzky_golay.py +4 -3
  375. scipy/signal/tests/test_short_time_fft.py +231 -5
  376. scipy/signal/tests/test_signaltools.py +2150 -1349
  377. scipy/signal/tests/test_spectral.py +50 -6
  378. scipy/signal/tests/test_splines.py +161 -96
  379. scipy/signal/tests/test_upfirdn.py +84 -50
  380. scipy/signal/tests/test_waveforms.py +20 -0
  381. scipy/signal/tests/test_windows.py +607 -466
  382. scipy/signal/windows/_windows.py +287 -148
  383. scipy/sparse/__init__.py +23 -4
  384. scipy/sparse/_base.py +269 -120
  385. scipy/sparse/_bsr.py +7 -4
  386. scipy/sparse/_compressed.py +59 -234
  387. scipy/sparse/_construct.py +90 -38
  388. scipy/sparse/_coo.py +115 -181
  389. scipy/sparse/_csc.py +4 -4
  390. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  391. scipy/sparse/_csr.py +2 -2
  392. scipy/sparse/_data.py +48 -48
  393. scipy/sparse/_dia.py +105 -21
  394. scipy/sparse/_dok.py +0 -23
  395. scipy/sparse/_index.py +4 -4
  396. scipy/sparse/_matrix.py +23 -0
  397. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  398. scipy/sparse/_sputils.py +37 -22
  399. scipy/sparse/base.py +0 -9
  400. scipy/sparse/bsr.py +0 -14
  401. scipy/sparse/compressed.py +0 -23
  402. scipy/sparse/construct.py +0 -6
  403. scipy/sparse/coo.py +0 -14
  404. scipy/sparse/csc.py +0 -3
  405. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  406. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  407. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  408. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  409. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  410. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  411. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  412. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  413. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  414. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  415. scipy/sparse/csr.py +0 -5
  416. scipy/sparse/data.py +1 -6
  417. scipy/sparse/dia.py +0 -7
  418. scipy/sparse/dok.py +0 -10
  419. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  420. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  421. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  422. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  423. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  424. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  425. scipy/sparse/linalg/_expm_multiply.py +8 -3
  426. scipy/sparse/linalg/_interface.py +29 -26
  427. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  428. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  429. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  430. scipy/sparse/linalg/_isolve/minres.py +5 -5
  431. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  432. scipy/sparse/linalg/_isolve/utils.py +2 -8
  433. scipy/sparse/linalg/_matfuncs.py +1 -1
  434. scipy/sparse/linalg/_norm.py +1 -1
  435. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  436. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  437. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  438. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  439. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  440. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  441. scipy/sparse/linalg/tests/test_interface.py +35 -0
  442. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  443. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  444. scipy/sparse/tests/test_base.py +224 -40
  445. scipy/sparse/tests/test_common1d.py +17 -12
  446. scipy/sparse/tests/test_construct.py +1 -1
  447. scipy/sparse/tests/test_coo.py +272 -4
  448. scipy/sparse/tests/test_sparsetools.py +5 -0
  449. scipy/sparse/tests/test_sputils.py +36 -7
  450. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  451. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  452. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  453. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  454. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  455. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  456. scipy/spatial/distance.py +49 -42
  457. scipy/spatial/tests/test_distance.py +15 -1
  458. scipy/spatial/tests/test_kdtree.py +1 -0
  459. scipy/spatial/tests/test_qhull.py +106 -2
  460. scipy/spatial/transform/__init__.py +5 -3
  461. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  462. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  463. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  464. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  465. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  466. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  467. scipy/special/__init__.py +1 -47
  468. scipy/special/_add_newdocs.py +34 -772
  469. scipy/special/_basic.py +22 -25
  470. scipy/special/_comb.cpython-312-darwin.so +0 -0
  471. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  472. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  473. scipy/special/_logsumexp.py +83 -69
  474. scipy/special/_orthogonal.pyi +1 -1
  475. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  476. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  477. scipy/special/_spherical_bessel.py +4 -4
  478. scipy/special/_support_alternative_backends.py +212 -119
  479. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  480. scipy/special/_testutils.py +4 -4
  481. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  482. scipy/special/_ufuncs.pyi +1 -0
  483. scipy/special/_ufuncs.pyx +215 -1400
  484. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  485. scipy/special/_ufuncs_cxx.pxd +2 -15
  486. scipy/special/_ufuncs_cxx.pyx +5 -44
  487. scipy/special/_ufuncs_cxx_defs.h +2 -16
  488. scipy/special/_ufuncs_defs.h +0 -8
  489. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  490. scipy/special/cython_special.pxd +1 -1
  491. scipy/special/tests/_cython_examples/meson.build +10 -1
  492. scipy/special/tests/test_basic.py +153 -20
  493. scipy/special/tests/test_boost_ufuncs.py +3 -0
  494. scipy/special/tests/test_cdflib.py +35 -11
  495. scipy/special/tests/test_gammainc.py +16 -0
  496. scipy/special/tests/test_hyp2f1.py +23 -2
  497. scipy/special/tests/test_log1mexp.py +85 -0
  498. scipy/special/tests/test_logsumexp.py +220 -64
  499. scipy/special/tests/test_mpmath.py +1 -0
  500. scipy/special/tests/test_nan_inputs.py +1 -1
  501. scipy/special/tests/test_orthogonal.py +17 -18
  502. scipy/special/tests/test_sf_error.py +3 -2
  503. scipy/special/tests/test_sph_harm.py +6 -7
  504. scipy/special/tests/test_support_alternative_backends.py +211 -76
  505. scipy/stats/__init__.py +4 -1
  506. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  507. scipy/stats/_axis_nan_policy.py +5 -12
  508. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  509. scipy/stats/_continued_fraction.py +387 -0
  510. scipy/stats/_continuous_distns.py +296 -319
  511. scipy/stats/_correlation.py +1 -1
  512. scipy/stats/_covariance.py +6 -3
  513. scipy/stats/_discrete_distns.py +39 -32
  514. scipy/stats/_distn_infrastructure.py +39 -12
  515. scipy/stats/_distribution_infrastructure.py +920 -238
  516. scipy/stats/_entropy.py +9 -10
  517. scipy/{_lib → stats}/_finite_differences.py +1 -1
  518. scipy/stats/_hypotests.py +83 -50
  519. scipy/stats/_kde.py +53 -49
  520. scipy/stats/_ksstats.py +1 -1
  521. scipy/stats/_levy_stable/__init__.py +7 -15
  522. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  523. scipy/stats/_morestats.py +118 -73
  524. scipy/stats/_mstats_basic.py +13 -17
  525. scipy/stats/_mstats_extras.py +8 -8
  526. scipy/stats/_multivariate.py +89 -113
  527. scipy/stats/_new_distributions.py +97 -20
  528. scipy/stats/_page_trend_test.py +12 -5
  529. scipy/stats/_probability_distribution.py +265 -43
  530. scipy/stats/_qmc.py +14 -9
  531. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  532. scipy/stats/_qmvnt.py +16 -95
  533. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  534. scipy/stats/_quantile.py +335 -0
  535. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  536. scipy/stats/_resampling.py +5 -30
  537. scipy/stats/_sampling.py +1 -1
  538. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  539. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  540. scipy/stats/_stats_mstats_common.py +21 -2
  541. scipy/stats/_stats_py.py +551 -477
  542. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  543. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  544. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  545. scipy/stats/_variation.py +6 -8
  546. scipy/stats/_wilcoxon.py +13 -7
  547. scipy/stats/tests/common_tests.py +6 -4
  548. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  549. scipy/stats/tests/test_continued_fraction.py +173 -0
  550. scipy/stats/tests/test_continuous.py +379 -60
  551. scipy/stats/tests/test_continuous_basic.py +18 -12
  552. scipy/stats/tests/test_discrete_basic.py +14 -8
  553. scipy/stats/tests/test_discrete_distns.py +16 -16
  554. scipy/stats/tests/test_distributions.py +117 -75
  555. scipy/stats/tests/test_entropy.py +40 -48
  556. scipy/stats/tests/test_fit.py +4 -3
  557. scipy/stats/tests/test_hypotests.py +153 -24
  558. scipy/stats/tests/test_kdeoth.py +109 -41
  559. scipy/stats/tests/test_marray.py +289 -0
  560. scipy/stats/tests/test_morestats.py +81 -49
  561. scipy/stats/tests/test_mstats_basic.py +3 -3
  562. scipy/stats/tests/test_multivariate.py +434 -83
  563. scipy/stats/tests/test_qmc.py +13 -10
  564. scipy/stats/tests/test_quantile.py +199 -0
  565. scipy/stats/tests/test_rank.py +119 -112
  566. scipy/stats/tests/test_resampling.py +47 -56
  567. scipy/stats/tests/test_sampling.py +9 -4
  568. scipy/stats/tests/test_stats.py +799 -939
  569. scipy/stats/tests/test_variation.py +8 -6
  570. scipy/version.py +2 -2
  571. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  572. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/METADATA +12 -12
  573. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/RECORD +574 -581
  574. scipy-1.16.0.dist-info/WHEEL +6 -0
  575. scipy/_lib/array_api_extra/_funcs.py +0 -484
  576. scipy/_lib/array_api_extra/_typing.py +0 -8
  577. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  578. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  579. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  580. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  581. scipy/spatial/qhull_src/COPYING.txt +0 -38
  582. scipy/special/libsf_error_state.dylib +0 -0
  583. scipy/special/tests/test_log_softmax.py +0 -109
  584. scipy/special/tests/test_xsf_cuda.py +0 -114
  585. scipy/special/xsf/binom.h +0 -89
  586. scipy/special/xsf/cdflib.h +0 -100
  587. scipy/special/xsf/cephes/airy.h +0 -307
  588. scipy/special/xsf/cephes/besselpoly.h +0 -51
  589. scipy/special/xsf/cephes/beta.h +0 -257
  590. scipy/special/xsf/cephes/cbrt.h +0 -131
  591. scipy/special/xsf/cephes/chbevl.h +0 -85
  592. scipy/special/xsf/cephes/chdtr.h +0 -193
  593. scipy/special/xsf/cephes/const.h +0 -87
  594. scipy/special/xsf/cephes/ellie.h +0 -293
  595. scipy/special/xsf/cephes/ellik.h +0 -251
  596. scipy/special/xsf/cephes/ellpe.h +0 -107
  597. scipy/special/xsf/cephes/ellpk.h +0 -117
  598. scipy/special/xsf/cephes/expn.h +0 -260
  599. scipy/special/xsf/cephes/gamma.h +0 -398
  600. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  601. scipy/special/xsf/cephes/hyperg.h +0 -361
  602. scipy/special/xsf/cephes/i0.h +0 -149
  603. scipy/special/xsf/cephes/i1.h +0 -158
  604. scipy/special/xsf/cephes/igam.h +0 -421
  605. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  606. scipy/special/xsf/cephes/igami.h +0 -313
  607. scipy/special/xsf/cephes/j0.h +0 -225
  608. scipy/special/xsf/cephes/j1.h +0 -198
  609. scipy/special/xsf/cephes/jv.h +0 -715
  610. scipy/special/xsf/cephes/k0.h +0 -164
  611. scipy/special/xsf/cephes/k1.h +0 -163
  612. scipy/special/xsf/cephes/kn.h +0 -243
  613. scipy/special/xsf/cephes/lanczos.h +0 -112
  614. scipy/special/xsf/cephes/ndtr.h +0 -275
  615. scipy/special/xsf/cephes/poch.h +0 -85
  616. scipy/special/xsf/cephes/polevl.h +0 -167
  617. scipy/special/xsf/cephes/psi.h +0 -194
  618. scipy/special/xsf/cephes/rgamma.h +0 -111
  619. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  620. scipy/special/xsf/cephes/shichi.h +0 -248
  621. scipy/special/xsf/cephes/sici.h +0 -224
  622. scipy/special/xsf/cephes/sindg.h +0 -221
  623. scipy/special/xsf/cephes/tandg.h +0 -139
  624. scipy/special/xsf/cephes/trig.h +0 -58
  625. scipy/special/xsf/cephes/unity.h +0 -186
  626. scipy/special/xsf/cephes/zeta.h +0 -172
  627. scipy/special/xsf/config.h +0 -304
  628. scipy/special/xsf/digamma.h +0 -205
  629. scipy/special/xsf/error.h +0 -57
  630. scipy/special/xsf/evalpoly.h +0 -47
  631. scipy/special/xsf/expint.h +0 -266
  632. scipy/special/xsf/hyp2f1.h +0 -694
  633. scipy/special/xsf/iv_ratio.h +0 -173
  634. scipy/special/xsf/lambertw.h +0 -150
  635. scipy/special/xsf/loggamma.h +0 -163
  636. scipy/special/xsf/sici.h +0 -200
  637. scipy/special/xsf/tools.h +0 -427
  638. scipy/special/xsf/trig.h +0 -164
  639. scipy/special/xsf/wright_bessel.h +0 -843
  640. scipy/special/xsf/zlog1.h +0 -35
  641. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  642. scipy-1.15.2.dist-info/WHEEL +0 -4
@@ -24,11 +24,10 @@ import numpy as np
24
24
  from numpy.testing import assert_allclose
25
25
 
26
26
  from scipy.signal import ShortTimeFFT
27
- from scipy.signal import csd, get_window, stft, istft
27
+ from scipy.signal import get_window, stft, istft
28
28
  from scipy.signal._arraytools import const_ext, even_ext, odd_ext, zero_ext
29
29
  from scipy.signal._short_time_fft import FFT_MODE_TYPE
30
- from scipy.signal._spectral_py import _spectral_helper, _triage_segments, \
31
- _median_bias
30
+ from scipy.signal._spectral_py import _triage_segments
32
31
 
33
32
 
34
33
  def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
@@ -103,7 +102,7 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
103
102
  # This is an edge case where shortTimeFFT returns one more time slice
104
103
  # than the Scipy stft() shorten to remove last time slice:
105
104
  if n % 2 == 1 and nperseg % 2 == 1 and noverlap % 2 == 1:
106
- x = x[..., :axis - 1]
105
+ x = x[..., : -1]
107
106
 
108
107
  nadd = (-(x.shape[-1]-nperseg) % nstep) % nperseg
109
108
  zeros_shape = list(x.shape[:-1]) + [nadd]
@@ -124,11 +123,8 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
124
123
  k_off = nperseg // 2
125
124
  p0 = 0 # ST.lower_border_end[1] + 1
126
125
  nn = x.shape[axis] if padded else n+k_off+1
127
- p1 = ST.upper_border_begin(nn)[1] # ST.p_max(n) + 1
128
-
129
- # This is bad hack to pass the test test_roundtrip_boundary_extension():
130
- if padded is True and nperseg - noverlap == 1:
131
- p1 -= nperseg // 2 - 1 # the reasoning behind this is not clear to me
126
+ # number of frames akin to legacy stft computation
127
+ p1 = (x.shape[axis] - nperseg) // nstep + 1
132
128
 
133
129
  detr = None if detrend is False else detrend
134
130
  Sxx = ST.stft_detrend(x, detr, p0, p1, k_offset=k_off, axis=axis)
@@ -136,11 +132,6 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
136
132
  if x.dtype in (np.float32, np.complex64):
137
133
  Sxx = Sxx.astype(np.complex64)
138
134
 
139
- # workaround for test_average_all_segments() - seems to be buggy behavior:
140
- if boundary is None and padded is False:
141
- t, Sxx = t[1:-1], Sxx[..., :-2]
142
- t -= k_off / fs
143
-
144
135
  return ST.f, t, Sxx
145
136
 
146
137
 
@@ -234,156 +225,6 @@ def _istft_wrapper(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None,
234
225
  return t, x, (ST.lower_border_end[0], k_hi)
235
226
 
236
227
 
237
- def _csd_wrapper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
238
- nfft=None, detrend='constant', return_onesided=True,
239
- scaling='density', axis=-1, average='mean'):
240
- """Wrapper for the `csd()` function based on `ShortTimeFFT` for
241
- unit testing.
242
- """
243
- freqs, _, Pxy = _csd_test_shim(x, y, fs, window, nperseg, noverlap, nfft,
244
- detrend, return_onesided, scaling, axis)
245
-
246
- # The following code is taken from csd():
247
- if len(Pxy.shape) >= 2 and Pxy.size > 0:
248
- if Pxy.shape[-1] > 1:
249
- if average == 'median':
250
- # np.median must be passed real arrays for the desired result
251
- bias = _median_bias(Pxy.shape[-1])
252
- if np.iscomplexobj(Pxy):
253
- Pxy = (np.median(np.real(Pxy), axis=-1)
254
- + 1j * np.median(np.imag(Pxy), axis=-1))
255
- else:
256
- Pxy = np.median(Pxy, axis=-1)
257
- Pxy /= bias
258
- elif average == 'mean':
259
- Pxy = Pxy.mean(axis=-1)
260
- else:
261
- raise ValueError(f'average must be "median" or "mean", got {average}')
262
- else:
263
- Pxy = np.reshape(Pxy, Pxy.shape[:-1])
264
-
265
- return freqs, Pxy
266
-
267
-
268
- def _csd_test_shim(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
269
- nfft=None, detrend='constant', return_onesided=True,
270
- scaling='density', axis=-1):
271
- """Compare output of _spectral_helper() and ShortTimeFFT, more
272
- precisely _spect_helper_csd() for used in csd_wrapper().
273
-
274
- The motivation of this function is to test if the ShortTimeFFT-based
275
- wrapper `_spect_helper_csd()` returns the same values as `_spectral_helper`.
276
- This function should only be usd by csd() in (unit) testing.
277
- """
278
- freqs, t, Pxy = _spectral_helper(x, y, fs, window, nperseg, noverlap, nfft,
279
- detrend, return_onesided, scaling, axis,
280
- mode='psd')
281
- freqs1, Pxy1 = _spect_helper_csd(x, y, fs, window, nperseg, noverlap, nfft,
282
- detrend, return_onesided, scaling, axis)
283
-
284
- np.testing.assert_allclose(freqs1, freqs)
285
- amax_Pxy = max(np.abs(Pxy).max(), 1) if Pxy.size else 1
286
- atol = np.finfo(Pxy.dtype).resolution * amax_Pxy # needed for large Pxy
287
- # for c_ in range(Pxy.shape[-1]):
288
- # np.testing.assert_allclose(Pxy1[:, c_], Pxy[:, c_], atol=atol)
289
- np.testing.assert_allclose(Pxy1, Pxy, atol=atol)
290
- return freqs, t, Pxy
291
-
292
-
293
- def _spect_helper_csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
294
- nfft=None, detrend='constant', return_onesided=True,
295
- scaling='density', axis=-1):
296
- """Wrapper for replacing _spectral_helper() by using the ShortTimeFFT
297
- for use by csd().
298
-
299
- This function should be only used by _csd_test_shim() and is only useful
300
- for testing the ShortTimeFFT implementation.
301
- """
302
-
303
- # The following lines are taken from the original _spectral_helper():
304
- same_data = y is x
305
- axis = int(axis)
306
-
307
- # Ensure we have np.arrays, get outdtype
308
- x = np.asarray(x)
309
- if not same_data:
310
- y = np.asarray(y)
311
- # outdtype = np.result_type(x, y, np.complex64)
312
- # else:
313
- # outdtype = np.result_type(x, np.complex64)
314
-
315
- if not same_data:
316
- # Check if we can broadcast the outer axes together
317
- xouter = list(x.shape)
318
- youter = list(y.shape)
319
- xouter.pop(axis)
320
- youter.pop(axis)
321
- try:
322
- outershape = np.broadcast(np.empty(xouter), np.empty(youter)).shape
323
- except ValueError as e:
324
- raise ValueError('x and y cannot be broadcast together.') from e
325
-
326
- if same_data:
327
- if x.size == 0:
328
- return np.empty(x.shape), np.empty(x.shape)
329
- else:
330
- if x.size == 0 or y.size == 0:
331
- outshape = outershape + (min([x.shape[axis], y.shape[axis]]),)
332
- emptyout = np.moveaxis(np.empty(outshape), -1, axis)
333
- return emptyout, emptyout
334
-
335
- if nperseg is not None: # if specified by user
336
- nperseg = int(nperseg)
337
- if nperseg < 1:
338
- raise ValueError('nperseg must be a positive integer')
339
-
340
- # parse window; if array like, then set nperseg = win.shape
341
- n = x.shape[axis] if same_data else max(x.shape[axis], y.shape[axis])
342
- win, nperseg = _triage_segments(window, nperseg, input_length=n)
343
-
344
- if nfft is None:
345
- nfft = nperseg
346
- elif nfft < nperseg:
347
- raise ValueError('nfft must be greater than or equal to nperseg.')
348
- else:
349
- nfft = int(nfft)
350
-
351
- if noverlap is None:
352
- noverlap = nperseg // 2
353
- else:
354
- noverlap = int(noverlap)
355
- if noverlap >= nperseg:
356
- raise ValueError('noverlap must be less than nperseg.')
357
- nstep = nperseg - noverlap
358
-
359
- if np.iscomplexobj(x) and return_onesided:
360
- return_onesided = False
361
-
362
- # using cast() to make mypy happy:
363
- fft_mode = cast(FFT_MODE_TYPE, 'onesided' if return_onesided
364
- else 'twosided')
365
- scale = {'spectrum': 'magnitude', 'density': 'psd'}[scaling]
366
- SFT = ShortTimeFFT(win, nstep, fs, fft_mode=fft_mode, mfft=nfft,
367
- scale_to=scale, phase_shift=None)
368
-
369
- # _spectral_helper() calculates X.conj()*Y instead of X*Y.conj():
370
- Pxy = SFT.spectrogram(y, x, detr=None if detrend is False else detrend,
371
- p0=0, p1=(n-noverlap)//SFT.hop, k_offset=nperseg//2,
372
- axis=axis).conj()
373
- # Note:
374
- # 'onesided2X' scaling of ShortTimeFFT conflicts with the
375
- # scaling='spectrum' parameter, since it doubles the squared magnitude,
376
- # which in the view of the ShortTimeFFT implementation does not make sense.
377
- # Hence, the doubling of the square is implemented here:
378
- if return_onesided:
379
- f_axis = Pxy.ndim - 1 + axis if axis < 0 else axis
380
- Pxy = np.moveaxis(Pxy, f_axis, -1)
381
- Pxy[..., 1:-1 if SFT.mfft % 2 == 0 else None] *= 2
382
- Pxy = np.moveaxis(Pxy, -1, f_axis)
383
-
384
- return SFT.f, Pxy
385
-
386
-
387
228
  def stft_compare(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
388
229
  nfft=None, detrend=False, return_onesided=True,
389
230
  boundary='zeros', padded=True, axis=-1, scaling='spectrum'):
@@ -468,21 +309,3 @@ def istft_compare(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None,
468
309
  assert_allclose(x_wrapper[k_lo:k_hi], x[k_lo:k_hi], atol=atol, rtol=rtol,
469
310
  err_msg=f"Signal values {e_msg_part}")
470
311
  return t, x
471
-
472
-
473
- def csd_compare(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
474
- nfft=None, detrend='constant', return_onesided=True,
475
- scaling='density', axis=-1, average='mean'):
476
- """Assert that the results from the existing `csd()` and `_csd_wrapper()`
477
- are close to each other. """
478
- kw = dict(x=x, y=y, fs=fs, window=window, nperseg=nperseg,
479
- noverlap=noverlap, nfft=nfft, detrend=detrend,
480
- return_onesided=return_onesided, scaling=scaling, axis=axis,
481
- average=average)
482
- freqs0, Pxy0 = csd(**kw)
483
- freqs1, Pxy1 = _csd_wrapper(**kw)
484
-
485
- assert_allclose(freqs1, freqs0)
486
- assert_allclose(Pxy1, Pxy0)
487
- assert_allclose(freqs1, freqs0)
488
- return freqs0, Pxy0
@@ -1,4 +1,5 @@
1
1
  # pylint: disable=missing-docstring
2
+ import math
2
3
  import numpy as np
3
4
 
4
5
  from scipy._lib._array_api import (
@@ -7,9 +8,11 @@ from scipy._lib._array_api import (
7
8
  import pytest
8
9
  from pytest import raises
9
10
 
10
- import scipy.signal._spline_filters as bsp
11
11
  from scipy import signal
12
12
 
13
+ skip_xp_backends = pytest.mark.skip_xp_backends
14
+ xfail_xp_backends = pytest.mark.xfail_xp_backends
15
+
13
16
 
14
17
  class TestBSplines:
15
18
  """Test behaviors of B-splines. Some of the values tested against were
@@ -17,15 +20,17 @@ class TestBSplines:
17
20
  purposes. Others (at integer points) are compared to theoretical
18
21
  expressions (cf. Unser, Aldroubi, Eden, IEEE TSP 1993, Table 1)."""
19
22
 
20
- def test_spline_filter(self):
23
+ @skip_xp_backends(cpu_only=True, exceptions=["cupy"])
24
+ def test_spline_filter(self, xp):
21
25
  rng = np.random.RandomState(12457)
22
26
  # Test the type-error branch
23
- raises(TypeError, bsp.spline_filter, np.asarray([0]), 0)
27
+ raises(TypeError, signal.spline_filter, xp.asarray([0]), 0)
24
28
  # Test the real branch
25
29
  data_array_real = rng.rand(12, 12)
26
30
  # make the magnitude exceed 1, and make some negative
27
31
  data_array_real = 10*(1-2*data_array_real)
28
- result_array_real = np.asarray(
32
+ data_array_real = xp.asarray(data_array_real)
33
+ result_array_real = xp.asarray(
29
34
  [[-.463312621, 8.33391222, .697290949, 5.28390836,
30
35
  5.92066474, 6.59452137, 9.84406950, -8.78324188,
31
36
  7.20675750, -8.17222994, -4.38633345, 9.89917069],
@@ -61,16 +66,19 @@ class TestBSplines:
61
66
  -3.77114594, -1.11903194, -5.39151466, 3.06620093],
62
67
  [9.86326886, 1.05134482, -7.75950607, -3.64429655,
63
68
  7.81848957, -9.02270373, 3.73399754, -4.71962549,
64
- -7.71144306, 3.78263161, 6.46034818, -4.43444731]])
65
- xp_assert_close(bsp.spline_filter(data_array_real, 0),
69
+ -7.71144306, 3.78263161, 6.46034818, -4.43444731]], dtype=xp.float64)
70
+ xp_assert_close(signal.spline_filter(data_array_real, 0),
66
71
  result_array_real)
67
72
 
68
- def test_spline_filter_complex(self):
73
+ @skip_xp_backends(cpu_only=True, exceptions=["cupy"])
74
+ def test_spline_filter_complex(self, xp):
69
75
  rng = np.random.RandomState(12457)
70
76
  data_array_complex = rng.rand(7, 7) + rng.rand(7, 7)*1j
71
77
  # make the magnitude exceed 1, and make some negative
72
78
  data_array_complex = 10*(1+1j-2*data_array_complex)
73
- result_array_complex = np.asarray(
79
+ data_array_complex = xp.asarray(data_array_complex)
80
+
81
+ result_array_complex = xp.asarray(
74
82
  [[-4.61489230e-01-1.92994022j, 8.33332443+6.25519943j,
75
83
  6.96300745e-01-9.05576038j, 5.28294849+3.97541356j,
76
84
  5.92165565+7.68240595j, 6.59493160-1.04542804j,
@@ -98,99 +106,120 @@ class TestBSplines:
98
106
  [7.13875294+2.91851187j, -5.35737514+9.64132309j,
99
107
  -9.66586399+0.70250005j, -9.87717438-2.0262239j,
100
108
  9.93160629+1.5630846j, 4.71948051-2.22050714j,
101
- 9.49550819+7.8995142j]])
109
+ 9.49550819+7.8995142j]], dtype=xp.complex128)
102
110
  # FIXME: for complex types, the computations are done in
103
111
  # single precision (reason unclear). When this is changed,
104
112
  # this test needs updating.
105
- xp_assert_close(bsp.spline_filter(data_array_complex, 0),
113
+ xp_assert_close(signal.spline_filter(data_array_complex, 0),
106
114
  result_array_complex, rtol=1e-6)
107
115
 
108
- def test_gauss_spline(self):
109
- np.random.seed(12459)
110
- assert_almost_equal(bsp.gauss_spline(0, 0), 1.381976597885342)
111
- xp_assert_close(bsp.gauss_spline(np.asarray([1.]), 1),
112
- np.asarray([0.04865217]), atol=1e-9
116
+ def test_gauss_spline(self, xp):
117
+ assert math.isclose(signal.gauss_spline(0, 0), 1.381976597885342)
118
+
119
+ xp_assert_close(signal.gauss_spline(xp.asarray([1.]), 1),
120
+ xp.asarray([0.04865217]), atol=1e-9
113
121
  )
114
122
 
115
- def test_gauss_spline_list(self):
123
+ @skip_xp_backends(np_only=True, reason="deliberate: array-likes are accepted")
124
+ def test_gauss_spline_list(self, xp):
116
125
  # regression test for gh-12152 (accept array_like)
117
126
  knots = [-1.0, 0.0, -1.0]
118
- assert_almost_equal(bsp.gauss_spline(knots, 3),
127
+ assert_almost_equal(signal.gauss_spline(knots, 3),
119
128
  np.asarray([0.15418033, 0.6909883, 0.15418033])
120
129
  )
121
130
 
122
- def test_cspline1d(self):
123
- np.random.seed(12462)
124
- xp_assert_equal(bsp.cspline1d(np.asarray([0])), [0.])
125
- c1d = np.asarray([1.21037185, 1.86293902, 2.98834059, 4.11660378,
126
- 4.78893826])
131
+ @skip_xp_backends(cpu_only=True)
132
+ def test_cspline1d(self, xp):
133
+ xp_assert_equal(signal.cspline1d(xp.asarray([0])),
134
+ xp.asarray([0.], dtype=xp.float64))
135
+ c1d = xp.asarray([1.21037185, 1.86293902, 2.98834059, 4.11660378,
136
+ 4.78893826], dtype=xp.float64)
127
137
  # test lamda != 0
128
- xp_assert_close(bsp.cspline1d(np.asarray([1., 2, 3, 4, 5]), 1), c1d)
129
- c1d0 = np.asarray([0.78683946, 2.05333735, 2.99981113, 3.94741812,
130
- 5.21051638])
131
- xp_assert_close(bsp.cspline1d(np.asarray([1., 2, 3, 4, 5])), c1d0)
132
-
133
- def test_qspline1d(self):
134
- np.random.seed(12463)
135
- xp_assert_equal(bsp.qspline1d(np.asarray([0])), [0.])
138
+ xp_assert_close(signal.cspline1d(xp.asarray([1., 2, 3, 4, 5]), 1), c1d)
139
+ c1d0 = xp.asarray([0.78683946, 2.05333735, 2.99981113, 3.94741812,
140
+ 5.21051638], dtype=xp.float64)
141
+ xp_assert_close(signal.cspline1d(xp.asarray([1., 2, 3, 4, 5])), c1d0)
142
+
143
+ @skip_xp_backends(cpu_only=True)
144
+ def test_qspline1d(self, xp):
145
+ xp_assert_equal(signal.qspline1d(xp.asarray([0])),
146
+ xp.asarray([0.], dtype=xp.float64))
136
147
  # test lamda != 0
137
- raises(ValueError, bsp.qspline1d, np.asarray([1., 2, 3, 4, 5]), 1.)
138
- raises(ValueError, bsp.qspline1d, np.asarray([1., 2, 3, 4, 5]), -1.)
139
- q1d0 = np.asarray([0.85350007, 2.02441743, 2.99999534, 3.97561055,
140
- 5.14634135])
141
- xp_assert_close(bsp.qspline1d(np.asarray([1., 2, 3, 4, 5])), q1d0)
142
-
143
- def test_cspline1d_eval(self):
144
- np.random.seed(12464)
145
- xp_assert_close(bsp.cspline1d_eval(np.asarray([0., 0]), [0.]),
146
- np.asarray([0.])
147
- )
148
- xp_assert_equal(bsp.cspline1d_eval(np.asarray([1., 0, 1]), []),
149
- np.asarray([])
148
+ raises(ValueError, signal.qspline1d, xp.asarray([1., 2, 3, 4, 5]), 1.)
149
+ raises(ValueError, signal.qspline1d, xp.asarray([1., 2, 3, 4, 5]), -1.)
150
+ q1d0 = xp.asarray([0.85350007, 2.02441743, 2.99999534, 3.97561055,
151
+ 5.14634135], dtype=xp.float64)
152
+ xp_assert_close(
153
+ signal.qspline1d(xp.asarray([1., 2, 3, 4, 5], dtype=xp.float64)), q1d0
150
154
  )
155
+
156
+ @skip_xp_backends(cpu_only=True)
157
+ def test_cspline1d_eval(self, xp):
158
+ r = signal.cspline1d_eval(xp.asarray([0., 0], dtype=xp.float64),
159
+ xp.asarray([0.], dtype=xp.float64))
160
+ xp_assert_close(r, xp.asarray([0.], dtype=xp.float64))
161
+
162
+ r = signal.cspline1d_eval(xp.asarray([1., 0, 1], dtype=xp.float64),
163
+ xp.asarray([], dtype=xp.float64))
164
+ xp_assert_equal(r, xp.asarray([], dtype=xp.float64))
151
165
  x = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
152
166
  dx = x[1] - x[0]
153
167
  newx = [-6., -5.5, -5., -4.5, -4., -3.5, -3., -2.5, -2., -1.5, -1.,
154
168
  -0.5, 0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5, 5., 5.5, 6.,
155
169
  6.5, 7., 7.5, 8., 8.5, 9., 9.5, 10., 10.5, 11., 11.5, 12.,
156
170
  12.5]
157
- y = np.asarray([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
171
+ y = xp.asarray([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
158
172
  1.396, 4.094])
159
- cj = bsp.cspline1d(y)
160
- newy = np.asarray([6.203, 4.41570658, 3.514, 5.16924703, 6.864, 6.04643068,
173
+ cj = signal.cspline1d(y)
174
+ newy = xp.asarray([6.203, 4.41570658, 3.514, 5.16924703, 6.864, 6.04643068,
161
175
  4.21600281, 6.04643068, 6.864, 5.16924703, 3.514,
162
176
  4.41570658, 6.203, 6.80717667, 6.759, 6.98971173, 7.433,
163
177
  7.79560142, 7.874, 7.41525761, 5.879, 3.18686814, 1.396,
164
178
  2.24889482, 4.094, 2.24889482, 1.396, 3.18686814, 5.879,
165
179
  7.41525761, 7.874, 7.79560142, 7.433, 6.98971173, 6.759,
166
- 6.80717667, 6.203, 4.41570658])
167
- xp_assert_close(bsp.cspline1d_eval(cj, newx, dx=dx, x0=x[0]), newy)
180
+ 6.80717667, 6.203, 4.41570658], dtype=xp.float64)
181
+ xp_assert_close(
182
+ signal.cspline1d_eval(cj, xp.asarray(newx), dx=dx, x0=x[0]), newy
183
+ )
184
+
185
+ with pytest.raises(ValueError,
186
+ match="Spline coefficients 'cj' must not be empty."):
187
+ signal.cspline1d_eval(xp.asarray([], dtype=xp.float64),
188
+ xp.asarray([0.0], dtype=xp.float64))
168
189
 
169
- def test_qspline1d_eval(self):
170
- np.random.seed(12465)
171
- xp_assert_close(bsp.qspline1d_eval(np.asarray([0., 0]), [0.]),
172
- np.asarray([0.])
190
+ @skip_xp_backends(cpu_only=True)
191
+ def test_qspline1d_eval(self, xp):
192
+ xp_assert_close(signal.qspline1d_eval(xp.asarray([0., 0]), xp.asarray([0.])),
193
+ xp.asarray([0.])
173
194
  )
174
- xp_assert_equal(bsp.qspline1d_eval(np.asarray([1., 0, 1]), []),
175
- np.asarray([])
195
+ xp_assert_equal(signal.qspline1d_eval(xp.asarray([1., 0, 1]), xp.asarray([])),
196
+ xp.asarray([])
176
197
  )
177
198
  x = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
178
- dx = x[1]-x[0]
199
+ dx = x[1] - x[0]
179
200
  newx = [-6., -5.5, -5., -4.5, -4., -3.5, -3., -2.5, -2., -1.5, -1.,
180
201
  -0.5, 0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5, 5., 5.5, 6.,
181
202
  6.5, 7., 7.5, 8., 8.5, 9., 9.5, 10., 10.5, 11., 11.5, 12.,
182
203
  12.5]
183
- y = np.asarray([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
204
+ y = xp.asarray([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
184
205
  1.396, 4.094])
185
- cj = bsp.qspline1d(y)
186
- newy = np.asarray([6.203, 4.49418159, 3.514, 5.18390821, 6.864, 5.91436915,
206
+ cj = signal.qspline1d(y)
207
+ newy = xp.asarray([6.203, 4.49418159, 3.514, 5.18390821, 6.864, 5.91436915,
187
208
  4.21600002, 5.91436915, 6.864, 5.18390821, 3.514,
188
209
  4.49418159, 6.203, 6.71900226, 6.759, 7.03980488, 7.433,
189
210
  7.81016848, 7.874, 7.32718426, 5.879, 3.23872593, 1.396,
190
211
  2.34046013, 4.094, 2.34046013, 1.396, 3.23872593, 5.879,
191
212
  7.32718426, 7.874, 7.81016848, 7.433, 7.03980488, 6.759,
192
- 6.71900226, 6.203, 4.49418159])
193
- xp_assert_close(bsp.qspline1d_eval(cj, newx, dx=dx, x0=x[0]), newy)
213
+ 6.71900226, 6.203, 4.49418159], dtype=xp.float64)
214
+ r = signal.qspline1d_eval(
215
+ cj, xp.asarray(newx, dtype=xp.float64), dx=dx, x0=x[0]
216
+ )
217
+ xp_assert_close(r, newy)
218
+
219
+ with pytest.raises(ValueError,
220
+ match="Spline coefficients 'cj' must not be empty."):
221
+ signal.qspline1d_eval(xp.asarray([], dtype=xp.float64),
222
+ xp.asarray([0.0], dtype=xp.float64))
194
223
 
195
224
 
196
225
  # i/o dtypes with scipy 1.9.1, likely fixed by backwards compat
@@ -198,10 +227,13 @@ sepfir_dtype_map = {np.uint8: np.float32, int: np.float64,
198
227
  np.float32: np.float32, float: float,
199
228
  np.complex64: np.complex64, complex: complex}
200
229
 
230
+
231
+ @skip_xp_backends(np_only=True)
201
232
  class TestSepfir2d:
202
- def test_sepfir2d_invalid_filter(self):
203
- filt = np.array([1.0, 2.0, 4.0, 2.0, 1.0])
233
+ def test_sepfir2d_invalid_filter(self, xp):
234
+ filt = xp.asarray([1.0, 2.0, 4.0, 2.0, 1.0])
204
235
  image = np.random.rand(7, 9)
236
+ image = xp.asarray(image)
205
237
  # No error for odd lengths
206
238
  signal.sepfir2d(image, filt, filt[2:])
207
239
 
@@ -213,25 +245,26 @@ class TestSepfir2d:
213
245
 
214
246
  # Filters must be 1-dimensional
215
247
  with pytest.raises(ValueError, match="object too deep"):
216
- signal.sepfir2d(image, filt.reshape(1, -1), filt)
248
+ signal.sepfir2d(image, xp.reshape(filt, (1, -1)), filt)
217
249
  with pytest.raises(ValueError, match="object too deep"):
218
- signal.sepfir2d(image, filt, filt.reshape(1, -1))
250
+ signal.sepfir2d(image, filt, xp.reshape(filt, (1, -1)))
219
251
 
220
- def test_sepfir2d_invalid_image(self):
221
- filt = np.array([1.0, 2.0, 4.0, 2.0, 1.0])
252
+ def test_sepfir2d_invalid_image(self, xp):
253
+ filt = xp.asarray([1.0, 2.0, 4.0, 2.0, 1.0])
222
254
  image = np.random.rand(8, 8)
255
+ image = xp.asarray(image)
223
256
 
224
257
  # Image must be 2 dimensional
225
258
  with pytest.raises(ValueError, match="object too deep"):
226
- signal.sepfir2d(image.reshape(4, 4, 4), filt, filt)
259
+ signal.sepfir2d(xp.reshape(image, (4, 4, 4)), filt, filt)
227
260
 
228
261
  with pytest.raises(ValueError, match="object of too small depth"):
229
- signal.sepfir2d(image[0], filt, filt)
262
+ signal.sepfir2d(image[0, :], filt, filt)
230
263
 
231
264
  @pytest.mark.parametrize('dtyp',
232
265
  [np.uint8, int, np.float32, float, np.complex64, complex]
233
266
  )
234
- def test_simple(self, dtyp):
267
+ def test_simple(self, dtyp, xp):
235
268
  # test values on a paper-and-pencil example
236
269
  a = np.array([[1, 2, 3, 3, 2, 1],
237
270
  [1, 2, 3, 3, 2, 1],
@@ -254,10 +287,11 @@ class TestSepfir2d:
254
287
  [2., 4., 6., 6., 4., 2.]], dtype=dt)
255
288
  xp_assert_close(result, expected, atol=1e-16)
256
289
 
290
+ @skip_xp_backends(np_only=True, reason="TODO: convert this test")
257
291
  @pytest.mark.parametrize('dtyp',
258
292
  [np.uint8, int, np.float32, float, np.complex64, complex]
259
293
  )
260
- def test_strided(self, dtyp):
294
+ def test_strided(self, dtyp, xp):
261
295
  a = np.array([[1, 2, 3, 3, 2, 1, 1, 2, 3],
262
296
  [1, 2, 3, 3, 2, 1, 1, 2, 3],
263
297
  [1, 2, 3, 3, 2, 1, 1, 2, 3],
@@ -268,11 +302,11 @@ class TestSepfir2d:
268
302
  xp_assert_close(result_strided, result_contig, atol=1e-15)
269
303
  assert result_strided.dtype == result_contig.dtype
270
304
 
305
+ @skip_xp_backends(np_only=True, reason="TODO: convert this test")
271
306
  @pytest.mark.xfail(reason="XXX: filt.size > image.shape: flaky")
272
- def test_sepfir2d_strided_2(self):
307
+ def test_sepfir2d_strided_2(self, xp):
273
308
  # XXX: this test is flaky: fails on some reruns, with
274
309
  # result[0, 1] and result[1, 1] being ~1e+224.
275
- np.random.seed(1234)
276
310
  filt = np.array([1.0, 2.0, 4.0, 2.0, 1.0, 3.0, 2.0])
277
311
  image = np.random.rand(4, 4)
278
312
 
@@ -282,11 +316,12 @@ class TestSepfir2d:
282
316
  [49.120928, 39.681844, 43.596067, 45.085854]])
283
317
  xp_assert_close(signal.sepfir2d(image, filt, filt[::3]), expected)
284
318
 
319
+ @skip_xp_backends(np_only=True, reason="TODO: convert this test")
285
320
  @pytest.mark.xfail(reason="XXX: flaky. pointers OOB on some platforms")
286
321
  @pytest.mark.parametrize('dtyp',
287
322
  [np.uint8, int, np.float32, float, np.complex64, complex]
288
323
  )
289
- def test_sepfir2d_strided_3(self, dtyp):
324
+ def test_sepfir2d_strided_3(self, dtyp, xp):
290
325
  # NB: 'image' and 'filt' dtypes match here. Otherwise we can run into
291
326
  # unsafe casting errors for many combinations. Historically, dtype handling
292
327
  # in `sepfir2d` is a tad baroque; fixing it is an enhancement.
@@ -318,13 +353,13 @@ class TestSepfir2d:
318
353
  assert result.dtype == sepfir_dtype_map[dtyp]
319
354
 
320
355
 
321
- def test_cspline2d():
322
- np.random.seed(181819142)
323
- image = np.random.rand(71, 73)
356
+ def test_cspline2d(xp):
357
+ rng = np.random.RandomState(181819142)
358
+ image = rng.rand(71, 73)
324
359
  signal.cspline2d(image, 8.0)
325
360
 
326
361
 
327
- def test_qspline2d():
328
- np.random.seed(181819143)
329
- image = np.random.rand(71, 73)
362
+ def test_qspline2d(xp):
363
+ rng = np.random.RandomState(181819143)
364
+ image = rng.rand(71, 73)
330
365
  signal.qspline2d(image)
@@ -13,7 +13,6 @@ from scipy.signal import tf2ss, impulse, dimpulse, step, dstep
13
13
 
14
14
 
15
15
  class TestC2D:
16
- @pytest.mark.thread_unsafe # due to Cython fused types, see cython#6506
17
16
  def test_zoh(self):
18
17
  ac = np.eye(2, dtype=np.float64)
19
18
  bc = np.full((2, 1), 0.5, dtype=np.float64)
@@ -354,19 +353,27 @@ class TestC2dLti:
354
353
  B = np.array([[0], [1]])
355
354
  C = np.array([[1, 0]])
356
355
  D = 0
356
+ dt = 0.05
357
357
 
358
358
  A_res = np.array([[0.985136404135682, 0.004876671474795],
359
359
  [0.009753342949590, 0.965629718236502]])
360
360
  B_res = np.array([[0.000122937599964], [0.049135527547844]])
361
361
 
362
362
  sys_ssc = lti(A, B, C, D)
363
- sys_ssd = sys_ssc.to_discrete(0.05)
363
+ sys_ssd = sys_ssc.to_discrete(dt=dt)
364
364
 
365
365
  xp_assert_close(sys_ssd.A, A_res)
366
366
  xp_assert_close(sys_ssd.B, B_res)
367
367
  xp_assert_close(sys_ssd.C, C)
368
368
  xp_assert_close(sys_ssd.D, np.zeros_like(sys_ssd.D))
369
369
 
370
+ sys_ssd2 = c2d(sys_ssc, dt=dt)
371
+
372
+ xp_assert_close(sys_ssd2.A, A_res)
373
+ xp_assert_close(sys_ssd2.B, B_res)
374
+ xp_assert_close(sys_ssd2.C, C)
375
+ xp_assert_close(sys_ssd2.D, np.zeros_like(sys_ssd2.D))
376
+
370
377
  def test_c2d_tf(self):
371
378
 
372
379
  sys = lti([0.5, 0.3], [1.0, 0.4])