scipy 1.15.3__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0rc1__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 (608) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-darwin.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_quad_vec.py +21 -29
  128. scipy/integrate/_quadpack_py.py +11 -7
  129. scipy/integrate/_quadrature.py +3 -3
  130. scipy/integrate/_rules/_base.py +2 -2
  131. scipy/integrate/_tanhsinh.py +48 -47
  132. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  133. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  134. scipy/integrate/tests/test__quad_vec.py +0 -6
  135. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  136. scipy/integrate/tests/test_cubature.py +21 -35
  137. scipy/integrate/tests/test_quadrature.py +6 -8
  138. scipy/integrate/tests/test_tanhsinh.py +56 -48
  139. scipy/interpolate/__init__.py +70 -58
  140. scipy/interpolate/_bary_rational.py +22 -22
  141. scipy/interpolate/_bsplines.py +119 -66
  142. scipy/interpolate/_cubic.py +65 -50
  143. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  144. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  145. scipy/interpolate/_fitpack2.py +9 -6
  146. scipy/interpolate/_fitpack_impl.py +32 -26
  147. scipy/interpolate/_fitpack_repro.py +23 -19
  148. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  149. scipy/interpolate/_interpolate.py +30 -12
  150. scipy/interpolate/_ndbspline.py +13 -18
  151. scipy/interpolate/_ndgriddata.py +5 -8
  152. scipy/interpolate/_polyint.py +95 -31
  153. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  154. scipy/interpolate/_rbf.py +2 -2
  155. scipy/interpolate/_rbfinterp.py +1 -1
  156. scipy/interpolate/_rgi.py +31 -26
  157. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  158. scipy/interpolate/dfitpack.py +0 -20
  159. scipy/interpolate/interpnd.py +1 -2
  160. scipy/interpolate/tests/test_bary_rational.py +2 -2
  161. scipy/interpolate/tests/test_bsplines.py +97 -1
  162. scipy/interpolate/tests/test_fitpack2.py +39 -1
  163. scipy/interpolate/tests/test_interpnd.py +32 -20
  164. scipy/interpolate/tests/test_interpolate.py +48 -4
  165. scipy/interpolate/tests/test_rgi.py +2 -1
  166. scipy/io/_fast_matrix_market/__init__.py +2 -0
  167. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  168. scipy/io/_harwell_boeing/hb.py +7 -11
  169. scipy/io/_idl.py +5 -7
  170. scipy/io/_netcdf.py +15 -5
  171. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  172. scipy/io/arff/tests/test_arffread.py +3 -3
  173. scipy/io/matlab/__init__.py +5 -3
  174. scipy/io/matlab/_mio.py +4 -1
  175. scipy/io/matlab/_mio5.py +19 -13
  176. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  177. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  178. scipy/io/matlab/_miobase.py +4 -1
  179. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  180. scipy/io/matlab/tests/test_mio.py +46 -18
  181. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  182. scipy/io/tests/test_mmio.py +7 -1
  183. scipy/io/tests/test_wavfile.py +41 -0
  184. scipy/io/wavfile.py +57 -10
  185. scipy/linalg/_basic.py +113 -86
  186. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  187. scipy/linalg/_decomp.py +22 -9
  188. scipy/linalg/_decomp_cholesky.py +28 -13
  189. scipy/linalg/_decomp_cossin.py +45 -30
  190. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  191. scipy/linalg/_decomp_ldl.py +4 -1
  192. scipy/linalg/_decomp_lu.py +18 -6
  193. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  194. scipy/linalg/_decomp_polar.py +2 -0
  195. scipy/linalg/_decomp_qr.py +6 -2
  196. scipy/linalg/_decomp_qz.py +3 -0
  197. scipy/linalg/_decomp_schur.py +3 -1
  198. scipy/linalg/_decomp_svd.py +13 -2
  199. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  200. scipy/linalg/_expm_frechet.py +4 -0
  201. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  202. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  203. scipy/linalg/_matfuncs.py +187 -4
  204. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  206. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_procrustes.py +2 -0
  208. scipy/linalg/_sketches.py +17 -6
  209. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  210. scipy/linalg/_solvers.py +7 -2
  211. scipy/linalg/_special_matrices.py +26 -36
  212. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  213. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  214. scipy/linalg/lapack.py +22 -2
  215. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  216. scipy/linalg/tests/test_basic.py +31 -16
  217. scipy/linalg/tests/test_batch.py +588 -0
  218. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  219. scipy/linalg/tests/test_decomp.py +40 -3
  220. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  221. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  222. scipy/linalg/tests/test_lapack.py +115 -7
  223. scipy/linalg/tests/test_matfuncs.py +157 -102
  224. scipy/linalg/tests/test_procrustes.py +0 -7
  225. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  226. scipy/linalg/tests/test_special_matrices.py +1 -5
  227. scipy/ndimage/__init__.py +1 -0
  228. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  229. scipy/ndimage/_delegators.py +8 -2
  230. scipy/ndimage/_filters.py +433 -5
  231. scipy/ndimage/_interpolation.py +36 -6
  232. scipy/ndimage/_measurements.py +4 -2
  233. scipy/ndimage/_morphology.py +5 -0
  234. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  235. scipy/ndimage/_ni_docstrings.py +5 -1
  236. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  237. scipy/ndimage/_ni_support.py +1 -5
  238. scipy/ndimage/_support_alternative_backends.py +18 -6
  239. scipy/ndimage/tests/test_filters.py +337 -259
  240. scipy/ndimage/tests/test_fourier.py +7 -9
  241. scipy/ndimage/tests/test_interpolation.py +68 -61
  242. scipy/ndimage/tests/test_measurements.py +18 -35
  243. scipy/ndimage/tests/test_morphology.py +143 -131
  244. scipy/ndimage/tests/test_splines.py +1 -3
  245. scipy/optimize/_basinhopping.py +13 -7
  246. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  247. scipy/optimize/_bracket.py +17 -24
  248. scipy/optimize/_chandrupatla.py +9 -10
  249. scipy/optimize/_cobyla_py.py +104 -123
  250. scipy/optimize/_constraints.py +14 -10
  251. scipy/optimize/_differentiable_functions.py +371 -230
  252. scipy/optimize/_differentialevolution.py +4 -3
  253. scipy/optimize/_dual_annealing.py +1 -1
  254. scipy/optimize/_elementwise.py +1 -4
  255. scipy/optimize/_lbfgsb_py.py +57 -16
  256. scipy/optimize/_linprog_doc.py +2 -2
  257. scipy/optimize/_linprog_highs.py +2 -2
  258. scipy/optimize/_linprog_ip.py +25 -10
  259. scipy/optimize/_linprog_util.py +14 -16
  260. scipy/optimize/_lsq/common.py +3 -3
  261. scipy/optimize/_lsq/dogbox.py +16 -2
  262. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_lsq/least_squares.py +198 -126
  264. scipy/optimize/_lsq/lsq_linear.py +6 -6
  265. scipy/optimize/_lsq/trf.py +35 -8
  266. scipy/optimize/_milp.py +3 -1
  267. scipy/optimize/_minimize.py +105 -36
  268. scipy/optimize/_minpack_py.py +21 -14
  269. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  270. scipy/optimize/_nnls.py +20 -21
  271. scipy/optimize/_nonlin.py +34 -3
  272. scipy/optimize/_numdiff.py +288 -110
  273. scipy/optimize/_optimize.py +86 -48
  274. scipy/optimize/_remove_redundancy.py +5 -5
  275. scipy/optimize/_root_scalar.py +1 -1
  276. scipy/optimize/_shgo.py +6 -0
  277. scipy/optimize/_shgo_lib/_complex.py +1 -1
  278. scipy/optimize/_slsqp_py.py +216 -124
  279. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  280. scipy/optimize/_spectral.py +1 -1
  281. scipy/optimize/_tnc.py +8 -1
  282. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_trustregion.py +20 -6
  284. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  285. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  286. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  287. scipy/optimize/_trustregion_constr/projections.py +12 -8
  288. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  289. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  290. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  291. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  292. scipy/optimize/_trustregion_exact.py +0 -1
  293. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_zeros_py.py +97 -17
  295. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  296. scipy/optimize/slsqp.py +0 -1
  297. scipy/optimize/tests/test__basinhopping.py +1 -1
  298. scipy/optimize/tests/test__differential_evolution.py +4 -4
  299. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  300. scipy/optimize/tests/test__numdiff.py +66 -22
  301. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  302. scipy/optimize/tests/test__shgo.py +9 -1
  303. scipy/optimize/tests/test_bracket.py +36 -46
  304. scipy/optimize/tests/test_chandrupatla.py +133 -135
  305. scipy/optimize/tests/test_cobyla.py +74 -45
  306. scipy/optimize/tests/test_constraints.py +1 -1
  307. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  308. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  309. scipy/optimize/tests/test_least_squares.py +125 -13
  310. scipy/optimize/tests/test_linear_assignment.py +3 -3
  311. scipy/optimize/tests/test_linprog.py +3 -3
  312. scipy/optimize/tests/test_lsq_linear.py +5 -5
  313. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  314. scipy/optimize/tests/test_minpack.py +4 -4
  315. scipy/optimize/tests/test_nnls.py +43 -3
  316. scipy/optimize/tests/test_nonlin.py +36 -0
  317. scipy/optimize/tests/test_optimize.py +95 -17
  318. scipy/optimize/tests/test_slsqp.py +36 -4
  319. scipy/optimize/tests/test_zeros.py +34 -1
  320. scipy/signal/__init__.py +12 -23
  321. scipy/signal/_delegators.py +568 -0
  322. scipy/signal/_filter_design.py +459 -241
  323. scipy/signal/_fir_filter_design.py +262 -90
  324. scipy/signal/_lti_conversion.py +3 -2
  325. scipy/signal/_ltisys.py +118 -91
  326. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  327. scipy/signal/_polyutils.py +172 -0
  328. scipy/signal/_short_time_fft.py +519 -70
  329. scipy/signal/_signal_api.py +30 -0
  330. scipy/signal/_signaltools.py +719 -399
  331. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  332. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  333. scipy/signal/_spectral_py.py +221 -50
  334. scipy/signal/_spline_filters.py +108 -68
  335. scipy/signal/_support_alternative_backends.py +73 -0
  336. scipy/signal/_upfirdn.py +4 -1
  337. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  338. scipy/signal/_waveforms.py +2 -11
  339. scipy/signal/_wavelets.py +1 -1
  340. scipy/signal/fir_filter_design.py +1 -0
  341. scipy/signal/spline.py +4 -11
  342. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  343. scipy/signal/tests/test_bsplines.py +114 -79
  344. scipy/signal/tests/test_cont2discrete.py +9 -2
  345. scipy/signal/tests/test_filter_design.py +721 -481
  346. scipy/signal/tests/test_fir_filter_design.py +332 -140
  347. scipy/signal/tests/test_savitzky_golay.py +4 -3
  348. scipy/signal/tests/test_short_time_fft.py +221 -3
  349. scipy/signal/tests/test_signaltools.py +2144 -1348
  350. scipy/signal/tests/test_spectral.py +19 -6
  351. scipy/signal/tests/test_splines.py +161 -96
  352. scipy/signal/tests/test_upfirdn.py +84 -50
  353. scipy/signal/tests/test_waveforms.py +20 -0
  354. scipy/signal/tests/test_windows.py +607 -466
  355. scipy/signal/windows/_windows.py +287 -148
  356. scipy/sparse/__init__.py +23 -4
  357. scipy/sparse/_base.py +270 -108
  358. scipy/sparse/_bsr.py +7 -4
  359. scipy/sparse/_compressed.py +59 -231
  360. scipy/sparse/_construct.py +90 -38
  361. scipy/sparse/_coo.py +115 -181
  362. scipy/sparse/_csc.py +4 -4
  363. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  364. scipy/sparse/_csr.py +2 -2
  365. scipy/sparse/_data.py +48 -48
  366. scipy/sparse/_dia.py +105 -18
  367. scipy/sparse/_dok.py +0 -23
  368. scipy/sparse/_index.py +4 -4
  369. scipy/sparse/_matrix.py +23 -0
  370. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  371. scipy/sparse/_sputils.py +37 -22
  372. scipy/sparse/base.py +0 -9
  373. scipy/sparse/bsr.py +0 -14
  374. scipy/sparse/compressed.py +0 -23
  375. scipy/sparse/construct.py +0 -6
  376. scipy/sparse/coo.py +0 -14
  377. scipy/sparse/csc.py +0 -3
  378. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  379. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  380. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  381. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  382. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  383. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  384. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  385. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  386. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  387. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  388. scipy/sparse/csr.py +0 -5
  389. scipy/sparse/data.py +1 -6
  390. scipy/sparse/dia.py +0 -7
  391. scipy/sparse/dok.py +0 -10
  392. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  393. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  394. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  395. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  396. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  397. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  398. scipy/sparse/linalg/_interface.py +17 -18
  399. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  400. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  401. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  402. scipy/sparse/linalg/_isolve/minres.py +5 -5
  403. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  404. scipy/sparse/linalg/_isolve/utils.py +2 -8
  405. scipy/sparse/linalg/_matfuncs.py +1 -1
  406. scipy/sparse/linalg/_norm.py +1 -1
  407. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  408. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  409. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  410. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  411. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  412. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  413. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  414. scipy/sparse/tests/test_base.py +207 -42
  415. scipy/sparse/tests/test_common1d.py +7 -7
  416. scipy/sparse/tests/test_construct.py +1 -1
  417. scipy/sparse/tests/test_coo.py +272 -4
  418. scipy/sparse/tests/test_sparsetools.py +5 -0
  419. scipy/sparse/tests/test_sputils.py +36 -7
  420. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  421. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  422. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  423. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  424. scipy/spatial/distance.py +49 -42
  425. scipy/spatial/tests/test_distance.py +3 -1
  426. scipy/spatial/tests/test_kdtree.py +1 -0
  427. scipy/spatial/tests/test_qhull.py +7 -2
  428. scipy/spatial/transform/__init__.py +5 -3
  429. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  430. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  431. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  432. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  433. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  434. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  435. scipy/special/__init__.py +1 -47
  436. scipy/special/_add_newdocs.py +34 -772
  437. scipy/special/_basic.py +22 -25
  438. scipy/special/_comb.cpython-312-darwin.so +0 -0
  439. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  440. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  441. scipy/special/_logsumexp.py +67 -58
  442. scipy/special/_orthogonal.pyi +1 -1
  443. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  444. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  445. scipy/special/_spherical_bessel.py +4 -4
  446. scipy/special/_support_alternative_backends.py +212 -119
  447. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  448. scipy/special/_testutils.py +4 -4
  449. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  450. scipy/special/_ufuncs.pyi +1 -0
  451. scipy/special/_ufuncs.pyx +215 -1400
  452. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  453. scipy/special/_ufuncs_cxx.pxd +2 -15
  454. scipy/special/_ufuncs_cxx.pyx +5 -44
  455. scipy/special/_ufuncs_cxx_defs.h +2 -16
  456. scipy/special/_ufuncs_defs.h +0 -8
  457. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  458. scipy/special/cython_special.pxd +1 -1
  459. scipy/special/tests/_cython_examples/meson.build +10 -1
  460. scipy/special/tests/test_basic.py +153 -20
  461. scipy/special/tests/test_boost_ufuncs.py +3 -0
  462. scipy/special/tests/test_cdflib.py +35 -11
  463. scipy/special/tests/test_gammainc.py +16 -0
  464. scipy/special/tests/test_hyp2f1.py +2 -2
  465. scipy/special/tests/test_log1mexp.py +85 -0
  466. scipy/special/tests/test_logsumexp.py +206 -64
  467. scipy/special/tests/test_mpmath.py +1 -0
  468. scipy/special/tests/test_nan_inputs.py +1 -1
  469. scipy/special/tests/test_orthogonal.py +17 -18
  470. scipy/special/tests/test_sf_error.py +3 -2
  471. scipy/special/tests/test_sph_harm.py +6 -7
  472. scipy/special/tests/test_support_alternative_backends.py +211 -76
  473. scipy/stats/__init__.py +4 -1
  474. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  475. scipy/stats/_axis_nan_policy.py +4 -3
  476. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  477. scipy/stats/_continued_fraction.py +387 -0
  478. scipy/stats/_continuous_distns.py +277 -310
  479. scipy/stats/_covariance.py +6 -3
  480. scipy/stats/_discrete_distns.py +39 -32
  481. scipy/stats/_distn_infrastructure.py +39 -12
  482. scipy/stats/_distribution_infrastructure.py +900 -238
  483. scipy/stats/_entropy.py +7 -8
  484. scipy/{_lib → stats}/_finite_differences.py +1 -1
  485. scipy/stats/_hypotests.py +82 -49
  486. scipy/stats/_kde.py +53 -49
  487. scipy/stats/_ksstats.py +1 -1
  488. scipy/stats/_levy_stable/__init__.py +7 -15
  489. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  490. scipy/stats/_morestats.py +112 -67
  491. scipy/stats/_mstats_basic.py +13 -17
  492. scipy/stats/_mstats_extras.py +8 -8
  493. scipy/stats/_multivariate.py +89 -113
  494. scipy/stats/_new_distributions.py +97 -20
  495. scipy/stats/_page_trend_test.py +12 -5
  496. scipy/stats/_probability_distribution.py +265 -43
  497. scipy/stats/_qmc.py +14 -9
  498. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  499. scipy/stats/_qmvnt.py +16 -95
  500. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  501. scipy/stats/_quantile.py +335 -0
  502. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  503. scipy/stats/_resampling.py +4 -29
  504. scipy/stats/_sampling.py +1 -1
  505. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  506. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  507. scipy/stats/_stats_mstats_common.py +19 -2
  508. scipy/stats/_stats_py.py +534 -460
  509. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  510. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  511. scipy/stats/_variation.py +5 -7
  512. scipy/stats/_wilcoxon.py +13 -7
  513. scipy/stats/tests/common_tests.py +6 -4
  514. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  515. scipy/stats/tests/test_continued_fraction.py +173 -0
  516. scipy/stats/tests/test_continuous.py +379 -60
  517. scipy/stats/tests/test_continuous_basic.py +18 -12
  518. scipy/stats/tests/test_discrete_basic.py +14 -8
  519. scipy/stats/tests/test_discrete_distns.py +16 -16
  520. scipy/stats/tests/test_distributions.py +95 -75
  521. scipy/stats/tests/test_entropy.py +40 -48
  522. scipy/stats/tests/test_fit.py +4 -3
  523. scipy/stats/tests/test_hypotests.py +153 -24
  524. scipy/stats/tests/test_kdeoth.py +109 -41
  525. scipy/stats/tests/test_marray.py +289 -0
  526. scipy/stats/tests/test_morestats.py +79 -47
  527. scipy/stats/tests/test_mstats_basic.py +3 -3
  528. scipy/stats/tests/test_multivariate.py +434 -83
  529. scipy/stats/tests/test_qmc.py +13 -10
  530. scipy/stats/tests/test_quantile.py +199 -0
  531. scipy/stats/tests/test_rank.py +119 -112
  532. scipy/stats/tests/test_resampling.py +47 -56
  533. scipy/stats/tests/test_sampling.py +9 -4
  534. scipy/stats/tests/test_stats.py +799 -939
  535. scipy/stats/tests/test_variation.py +8 -6
  536. scipy/version.py +2 -2
  537. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  538. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +8 -8
  539. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +540 -547
  540. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  541. scipy/_lib/array_api_extra/_funcs.py +0 -484
  542. scipy/_lib/array_api_extra/_typing.py +0 -8
  543. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  544. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  545. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  546. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  547. scipy/spatial/qhull_src/COPYING.txt +0 -38
  548. scipy/special/libsf_error_state.dylib +0 -0
  549. scipy/special/tests/test_log_softmax.py +0 -109
  550. scipy/special/tests/test_xsf_cuda.py +0 -114
  551. scipy/special/xsf/binom.h +0 -89
  552. scipy/special/xsf/cdflib.h +0 -100
  553. scipy/special/xsf/cephes/airy.h +0 -307
  554. scipy/special/xsf/cephes/besselpoly.h +0 -51
  555. scipy/special/xsf/cephes/beta.h +0 -257
  556. scipy/special/xsf/cephes/cbrt.h +0 -131
  557. scipy/special/xsf/cephes/chbevl.h +0 -85
  558. scipy/special/xsf/cephes/chdtr.h +0 -193
  559. scipy/special/xsf/cephes/const.h +0 -87
  560. scipy/special/xsf/cephes/ellie.h +0 -293
  561. scipy/special/xsf/cephes/ellik.h +0 -251
  562. scipy/special/xsf/cephes/ellpe.h +0 -107
  563. scipy/special/xsf/cephes/ellpk.h +0 -117
  564. scipy/special/xsf/cephes/expn.h +0 -260
  565. scipy/special/xsf/cephes/gamma.h +0 -398
  566. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  567. scipy/special/xsf/cephes/hyperg.h +0 -361
  568. scipy/special/xsf/cephes/i0.h +0 -149
  569. scipy/special/xsf/cephes/i1.h +0 -158
  570. scipy/special/xsf/cephes/igam.h +0 -421
  571. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  572. scipy/special/xsf/cephes/igami.h +0 -313
  573. scipy/special/xsf/cephes/j0.h +0 -225
  574. scipy/special/xsf/cephes/j1.h +0 -198
  575. scipy/special/xsf/cephes/jv.h +0 -715
  576. scipy/special/xsf/cephes/k0.h +0 -164
  577. scipy/special/xsf/cephes/k1.h +0 -163
  578. scipy/special/xsf/cephes/kn.h +0 -243
  579. scipy/special/xsf/cephes/lanczos.h +0 -112
  580. scipy/special/xsf/cephes/ndtr.h +0 -275
  581. scipy/special/xsf/cephes/poch.h +0 -85
  582. scipy/special/xsf/cephes/polevl.h +0 -167
  583. scipy/special/xsf/cephes/psi.h +0 -194
  584. scipy/special/xsf/cephes/rgamma.h +0 -111
  585. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  586. scipy/special/xsf/cephes/shichi.h +0 -248
  587. scipy/special/xsf/cephes/sici.h +0 -224
  588. scipy/special/xsf/cephes/sindg.h +0 -221
  589. scipy/special/xsf/cephes/tandg.h +0 -139
  590. scipy/special/xsf/cephes/trig.h +0 -58
  591. scipy/special/xsf/cephes/unity.h +0 -186
  592. scipy/special/xsf/cephes/zeta.h +0 -172
  593. scipy/special/xsf/config.h +0 -304
  594. scipy/special/xsf/digamma.h +0 -205
  595. scipy/special/xsf/error.h +0 -57
  596. scipy/special/xsf/evalpoly.h +0 -47
  597. scipy/special/xsf/expint.h +0 -266
  598. scipy/special/xsf/hyp2f1.h +0 -694
  599. scipy/special/xsf/iv_ratio.h +0 -173
  600. scipy/special/xsf/lambertw.h +0 -150
  601. scipy/special/xsf/loggamma.h +0 -163
  602. scipy/special/xsf/sici.h +0 -200
  603. scipy/special/xsf/tools.h +0 -427
  604. scipy/special/xsf/trig.h +0 -164
  605. scipy/special/xsf/wright_bessel.h +0 -843
  606. scipy/special/xsf/zlog1.h +0 -35
  607. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  608. scipy-1.15.3.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,
@@ -226,156 +225,6 @@ def _istft_wrapper(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None,
226
225
  return t, x, (ST.lower_border_end[0], k_hi)
227
226
 
228
227
 
229
- def _csd_wrapper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
230
- nfft=None, detrend='constant', return_onesided=True,
231
- scaling='density', axis=-1, average='mean'):
232
- """Wrapper for the `csd()` function based on `ShortTimeFFT` for
233
- unit testing.
234
- """
235
- freqs, _, Pxy = _csd_test_shim(x, y, fs, window, nperseg, noverlap, nfft,
236
- detrend, return_onesided, scaling, axis)
237
-
238
- # The following code is taken from csd():
239
- if len(Pxy.shape) >= 2 and Pxy.size > 0:
240
- if Pxy.shape[-1] > 1:
241
- if average == 'median':
242
- # np.median must be passed real arrays for the desired result
243
- bias = _median_bias(Pxy.shape[-1])
244
- if np.iscomplexobj(Pxy):
245
- Pxy = (np.median(np.real(Pxy), axis=-1)
246
- + 1j * np.median(np.imag(Pxy), axis=-1))
247
- else:
248
- Pxy = np.median(Pxy, axis=-1)
249
- Pxy /= bias
250
- elif average == 'mean':
251
- Pxy = Pxy.mean(axis=-1)
252
- else:
253
- raise ValueError(f'average must be "median" or "mean", got {average}')
254
- else:
255
- Pxy = np.reshape(Pxy, Pxy.shape[:-1])
256
-
257
- return freqs, Pxy
258
-
259
-
260
- def _csd_test_shim(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
261
- nfft=None, detrend='constant', return_onesided=True,
262
- scaling='density', axis=-1):
263
- """Compare output of _spectral_helper() and ShortTimeFFT, more
264
- precisely _spect_helper_csd() for used in csd_wrapper().
265
-
266
- The motivation of this function is to test if the ShortTimeFFT-based
267
- wrapper `_spect_helper_csd()` returns the same values as `_spectral_helper`.
268
- This function should only be usd by csd() in (unit) testing.
269
- """
270
- freqs, t, Pxy = _spectral_helper(x, y, fs, window, nperseg, noverlap, nfft,
271
- detrend, return_onesided, scaling, axis,
272
- mode='psd')
273
- freqs1, Pxy1 = _spect_helper_csd(x, y, fs, window, nperseg, noverlap, nfft,
274
- detrend, return_onesided, scaling, axis)
275
-
276
- np.testing.assert_allclose(freqs1, freqs)
277
- amax_Pxy = max(np.abs(Pxy).max(), 1) if Pxy.size else 1
278
- atol = np.finfo(Pxy.dtype).resolution * amax_Pxy # needed for large Pxy
279
- # for c_ in range(Pxy.shape[-1]):
280
- # np.testing.assert_allclose(Pxy1[:, c_], Pxy[:, c_], atol=atol)
281
- np.testing.assert_allclose(Pxy1, Pxy, atol=atol)
282
- return freqs, t, Pxy
283
-
284
-
285
- def _spect_helper_csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
286
- nfft=None, detrend='constant', return_onesided=True,
287
- scaling='density', axis=-1):
288
- """Wrapper for replacing _spectral_helper() by using the ShortTimeFFT
289
- for use by csd().
290
-
291
- This function should be only used by _csd_test_shim() and is only useful
292
- for testing the ShortTimeFFT implementation.
293
- """
294
-
295
- # The following lines are taken from the original _spectral_helper():
296
- same_data = y is x
297
- axis = int(axis)
298
-
299
- # Ensure we have np.arrays, get outdtype
300
- x = np.asarray(x)
301
- if not same_data:
302
- y = np.asarray(y)
303
- # outdtype = np.result_type(x, y, np.complex64)
304
- # else:
305
- # outdtype = np.result_type(x, np.complex64)
306
-
307
- if not same_data:
308
- # Check if we can broadcast the outer axes together
309
- xouter = list(x.shape)
310
- youter = list(y.shape)
311
- xouter.pop(axis)
312
- youter.pop(axis)
313
- try:
314
- outershape = np.broadcast(np.empty(xouter), np.empty(youter)).shape
315
- except ValueError as e:
316
- raise ValueError('x and y cannot be broadcast together.') from e
317
-
318
- if same_data:
319
- if x.size == 0:
320
- return np.empty(x.shape), np.empty(x.shape)
321
- else:
322
- if x.size == 0 or y.size == 0:
323
- outshape = outershape + (min([x.shape[axis], y.shape[axis]]),)
324
- emptyout = np.moveaxis(np.empty(outshape), -1, axis)
325
- return emptyout, emptyout
326
-
327
- if nperseg is not None: # if specified by user
328
- nperseg = int(nperseg)
329
- if nperseg < 1:
330
- raise ValueError('nperseg must be a positive integer')
331
-
332
- # parse window; if array like, then set nperseg = win.shape
333
- n = x.shape[axis] if same_data else max(x.shape[axis], y.shape[axis])
334
- win, nperseg = _triage_segments(window, nperseg, input_length=n)
335
-
336
- if nfft is None:
337
- nfft = nperseg
338
- elif nfft < nperseg:
339
- raise ValueError('nfft must be greater than or equal to nperseg.')
340
- else:
341
- nfft = int(nfft)
342
-
343
- if noverlap is None:
344
- noverlap = nperseg // 2
345
- else:
346
- noverlap = int(noverlap)
347
- if noverlap >= nperseg:
348
- raise ValueError('noverlap must be less than nperseg.')
349
- nstep = nperseg - noverlap
350
-
351
- if np.iscomplexobj(x) and return_onesided:
352
- return_onesided = False
353
-
354
- # using cast() to make mypy happy:
355
- fft_mode = cast(FFT_MODE_TYPE, 'onesided' if return_onesided
356
- else 'twosided')
357
- scale = {'spectrum': 'magnitude', 'density': 'psd'}[scaling]
358
- SFT = ShortTimeFFT(win, nstep, fs, fft_mode=fft_mode, mfft=nfft,
359
- scale_to=scale, phase_shift=None)
360
-
361
- # _spectral_helper() calculates X.conj()*Y instead of X*Y.conj():
362
- Pxy = SFT.spectrogram(y, x, detr=None if detrend is False else detrend,
363
- p0=0, p1=(n-noverlap)//SFT.hop, k_offset=nperseg//2,
364
- axis=axis).conj()
365
- # Note:
366
- # 'onesided2X' scaling of ShortTimeFFT conflicts with the
367
- # scaling='spectrum' parameter, since it doubles the squared magnitude,
368
- # which in the view of the ShortTimeFFT implementation does not make sense.
369
- # Hence, the doubling of the square is implemented here:
370
- if return_onesided:
371
- f_axis = Pxy.ndim - 1 + axis if axis < 0 else axis
372
- Pxy = np.moveaxis(Pxy, f_axis, -1)
373
- Pxy[..., 1:-1 if SFT.mfft % 2 == 0 else None] *= 2
374
- Pxy = np.moveaxis(Pxy, -1, f_axis)
375
-
376
- return SFT.f, Pxy
377
-
378
-
379
228
  def stft_compare(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
380
229
  nfft=None, detrend=False, return_onesided=True,
381
230
  boundary='zeros', padded=True, axis=-1, scaling='spectrum'):
@@ -460,21 +309,3 @@ def istft_compare(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None,
460
309
  assert_allclose(x_wrapper[k_lo:k_hi], x[k_lo:k_hi], atol=atol, rtol=rtol,
461
310
  err_msg=f"Signal values {e_msg_part}")
462
311
  return t, x
463
-
464
-
465
- def csd_compare(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
466
- nfft=None, detrend='constant', return_onesided=True,
467
- scaling='density', axis=-1, average='mean'):
468
- """Assert that the results from the existing `csd()` and `_csd_wrapper()`
469
- are close to each other. """
470
- kw = dict(x=x, y=y, fs=fs, window=window, nperseg=nperseg,
471
- noverlap=noverlap, nfft=nfft, detrend=detrend,
472
- return_onesided=return_onesided, scaling=scaling, axis=axis,
473
- average=average)
474
- freqs0, Pxy0 = csd(**kw)
475
- freqs1, Pxy1 = _csd_wrapper(**kw)
476
-
477
- assert_allclose(freqs1, freqs0)
478
- assert_allclose(Pxy1, Pxy0)
479
- assert_allclose(freqs1, freqs0)
480
- 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])