scipy 1.15.3__cp313-cp313t-macosx_14_0_arm64.whl → 1.16.0rc2__cp313-cp313t-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 (627) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  12. scipy/_lib/_testutils.py +6 -2
  13. scipy/_lib/_util.py +222 -125
  14. scipy/_lib/array_api_compat/__init__.py +4 -4
  15. scipy/_lib/array_api_compat/_internal.py +19 -6
  16. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  17. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  18. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  19. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  20. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  21. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  22. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  23. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  24. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  25. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  26. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  27. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  28. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  29. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  30. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  31. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  32. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  33. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  34. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  35. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  36. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  37. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  38. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  39. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  40. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  41. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  42. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  43. scipy/_lib/array_api_extra/__init__.py +26 -3
  44. scipy/_lib/array_api_extra/_delegation.py +171 -0
  45. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  46. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  47. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  48. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  49. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  50. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  51. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  57. scipy/_lib/array_api_extra/testing.py +359 -0
  58. scipy/_lib/decorator.py +2 -2
  59. scipy/_lib/doccer.py +1 -7
  60. scipy/_lib/messagestream.cpython-313t-darwin.so +0 -0
  61. scipy/_lib/pyprima/__init__.py +212 -0
  62. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  63. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  64. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  65. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  66. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  67. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  68. scipy/_lib/pyprima/cobyla/update.py +289 -0
  69. scipy/_lib/pyprima/common/__init__.py +0 -0
  70. scipy/_lib/pyprima/common/_bounds.py +34 -0
  71. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  72. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  73. scipy/_lib/pyprima/common/_project.py +173 -0
  74. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  75. scipy/_lib/pyprima/common/consts.py +47 -0
  76. scipy/_lib/pyprima/common/evaluate.py +99 -0
  77. scipy/_lib/pyprima/common/history.py +38 -0
  78. scipy/_lib/pyprima/common/infos.py +30 -0
  79. scipy/_lib/pyprima/common/linalg.py +435 -0
  80. scipy/_lib/pyprima/common/message.py +290 -0
  81. scipy/_lib/pyprima/common/powalg.py +131 -0
  82. scipy/_lib/pyprima/common/preproc.py +277 -0
  83. scipy/_lib/pyprima/common/present.py +5 -0
  84. scipy/_lib/pyprima/common/ratio.py +54 -0
  85. scipy/_lib/pyprima/common/redrho.py +47 -0
  86. scipy/_lib/pyprima/common/selectx.py +296 -0
  87. scipy/_lib/tests/test__util.py +105 -121
  88. scipy/_lib/tests/test_array_api.py +166 -35
  89. scipy/_lib/tests/test_bunch.py +7 -0
  90. scipy/_lib/tests/test_ccallback.py +2 -10
  91. scipy/_lib/tests/test_public_api.py +13 -0
  92. scipy/cluster/_hierarchy.cpython-313t-darwin.so +0 -0
  93. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  94. scipy/cluster/_vq.cpython-313t-darwin.so +0 -0
  95. scipy/cluster/hierarchy.py +393 -223
  96. scipy/cluster/tests/test_hierarchy.py +273 -335
  97. scipy/cluster/tests/test_vq.py +45 -61
  98. scipy/cluster/vq.py +39 -35
  99. scipy/conftest.py +263 -157
  100. scipy/constants/_constants.py +4 -1
  101. scipy/constants/tests/test_codata.py +2 -2
  102. scipy/constants/tests/test_constants.py +11 -18
  103. scipy/datasets/_download_all.py +15 -1
  104. scipy/datasets/_fetchers.py +7 -1
  105. scipy/datasets/_utils.py +1 -1
  106. scipy/differentiate/_differentiate.py +25 -25
  107. scipy/differentiate/tests/test_differentiate.py +24 -25
  108. scipy/fft/_basic.py +20 -0
  109. scipy/fft/_helper.py +3 -34
  110. scipy/fft/_pocketfft/helper.py +29 -1
  111. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  112. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  113. scipy/fft/_realtransforms.py +13 -0
  114. scipy/fft/tests/test_basic.py +27 -25
  115. scipy/fft/tests/test_fftlog.py +16 -7
  116. scipy/fft/tests/test_helper.py +18 -34
  117. scipy/fft/tests/test_real_transforms.py +8 -10
  118. scipy/fftpack/convolve.cpython-313t-darwin.so +0 -0
  119. scipy/fftpack/tests/test_basic.py +2 -4
  120. scipy/fftpack/tests/test_real_transforms.py +8 -9
  121. scipy/integrate/_bvp.py +9 -3
  122. scipy/integrate/_cubature.py +3 -2
  123. scipy/integrate/_dop.cpython-313t-darwin.so +0 -0
  124. scipy/integrate/_lsoda.cpython-313t-darwin.so +0 -0
  125. scipy/integrate/_ode.py +9 -2
  126. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  127. scipy/integrate/_quad_vec.py +21 -29
  128. scipy/integrate/_quadpack.cpython-313t-darwin.so +0 -0
  129. scipy/integrate/_quadpack_py.py +11 -7
  130. scipy/integrate/_quadrature.py +3 -3
  131. scipy/integrate/_rules/_base.py +2 -2
  132. scipy/integrate/_tanhsinh.py +48 -47
  133. scipy/integrate/_test_odeint_banded.cpython-313t-darwin.so +0 -0
  134. scipy/integrate/_vode.cpython-313t-darwin.so +0 -0
  135. scipy/integrate/tests/test__quad_vec.py +0 -6
  136. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  137. scipy/integrate/tests/test_cubature.py +21 -35
  138. scipy/integrate/tests/test_quadrature.py +6 -8
  139. scipy/integrate/tests/test_tanhsinh.py +56 -48
  140. scipy/interpolate/__init__.py +70 -58
  141. scipy/interpolate/_bary_rational.py +22 -22
  142. scipy/interpolate/_bsplines.py +119 -66
  143. scipy/interpolate/_cubic.py +65 -50
  144. scipy/interpolate/_dfitpack.cpython-313t-darwin.so +0 -0
  145. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  146. scipy/interpolate/_fitpack.cpython-313t-darwin.so +0 -0
  147. scipy/interpolate/_fitpack2.py +9 -6
  148. scipy/interpolate/_fitpack_impl.py +32 -26
  149. scipy/interpolate/_fitpack_repro.py +23 -19
  150. scipy/interpolate/_interpnd.cpython-313t-darwin.so +0 -0
  151. scipy/interpolate/_interpolate.py +30 -12
  152. scipy/interpolate/_ndbspline.py +13 -18
  153. scipy/interpolate/_ndgriddata.py +5 -8
  154. scipy/interpolate/_polyint.py +95 -31
  155. scipy/interpolate/_ppoly.cpython-313t-darwin.so +0 -0
  156. scipy/interpolate/_rbf.py +2 -2
  157. scipy/interpolate/_rbfinterp.py +1 -1
  158. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  159. scipy/interpolate/_rgi.py +31 -26
  160. scipy/interpolate/_rgi_cython.cpython-313t-darwin.so +0 -0
  161. scipy/interpolate/dfitpack.py +0 -20
  162. scipy/interpolate/interpnd.py +1 -2
  163. scipy/interpolate/tests/test_bary_rational.py +2 -2
  164. scipy/interpolate/tests/test_bsplines.py +97 -1
  165. scipy/interpolate/tests/test_fitpack2.py +39 -1
  166. scipy/interpolate/tests/test_interpnd.py +32 -20
  167. scipy/interpolate/tests/test_interpolate.py +48 -4
  168. scipy/interpolate/tests/test_rgi.py +2 -1
  169. scipy/io/_fast_matrix_market/__init__.py +2 -0
  170. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  171. scipy/io/_harwell_boeing/hb.py +7 -11
  172. scipy/io/_idl.py +5 -7
  173. scipy/io/_netcdf.py +15 -5
  174. scipy/io/_test_fortran.cpython-313t-darwin.so +0 -0
  175. scipy/io/arff/tests/test_arffread.py +3 -3
  176. scipy/io/matlab/__init__.py +5 -3
  177. scipy/io/matlab/_mio.py +4 -1
  178. scipy/io/matlab/_mio5.py +19 -13
  179. scipy/io/matlab/_mio5_utils.cpython-313t-darwin.so +0 -0
  180. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  181. scipy/io/matlab/_miobase.py +4 -1
  182. scipy/io/matlab/_streams.cpython-313t-darwin.so +0 -0
  183. scipy/io/matlab/tests/test_mio.py +46 -18
  184. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  185. scipy/io/tests/test_mmio.py +7 -1
  186. scipy/io/tests/test_wavfile.py +41 -0
  187. scipy/io/wavfile.py +57 -10
  188. scipy/linalg/_basic.py +113 -86
  189. scipy/linalg/_cythonized_array_utils.cpython-313t-darwin.so +0 -0
  190. scipy/linalg/_decomp.py +22 -9
  191. scipy/linalg/_decomp_cholesky.py +28 -13
  192. scipy/linalg/_decomp_cossin.py +45 -30
  193. scipy/linalg/_decomp_interpolative.cpython-313t-darwin.so +0 -0
  194. scipy/linalg/_decomp_ldl.py +4 -1
  195. scipy/linalg/_decomp_lu.py +18 -6
  196. scipy/linalg/_decomp_lu_cython.cpython-313t-darwin.so +0 -0
  197. scipy/linalg/_decomp_polar.py +2 -0
  198. scipy/linalg/_decomp_qr.py +6 -2
  199. scipy/linalg/_decomp_qz.py +3 -0
  200. scipy/linalg/_decomp_schur.py +3 -1
  201. scipy/linalg/_decomp_svd.py +13 -2
  202. scipy/linalg/_decomp_update.cpython-313t-darwin.so +0 -0
  203. scipy/linalg/_expm_frechet.py +4 -0
  204. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  205. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  206. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  207. scipy/linalg/_matfuncs.py +187 -4
  208. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  209. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  210. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  211. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  212. scipy/linalg/_procrustes.py +2 -0
  213. scipy/linalg/_sketches.py +17 -6
  214. scipy/linalg/_solve_toeplitz.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_solvers.py +7 -2
  216. scipy/linalg/_special_matrices.py +26 -36
  217. scipy/linalg/cython_blas.cpython-313t-darwin.so +0 -0
  218. scipy/linalg/cython_lapack.cpython-313t-darwin.so +0 -0
  219. scipy/linalg/lapack.py +22 -2
  220. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  221. scipy/linalg/tests/test_basic.py +31 -16
  222. scipy/linalg/tests/test_batch.py +588 -0
  223. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  224. scipy/linalg/tests/test_decomp.py +40 -3
  225. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  226. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  227. scipy/linalg/tests/test_lapack.py +115 -7
  228. scipy/linalg/tests/test_matfuncs.py +157 -102
  229. scipy/linalg/tests/test_procrustes.py +0 -7
  230. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  231. scipy/linalg/tests/test_special_matrices.py +1 -5
  232. scipy/ndimage/__init__.py +1 -0
  233. scipy/ndimage/_cytest.cpython-313t-darwin.so +0 -0
  234. scipy/ndimage/_delegators.py +8 -2
  235. scipy/ndimage/_filters.py +453 -5
  236. scipy/ndimage/_interpolation.py +36 -6
  237. scipy/ndimage/_measurements.py +4 -2
  238. scipy/ndimage/_morphology.py +5 -0
  239. scipy/ndimage/_nd_image.cpython-313t-darwin.so +0 -0
  240. scipy/ndimage/_ni_docstrings.py +5 -1
  241. scipy/ndimage/_ni_label.cpython-313t-darwin.so +0 -0
  242. scipy/ndimage/_ni_support.py +1 -5
  243. scipy/ndimage/_rank_filter_1d.cpython-313t-darwin.so +0 -0
  244. scipy/ndimage/_support_alternative_backends.py +18 -6
  245. scipy/ndimage/tests/test_filters.py +370 -259
  246. scipy/ndimage/tests/test_fourier.py +7 -9
  247. scipy/ndimage/tests/test_interpolation.py +68 -61
  248. scipy/ndimage/tests/test_measurements.py +18 -35
  249. scipy/ndimage/tests/test_morphology.py +143 -131
  250. scipy/ndimage/tests/test_splines.py +1 -3
  251. scipy/odr/__odrpack.cpython-313t-darwin.so +0 -0
  252. scipy/optimize/_basinhopping.py +13 -7
  253. scipy/optimize/_bglu_dense.cpython-313t-darwin.so +0 -0
  254. scipy/optimize/_bracket.py +17 -24
  255. scipy/optimize/_chandrupatla.py +9 -10
  256. scipy/optimize/_cobyla_py.py +104 -123
  257. scipy/optimize/_constraints.py +14 -10
  258. scipy/optimize/_differentiable_functions.py +371 -230
  259. scipy/optimize/_differentialevolution.py +4 -3
  260. scipy/optimize/_direct.cpython-313t-darwin.so +0 -0
  261. scipy/optimize/_dual_annealing.py +1 -1
  262. scipy/optimize/_elementwise.py +1 -4
  263. scipy/optimize/_group_columns.cpython-313t-darwin.so +0 -0
  264. scipy/optimize/_lbfgsb.cpython-313t-darwin.so +0 -0
  265. scipy/optimize/_lbfgsb_py.py +57 -16
  266. scipy/optimize/_linprog_doc.py +2 -2
  267. scipy/optimize/_linprog_highs.py +2 -2
  268. scipy/optimize/_linprog_ip.py +25 -10
  269. scipy/optimize/_linprog_util.py +14 -16
  270. scipy/optimize/_lsap.cpython-313t-darwin.so +0 -0
  271. scipy/optimize/_lsq/common.py +3 -3
  272. scipy/optimize/_lsq/dogbox.py +16 -2
  273. scipy/optimize/_lsq/givens_elimination.cpython-313t-darwin.so +0 -0
  274. scipy/optimize/_lsq/least_squares.py +198 -126
  275. scipy/optimize/_lsq/lsq_linear.py +6 -6
  276. scipy/optimize/_lsq/trf.py +35 -8
  277. scipy/optimize/_milp.py +3 -1
  278. scipy/optimize/_minimize.py +105 -36
  279. scipy/optimize/_minpack.cpython-313t-darwin.so +0 -0
  280. scipy/optimize/_minpack_py.py +21 -14
  281. scipy/optimize/_moduleTNC.cpython-313t-darwin.so +0 -0
  282. scipy/optimize/_nnls.py +20 -21
  283. scipy/optimize/_nonlin.py +34 -3
  284. scipy/optimize/_numdiff.py +288 -110
  285. scipy/optimize/_optimize.py +86 -48
  286. scipy/optimize/_pava_pybind.cpython-313t-darwin.so +0 -0
  287. scipy/optimize/_remove_redundancy.py +5 -5
  288. scipy/optimize/_root_scalar.py +1 -1
  289. scipy/optimize/_shgo.py +6 -0
  290. scipy/optimize/_shgo_lib/_complex.py +1 -1
  291. scipy/optimize/_slsqp_py.py +216 -124
  292. scipy/optimize/_slsqplib.cpython-313t-darwin.so +0 -0
  293. scipy/optimize/_spectral.py +1 -1
  294. scipy/optimize/_tnc.py +8 -1
  295. scipy/optimize/_trlib/_trlib.cpython-313t-darwin.so +0 -0
  296. scipy/optimize/_trustregion.py +20 -6
  297. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  298. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  299. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  300. scipy/optimize/_trustregion_constr/projections.py +12 -8
  301. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  302. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  303. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  304. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  305. scipy/optimize/_trustregion_exact.py +0 -1
  306. scipy/optimize/_zeros.cpython-313t-darwin.so +0 -0
  307. scipy/optimize/_zeros_py.py +97 -17
  308. scipy/optimize/cython_optimize/_zeros.cpython-313t-darwin.so +0 -0
  309. scipy/optimize/slsqp.py +0 -1
  310. scipy/optimize/tests/test__basinhopping.py +1 -1
  311. scipy/optimize/tests/test__differential_evolution.py +4 -4
  312. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  313. scipy/optimize/tests/test__numdiff.py +66 -22
  314. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  315. scipy/optimize/tests/test__shgo.py +9 -1
  316. scipy/optimize/tests/test_bracket.py +36 -46
  317. scipy/optimize/tests/test_chandrupatla.py +133 -135
  318. scipy/optimize/tests/test_cobyla.py +74 -45
  319. scipy/optimize/tests/test_constraints.py +1 -1
  320. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  321. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  322. scipy/optimize/tests/test_least_squares.py +125 -13
  323. scipy/optimize/tests/test_linear_assignment.py +3 -3
  324. scipy/optimize/tests/test_linprog.py +3 -3
  325. scipy/optimize/tests/test_lsq_linear.py +6 -6
  326. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  327. scipy/optimize/tests/test_minpack.py +4 -4
  328. scipy/optimize/tests/test_nnls.py +43 -3
  329. scipy/optimize/tests/test_nonlin.py +36 -0
  330. scipy/optimize/tests/test_optimize.py +95 -17
  331. scipy/optimize/tests/test_slsqp.py +36 -4
  332. scipy/optimize/tests/test_zeros.py +34 -1
  333. scipy/signal/__init__.py +12 -23
  334. scipy/signal/_delegators.py +568 -0
  335. scipy/signal/_filter_design.py +459 -241
  336. scipy/signal/_fir_filter_design.py +262 -90
  337. scipy/signal/_lti_conversion.py +3 -2
  338. scipy/signal/_ltisys.py +118 -91
  339. scipy/signal/_max_len_seq_inner.cpython-313t-darwin.so +0 -0
  340. scipy/signal/_peak_finding_utils.cpython-313t-darwin.so +0 -0
  341. scipy/signal/_polyutils.py +172 -0
  342. scipy/signal/_short_time_fft.py +519 -70
  343. scipy/signal/_signal_api.py +30 -0
  344. scipy/signal/_signaltools.py +719 -399
  345. scipy/signal/_sigtools.cpython-313t-darwin.so +0 -0
  346. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  347. scipy/signal/_spectral_py.py +230 -50
  348. scipy/signal/_spline.cpython-313t-darwin.so +0 -0
  349. scipy/signal/_spline_filters.py +108 -68
  350. scipy/signal/_support_alternative_backends.py +73 -0
  351. scipy/signal/_upfirdn.py +4 -1
  352. scipy/signal/_upfirdn_apply.cpython-313t-darwin.so +0 -0
  353. scipy/signal/_waveforms.py +2 -11
  354. scipy/signal/_wavelets.py +1 -1
  355. scipy/signal/fir_filter_design.py +1 -0
  356. scipy/signal/spline.py +4 -11
  357. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  358. scipy/signal/tests/test_bsplines.py +114 -79
  359. scipy/signal/tests/test_cont2discrete.py +9 -2
  360. scipy/signal/tests/test_filter_design.py +721 -481
  361. scipy/signal/tests/test_fir_filter_design.py +332 -140
  362. scipy/signal/tests/test_savitzky_golay.py +4 -3
  363. scipy/signal/tests/test_short_time_fft.py +221 -3
  364. scipy/signal/tests/test_signaltools.py +2144 -1348
  365. scipy/signal/tests/test_spectral.py +50 -6
  366. scipy/signal/tests/test_splines.py +161 -96
  367. scipy/signal/tests/test_upfirdn.py +84 -50
  368. scipy/signal/tests/test_waveforms.py +20 -0
  369. scipy/signal/tests/test_windows.py +607 -466
  370. scipy/signal/windows/_windows.py +287 -148
  371. scipy/sparse/__init__.py +23 -4
  372. scipy/sparse/_base.py +270 -108
  373. scipy/sparse/_bsr.py +7 -4
  374. scipy/sparse/_compressed.py +59 -231
  375. scipy/sparse/_construct.py +90 -38
  376. scipy/sparse/_coo.py +115 -181
  377. scipy/sparse/_csc.py +4 -4
  378. scipy/sparse/_csparsetools.cpython-313t-darwin.so +0 -0
  379. scipy/sparse/_csr.py +2 -2
  380. scipy/sparse/_data.py +48 -48
  381. scipy/sparse/_dia.py +105 -18
  382. scipy/sparse/_dok.py +0 -23
  383. scipy/sparse/_index.py +4 -4
  384. scipy/sparse/_matrix.py +23 -0
  385. scipy/sparse/_sparsetools.cpython-313t-darwin.so +0 -0
  386. scipy/sparse/_sputils.py +37 -22
  387. scipy/sparse/base.py +0 -9
  388. scipy/sparse/bsr.py +0 -14
  389. scipy/sparse/compressed.py +0 -23
  390. scipy/sparse/construct.py +0 -6
  391. scipy/sparse/coo.py +0 -14
  392. scipy/sparse/csc.py +0 -3
  393. scipy/sparse/csgraph/_flow.cpython-313t-darwin.so +0 -0
  394. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  395. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  396. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  397. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  398. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  399. scipy/sparse/csgraph/_traversal.cpython-313t-darwin.so +0 -0
  400. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  401. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  402. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  403. scipy/sparse/csr.py +0 -5
  404. scipy/sparse/data.py +1 -6
  405. scipy/sparse/dia.py +0 -7
  406. scipy/sparse/dok.py +0 -10
  407. scipy/sparse/linalg/_dsolve/_superlu.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  409. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  410. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313t-darwin.so +0 -0
  411. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  412. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  413. scipy/sparse/linalg/_interface.py +17 -18
  414. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  415. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  416. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  417. scipy/sparse/linalg/_isolve/minres.py +5 -5
  418. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  419. scipy/sparse/linalg/_isolve/utils.py +2 -8
  420. scipy/sparse/linalg/_matfuncs.py +1 -1
  421. scipy/sparse/linalg/_norm.py +1 -1
  422. scipy/sparse/linalg/_propack/_cpropack.cpython-313t-darwin.so +0 -0
  423. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  424. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-darwin.so +0 -0
  426. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  427. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  428. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  429. scipy/sparse/tests/test_base.py +214 -42
  430. scipy/sparse/tests/test_common1d.py +7 -7
  431. scipy/sparse/tests/test_construct.py +1 -1
  432. scipy/sparse/tests/test_coo.py +272 -4
  433. scipy/sparse/tests/test_sparsetools.py +5 -0
  434. scipy/sparse/tests/test_sputils.py +36 -7
  435. scipy/spatial/_ckdtree.cpython-313t-darwin.so +0 -0
  436. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  437. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  438. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  439. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  440. scipy/spatial/_voronoi.cpython-313t-darwin.so +0 -0
  441. scipy/spatial/distance.py +49 -42
  442. scipy/spatial/tests/test_distance.py +15 -1
  443. scipy/spatial/tests/test_kdtree.py +1 -0
  444. scipy/spatial/tests/test_qhull.py +7 -2
  445. scipy/spatial/transform/__init__.py +5 -3
  446. scipy/spatial/transform/_rigid_transform.cpython-313t-darwin.so +0 -0
  447. scipy/spatial/transform/_rotation.cpython-313t-darwin.so +0 -0
  448. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  449. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  450. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  451. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  452. scipy/special/__init__.py +1 -47
  453. scipy/special/_add_newdocs.py +34 -772
  454. scipy/special/_basic.py +22 -25
  455. scipy/special/_comb.cpython-313t-darwin.so +0 -0
  456. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  457. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  458. scipy/special/_logsumexp.py +67 -58
  459. scipy/special/_orthogonal.pyi +1 -1
  460. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  461. scipy/special/_special_ufuncs.cpython-313t-darwin.so +0 -0
  462. scipy/special/_spherical_bessel.py +4 -4
  463. scipy/special/_support_alternative_backends.py +212 -119
  464. scipy/special/_test_internal.cpython-313t-darwin.so +0 -0
  465. scipy/special/_testutils.py +4 -4
  466. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  467. scipy/special/_ufuncs.pyi +1 -0
  468. scipy/special/_ufuncs.pyx +215 -1400
  469. scipy/special/_ufuncs_cxx.cpython-313t-darwin.so +0 -0
  470. scipy/special/_ufuncs_cxx.pxd +2 -15
  471. scipy/special/_ufuncs_cxx.pyx +5 -44
  472. scipy/special/_ufuncs_cxx_defs.h +2 -16
  473. scipy/special/_ufuncs_defs.h +0 -8
  474. scipy/special/cython_special.cpython-313t-darwin.so +0 -0
  475. scipy/special/cython_special.pxd +1 -1
  476. scipy/special/tests/_cython_examples/meson.build +10 -1
  477. scipy/special/tests/test_basic.py +153 -20
  478. scipy/special/tests/test_boost_ufuncs.py +3 -0
  479. scipy/special/tests/test_cdflib.py +35 -11
  480. scipy/special/tests/test_gammainc.py +16 -0
  481. scipy/special/tests/test_hyp2f1.py +2 -2
  482. scipy/special/tests/test_log1mexp.py +85 -0
  483. scipy/special/tests/test_logsumexp.py +206 -64
  484. scipy/special/tests/test_mpmath.py +1 -0
  485. scipy/special/tests/test_nan_inputs.py +1 -1
  486. scipy/special/tests/test_orthogonal.py +17 -18
  487. scipy/special/tests/test_sf_error.py +3 -2
  488. scipy/special/tests/test_sph_harm.py +6 -7
  489. scipy/special/tests/test_support_alternative_backends.py +211 -76
  490. scipy/stats/__init__.py +4 -1
  491. scipy/stats/_ansari_swilk_statistics.cpython-313t-darwin.so +0 -0
  492. scipy/stats/_axis_nan_policy.py +5 -12
  493. scipy/stats/_biasedurn.cpython-313t-darwin.so +0 -0
  494. scipy/stats/_continued_fraction.py +387 -0
  495. scipy/stats/_continuous_distns.py +277 -310
  496. scipy/stats/_correlation.py +1 -1
  497. scipy/stats/_covariance.py +6 -3
  498. scipy/stats/_discrete_distns.py +39 -32
  499. scipy/stats/_distn_infrastructure.py +39 -12
  500. scipy/stats/_distribution_infrastructure.py +900 -238
  501. scipy/stats/_entropy.py +9 -10
  502. scipy/{_lib → stats}/_finite_differences.py +1 -1
  503. scipy/stats/_hypotests.py +83 -50
  504. scipy/stats/_kde.py +53 -49
  505. scipy/stats/_ksstats.py +1 -1
  506. scipy/stats/_levy_stable/__init__.py +7 -15
  507. scipy/stats/_levy_stable/levyst.cpython-313t-darwin.so +0 -0
  508. scipy/stats/_morestats.py +118 -73
  509. scipy/stats/_mstats_basic.py +13 -17
  510. scipy/stats/_mstats_extras.py +8 -8
  511. scipy/stats/_multivariate.py +89 -113
  512. scipy/stats/_new_distributions.py +97 -20
  513. scipy/stats/_page_trend_test.py +12 -5
  514. scipy/stats/_probability_distribution.py +265 -43
  515. scipy/stats/_qmc.py +14 -9
  516. scipy/stats/_qmc_cy.cpython-313t-darwin.so +0 -0
  517. scipy/stats/_qmvnt.py +16 -95
  518. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  519. scipy/stats/_quantile.py +335 -0
  520. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  521. scipy/stats/_resampling.py +4 -29
  522. scipy/stats/_sampling.py +1 -1
  523. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  524. scipy/stats/_stats.cpython-313t-darwin.so +0 -0
  525. scipy/stats/_stats_mstats_common.py +21 -2
  526. scipy/stats/_stats_py.py +550 -476
  527. scipy/stats/_stats_pythran.cpython-313t-darwin.so +0 -0
  528. scipy/stats/_unuran/unuran_wrapper.cpython-313t-darwin.so +0 -0
  529. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  530. scipy/stats/_variation.py +6 -8
  531. scipy/stats/_wilcoxon.py +13 -7
  532. scipy/stats/tests/common_tests.py +6 -4
  533. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  534. scipy/stats/tests/test_continued_fraction.py +173 -0
  535. scipy/stats/tests/test_continuous.py +379 -60
  536. scipy/stats/tests/test_continuous_basic.py +18 -12
  537. scipy/stats/tests/test_discrete_basic.py +14 -8
  538. scipy/stats/tests/test_discrete_distns.py +16 -16
  539. scipy/stats/tests/test_distributions.py +95 -75
  540. scipy/stats/tests/test_entropy.py +40 -48
  541. scipy/stats/tests/test_fit.py +4 -3
  542. scipy/stats/tests/test_hypotests.py +153 -24
  543. scipy/stats/tests/test_kdeoth.py +109 -41
  544. scipy/stats/tests/test_marray.py +289 -0
  545. scipy/stats/tests/test_morestats.py +79 -47
  546. scipy/stats/tests/test_mstats_basic.py +3 -3
  547. scipy/stats/tests/test_multivariate.py +434 -83
  548. scipy/stats/tests/test_qmc.py +13 -10
  549. scipy/stats/tests/test_quantile.py +199 -0
  550. scipy/stats/tests/test_rank.py +119 -112
  551. scipy/stats/tests/test_resampling.py +47 -56
  552. scipy/stats/tests/test_sampling.py +9 -4
  553. scipy/stats/tests/test_stats.py +799 -939
  554. scipy/stats/tests/test_variation.py +8 -6
  555. scipy/version.py +2 -2
  556. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  557. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +559 -566
  559. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  560. scipy/_lib/array_api_extra/_funcs.py +0 -484
  561. scipy/_lib/array_api_extra/_typing.py +0 -8
  562. scipy/interpolate/_bspl.cpython-313t-darwin.so +0 -0
  563. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  564. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  565. scipy/optimize/_slsqp.cpython-313t-darwin.so +0 -0
  566. scipy/spatial/qhull_src/COPYING.txt +0 -38
  567. scipy/special/libsf_error_state.dylib +0 -0
  568. scipy/special/tests/test_log_softmax.py +0 -109
  569. scipy/special/tests/test_xsf_cuda.py +0 -114
  570. scipy/special/xsf/binom.h +0 -89
  571. scipy/special/xsf/cdflib.h +0 -100
  572. scipy/special/xsf/cephes/airy.h +0 -307
  573. scipy/special/xsf/cephes/besselpoly.h +0 -51
  574. scipy/special/xsf/cephes/beta.h +0 -257
  575. scipy/special/xsf/cephes/cbrt.h +0 -131
  576. scipy/special/xsf/cephes/chbevl.h +0 -85
  577. scipy/special/xsf/cephes/chdtr.h +0 -193
  578. scipy/special/xsf/cephes/const.h +0 -87
  579. scipy/special/xsf/cephes/ellie.h +0 -293
  580. scipy/special/xsf/cephes/ellik.h +0 -251
  581. scipy/special/xsf/cephes/ellpe.h +0 -107
  582. scipy/special/xsf/cephes/ellpk.h +0 -117
  583. scipy/special/xsf/cephes/expn.h +0 -260
  584. scipy/special/xsf/cephes/gamma.h +0 -398
  585. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  586. scipy/special/xsf/cephes/hyperg.h +0 -361
  587. scipy/special/xsf/cephes/i0.h +0 -149
  588. scipy/special/xsf/cephes/i1.h +0 -158
  589. scipy/special/xsf/cephes/igam.h +0 -421
  590. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  591. scipy/special/xsf/cephes/igami.h +0 -313
  592. scipy/special/xsf/cephes/j0.h +0 -225
  593. scipy/special/xsf/cephes/j1.h +0 -198
  594. scipy/special/xsf/cephes/jv.h +0 -715
  595. scipy/special/xsf/cephes/k0.h +0 -164
  596. scipy/special/xsf/cephes/k1.h +0 -163
  597. scipy/special/xsf/cephes/kn.h +0 -243
  598. scipy/special/xsf/cephes/lanczos.h +0 -112
  599. scipy/special/xsf/cephes/ndtr.h +0 -275
  600. scipy/special/xsf/cephes/poch.h +0 -85
  601. scipy/special/xsf/cephes/polevl.h +0 -167
  602. scipy/special/xsf/cephes/psi.h +0 -194
  603. scipy/special/xsf/cephes/rgamma.h +0 -111
  604. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  605. scipy/special/xsf/cephes/shichi.h +0 -248
  606. scipy/special/xsf/cephes/sici.h +0 -224
  607. scipy/special/xsf/cephes/sindg.h +0 -221
  608. scipy/special/xsf/cephes/tandg.h +0 -139
  609. scipy/special/xsf/cephes/trig.h +0 -58
  610. scipy/special/xsf/cephes/unity.h +0 -186
  611. scipy/special/xsf/cephes/zeta.h +0 -172
  612. scipy/special/xsf/config.h +0 -304
  613. scipy/special/xsf/digamma.h +0 -205
  614. scipy/special/xsf/error.h +0 -57
  615. scipy/special/xsf/evalpoly.h +0 -47
  616. scipy/special/xsf/expint.h +0 -266
  617. scipy/special/xsf/hyp2f1.h +0 -694
  618. scipy/special/xsf/iv_ratio.h +0 -173
  619. scipy/special/xsf/lambertw.h +0 -150
  620. scipy/special/xsf/loggamma.h +0 -163
  621. scipy/special/xsf/sici.h +0 -200
  622. scipy/special/xsf/tools.h +0 -427
  623. scipy/special/xsf/trig.h +0 -164
  624. scipy/special/xsf/wright_bessel.h +0 -843
  625. scipy/special/xsf/zlog1.h +0 -35
  626. scipy/stats/_mvn.cpython-313t-darwin.so +0 -0
  627. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -1,13 +1,20 @@
1
+ import math
2
+
1
3
  import numpy as np
2
4
  from numpy import array
3
- from numpy.testing import (assert_array_almost_equal, assert_array_equal,
4
- assert_allclose,
5
- assert_equal, assert_, assert_array_less,
6
- suppress_warnings)
5
+ from numpy.testing import suppress_warnings
6
+ import pytest
7
7
  from pytest import raises as assert_raises
8
8
 
9
9
  from scipy.fft import fft
10
10
  from scipy.signal import windows, get_window, resample
11
+ from scipy._lib._array_api import (
12
+ xp_assert_close, xp_assert_equal, array_namespace, is_torch, is_jax, is_cupy,
13
+ assert_array_almost_equal, SCIPY_DEVICE, is_numpy
14
+ )
15
+
16
+ skip_xp_backends = pytest.mark.skip_xp_backends
17
+ xfail_xp_backends = pytest.mark.xfail_xp_backends
11
18
 
12
19
 
13
20
  window_funcs = [
@@ -38,101 +45,116 @@ window_funcs = [
38
45
 
39
46
  class TestBartHann:
40
47
 
41
- def test_basic(self):
42
- assert_allclose(windows.barthann(6, sym=True),
43
- [0, 0.35857354213752, 0.8794264578624801,
44
- 0.8794264578624801, 0.3585735421375199, 0],
48
+ def test_basic(self, xp):
49
+ xp_assert_close(windows.barthann(6, sym=True, xp=xp),
50
+ xp.asarray([0, 0.35857354213752, 0.8794264578624801,
51
+ 0.8794264578624801, 0.3585735421375199, 0], dtype=xp.float64),
45
52
  rtol=1e-15, atol=1e-15)
46
- assert_allclose(windows.barthann(7),
47
- [0, 0.27, 0.73, 1.0, 0.73, 0.27, 0],
53
+ xp_assert_close(windows.barthann(7, xp=xp),
54
+ xp.asarray([0, 0.27, 0.73, 1.0, 0.73, 0.27, 0],
55
+ dtype=xp.float64),
48
56
  rtol=1e-15, atol=1e-15)
49
- assert_allclose(windows.barthann(6, False),
50
- [0, 0.27, 0.73, 1.0, 0.73, 0.27],
57
+ xp_assert_close(windows.barthann(6, False, xp=xp),
58
+ xp.asarray([0, 0.27, 0.73, 1.0, 0.73, 0.27], dtype=xp.float64),
51
59
  rtol=1e-15, atol=1e-15)
52
60
 
53
61
 
54
62
  class TestBartlett:
55
63
 
56
- def test_basic(self):
57
- assert_allclose(windows.bartlett(6), [0, 0.4, 0.8, 0.8, 0.4, 0])
58
- assert_allclose(windows.bartlett(7), [0, 1/3, 2/3, 1.0, 2/3, 1/3, 0])
59
- assert_allclose(windows.bartlett(6, False),
60
- [0, 1/3, 2/3, 1.0, 2/3, 1/3])
64
+ def test_basic(self, xp):
65
+ xp_assert_close(windows.bartlett(6, xp=xp),
66
+ xp.asarray([0, 0.4, 0.8, 0.8, 0.4, 0], dtype=xp.float64))
67
+ xp_assert_close(windows.bartlett(7, xp=xp),
68
+ xp.asarray([0, 1/3, 2/3, 1.0, 2/3, 1/3, 0], dtype=xp.float64))
69
+ xp_assert_close(windows.bartlett(6, False, xp=xp),
70
+ xp.asarray([0, 1/3, 2/3, 1.0, 2/3, 1/3], dtype=xp.float64))
61
71
 
62
72
 
63
73
  class TestBlackman:
64
74
 
65
- def test_basic(self):
66
- assert_allclose(windows.blackman(6, sym=False),
67
- [0, 0.13, 0.63, 1.0, 0.63, 0.13], atol=1e-14)
68
- assert_allclose(windows.blackman(7, sym=False),
69
- [0, 0.09045342435412804, 0.4591829575459636,
70
- 0.9203636180999081, 0.9203636180999081,
71
- 0.4591829575459636, 0.09045342435412804], atol=1e-8)
72
- assert_allclose(windows.blackman(6),
73
- [0, 0.2007701432625305, 0.8492298567374694,
74
- 0.8492298567374694, 0.2007701432625305, 0],
75
+ def test_basic(self, xp):
76
+ xp_assert_close(windows.blackman(6, sym=False, xp=xp),
77
+ xp.asarray([0, 0.13, 0.63, 1.0, 0.63, 0.13], dtype=xp.float64),
78
+ atol=1e-14)
79
+ xp_assert_close(windows.blackman(7, sym=False, xp=xp),
80
+ xp.asarray([0, 0.09045342435412804, 0.4591829575459636,
81
+ 0.9203636180999081, 0.9203636180999081,
82
+ 0.4591829575459636, 0.09045342435412804],
83
+ dtype=xp.float64),
84
+ atol=1e-8)
85
+ xp_assert_close(windows.blackman(6, xp=xp),
86
+ xp.asarray([0, 0.2007701432625305, 0.8492298567374694,
87
+ 0.8492298567374694, 0.2007701432625305, 0],
88
+ dtype=xp.float64),
75
89
  atol=1e-14)
76
- assert_allclose(windows.blackman(7, True),
77
- [0, 0.13, 0.63, 1.0, 0.63, 0.13, 0], atol=1e-14)
90
+ xp_assert_close(windows.blackman(7, True, xp=xp),
91
+ xp.asarray([0, 0.13, 0.63, 1.0, 0.63, 0.13, 0],
92
+ dtype=xp.float64), atol=1e-14)
78
93
 
79
94
 
80
95
  class TestBlackmanHarris:
81
96
 
82
- def test_basic(self):
83
- assert_allclose(windows.blackmanharris(6, False),
84
- [6.0e-05, 0.055645, 0.520575, 1.0, 0.520575, 0.055645])
85
- assert_allclose(windows.blackmanharris(7, sym=False),
86
- [6.0e-05, 0.03339172347815117, 0.332833504298565,
87
- 0.8893697722232837, 0.8893697722232838,
88
- 0.3328335042985652, 0.03339172347815122])
89
- assert_allclose(windows.blackmanharris(6),
90
- [6.0e-05, 0.1030114893456638, 0.7938335106543362,
91
- 0.7938335106543364, 0.1030114893456638, 6.0e-05])
92
- assert_allclose(windows.blackmanharris(7, sym=True),
93
- [6.0e-05, 0.055645, 0.520575, 1.0, 0.520575, 0.055645,
94
- 6.0e-05])
95
-
96
-
97
+ def test_basic(self, xp):
98
+ xp_assert_close(windows.blackmanharris(6, False, xp=xp),
99
+ xp.asarray([6.0e-05, 0.055645, 0.520575,
100
+ 1.0, 0.520575, 0.055645], dtype=xp.float64))
101
+ xp_assert_close(windows.blackmanharris(7, sym=False, xp=xp),
102
+ xp.asarray([6.0e-05, 0.03339172347815117, 0.332833504298565,
103
+ 0.8893697722232837, 0.8893697722232838,
104
+ 0.3328335042985652, 0.03339172347815122],
105
+ dtype=xp.float64))
106
+ xp_assert_close(windows.blackmanharris(6, xp=xp),
107
+ xp.asarray([6.0e-05, 0.1030114893456638, 0.7938335106543362,
108
+ 0.7938335106543364, 0.1030114893456638, 6.0e-05],
109
+ dtype=xp.float64))
110
+ xp_assert_close(windows.blackmanharris(7, sym=True, xp=xp),
111
+ xp.asarray([6.0e-05, 0.055645, 0.520575, 1.0, 0.520575,
112
+ 0.055645, 6.0e-05], dtype=xp.float64))
113
+
114
+
115
+ @skip_xp_backends('jax.numpy', reason='item assignment')
97
116
  class TestTaylor:
98
117
 
99
- def test_normalized(self):
118
+ def test_normalized(self, xp):
100
119
  """Tests windows of small length that are normalized to 1. See the
101
120
  documentation for the Taylor window for more information on
102
121
  normalization.
103
122
  """
104
- assert_allclose(windows.taylor(1, 2, 15), 1.0)
105
- assert_allclose(
106
- windows.taylor(5, 2, 15),
107
- np.array([0.75803341, 0.90757699, 1.0, 0.90757699, 0.75803341])
123
+ xp_assert_close(windows.taylor(1, 2, 15, xp=xp),
124
+ xp.asarray([1.0], dtype=xp.float64))
125
+ xp_assert_close(
126
+ windows.taylor(5, 2, 15, xp=xp),
127
+ xp.asarray([0.75803341, 0.90757699, 1.0, 0.90757699, 0.75803341],
128
+ dtype=xp.float64)
108
129
  )
109
- assert_allclose(
110
- windows.taylor(6, 2, 15),
111
- np.array([
130
+ xp_assert_close(
131
+ windows.taylor(6, 2, 15, xp=xp),
132
+ xp.asarray([
112
133
  0.7504082, 0.86624416, 0.98208011, 0.98208011, 0.86624416,
113
134
  0.7504082
114
- ])
135
+ ], dtype=xp.float64)
115
136
  )
116
137
 
117
- def test_non_normalized(self):
138
+ def test_non_normalized(self, xp):
118
139
  """Test windows of small length that are not normalized to 1. See
119
140
  the documentation for the Taylor window for more information on
120
141
  normalization.
121
142
  """
122
- assert_allclose(
123
- windows.taylor(5, 2, 15, norm=False),
124
- np.array([
143
+ xp_assert_close(
144
+ windows.taylor(5, 2, 15, norm=False, xp=xp),
145
+ xp.asarray([
125
146
  0.87508054, 1.04771499, 1.15440894, 1.04771499, 0.87508054
126
- ])
147
+ ], dtype=xp.float64)
127
148
  )
128
- assert_allclose(
129
- windows.taylor(6, 2, 15, norm=False),
130
- np.array([
149
+ xp_assert_close(
150
+ windows.taylor(6, 2, 15, norm=False, xp=xp),
151
+ xp.asarray([
131
152
  0.86627793, 1.0, 1.13372207, 1.13372207, 1.0, 0.86627793
132
- ])
153
+ ], dtype=xp.float64)
133
154
  )
134
155
 
135
- def test_correctness(self):
156
+ @skip_xp_backends(cpu_only=True)
157
+ def test_correctness(self, xp):
136
158
  """This test ensures the correctness of the implemented Taylor
137
159
  Windowing function. A Taylor Window of 1024 points is created, its FFT
138
160
  is taken, and the Peak Sidelobe Level (PSLL) and 3dB and 18dB bandwidth
@@ -152,131 +174,147 @@ class TestTaylor:
152
174
  # Set norm=False for correctness as the values obtained from the
153
175
  # scientific publication do not normalize the values. Normalizing
154
176
  # changes the sidelobe level from the desired value.
155
- w = windows.taylor(M_win, nbar=4, sll=35, norm=False, sym=False)
177
+ w = windows.taylor(M_win, nbar=4, sll=35, norm=False, sym=False, xp=xp)
156
178
  f = fft(w, N_fft)
157
- spec = 20 * np.log10(np.abs(f / np.amax(f)))
179
+
180
+ f_np = np.asarray(f)
181
+ spec = 20 * np.log10(np.abs(f_np / np.max(f_np)))
158
182
 
159
183
  first_zero = np.argmax(np.diff(spec) > 0)
160
184
 
161
- PSLL = np.amax(spec[first_zero:-first_zero])
185
+ PSLL = np.max(spec[first_zero:-first_zero])
162
186
 
163
187
  BW_3dB = 2*np.argmax(spec <= -3.0102999566398121) / N_fft * M_win
164
188
  BW_18dB = 2*np.argmax(spec <= -18.061799739838872) / N_fft * M_win
165
189
 
166
- assert_allclose(PSLL, -35.1672, atol=1)
167
- assert_allclose(BW_3dB, 1.1822, atol=0.1)
168
- assert_allclose(BW_18dB, 2.6112, atol=0.1)
190
+ assert math.isclose(PSLL, -35.1672, abs_tol=1)
191
+ assert math.isclose(BW_3dB, 1.1822, abs_tol=0.1)
192
+ assert math.isclose(BW_18dB, 2.6112, abs_tol=0.1)
169
193
 
170
194
 
171
195
  class TestBohman:
172
196
 
173
- def test_basic(self):
174
- assert_allclose(windows.bohman(6),
175
- [0, 0.1791238937062839, 0.8343114522576858,
176
- 0.8343114522576858, 0.1791238937062838, 0])
177
- assert_allclose(windows.bohman(7, sym=True),
178
- [0, 0.1089977810442293, 0.6089977810442293, 1.0,
179
- 0.6089977810442295, 0.1089977810442293, 0])
180
- assert_allclose(windows.bohman(6, False),
181
- [0, 0.1089977810442293, 0.6089977810442293, 1.0,
182
- 0.6089977810442295, 0.1089977810442293])
197
+ def test_basic(self, xp):
198
+ xp_assert_close(windows.bohman(6, xp=xp),
199
+ xp.asarray([0, 0.1791238937062839, 0.8343114522576858,
200
+ 0.8343114522576858, 0.1791238937062838, 0],
201
+ dtype=xp.float64))
202
+ xp_assert_close(windows.bohman(7, sym=True, xp=xp),
203
+ xp.asarray([0, 0.1089977810442293, 0.6089977810442293, 1.0,
204
+ 0.6089977810442295, 0.1089977810442293, 0],
205
+ dtype=xp.float64))
206
+ xp_assert_close(windows.bohman(6, False, xp=xp),
207
+ xp.asarray([0, 0.1089977810442293, 0.6089977810442293, 1.0,
208
+ 0.6089977810442295, 0.1089977810442293],
209
+ dtype=xp.float64))
183
210
 
184
211
 
185
212
  class TestBoxcar:
186
213
 
187
- def test_basic(self):
188
- assert_allclose(windows.boxcar(6), [1, 1, 1, 1, 1, 1])
189
- assert_allclose(windows.boxcar(7), [1, 1, 1, 1, 1, 1, 1])
190
- assert_allclose(windows.boxcar(6, False), [1, 1, 1, 1, 1, 1])
191
-
192
-
193
- cheb_odd_true = array([0.200938, 0.107729, 0.134941, 0.165348,
194
- 0.198891, 0.235450, 0.274846, 0.316836,
195
- 0.361119, 0.407338, 0.455079, 0.503883,
196
- 0.553248, 0.602637, 0.651489, 0.699227,
197
- 0.745266, 0.789028, 0.829947, 0.867485,
198
- 0.901138, 0.930448, 0.955010, 0.974482,
199
- 0.988591, 0.997138, 1.000000, 0.997138,
200
- 0.988591, 0.974482, 0.955010, 0.930448,
201
- 0.901138, 0.867485, 0.829947, 0.789028,
202
- 0.745266, 0.699227, 0.651489, 0.602637,
203
- 0.553248, 0.503883, 0.455079, 0.407338,
204
- 0.361119, 0.316836, 0.274846, 0.235450,
205
- 0.198891, 0.165348, 0.134941, 0.107729,
206
- 0.200938])
207
-
208
- cheb_even_true = array([0.203894, 0.107279, 0.133904,
209
- 0.163608, 0.196338, 0.231986,
210
- 0.270385, 0.311313, 0.354493,
211
- 0.399594, 0.446233, 0.493983,
212
- 0.542378, 0.590916, 0.639071,
213
- 0.686302, 0.732055, 0.775783,
214
- 0.816944, 0.855021, 0.889525,
215
- 0.920006, 0.946060, 0.967339,
216
- 0.983557, 0.994494, 1.000000,
217
- 1.000000, 0.994494, 0.983557,
218
- 0.967339, 0.946060, 0.920006,
219
- 0.889525, 0.855021, 0.816944,
220
- 0.775783, 0.732055, 0.686302,
221
- 0.639071, 0.590916, 0.542378,
222
- 0.493983, 0.446233, 0.399594,
223
- 0.354493, 0.311313, 0.270385,
224
- 0.231986, 0.196338, 0.163608,
225
- 0.133904, 0.107279, 0.203894])
226
-
227
-
214
+ def test_basic(self, xp):
215
+ xp_assert_close(windows.boxcar(6, xp=xp),
216
+ xp.asarray([1.0, 1, 1, 1, 1, 1], dtype=xp.float64))
217
+ xp_assert_close(windows.boxcar(7, xp=xp),
218
+ xp.asarray([1.0, 1, 1, 1, 1, 1, 1], dtype=xp.float64))
219
+ xp_assert_close(windows.boxcar(6, False, xp=xp),
220
+ xp.asarray([1.0, 1, 1, 1, 1, 1], dtype=xp.float64))
221
+
222
+
223
+ cheb_odd_true = [0.200938, 0.107729, 0.134941, 0.165348,
224
+ 0.198891, 0.235450, 0.274846, 0.316836,
225
+ 0.361119, 0.407338, 0.455079, 0.503883,
226
+ 0.553248, 0.602637, 0.651489, 0.699227,
227
+ 0.745266, 0.789028, 0.829947, 0.867485,
228
+ 0.901138, 0.930448, 0.955010, 0.974482,
229
+ 0.988591, 0.997138, 1.000000, 0.997138,
230
+ 0.988591, 0.974482, 0.955010, 0.930448,
231
+ 0.901138, 0.867485, 0.829947, 0.789028,
232
+ 0.745266, 0.699227, 0.651489, 0.602637,
233
+ 0.553248, 0.503883, 0.455079, 0.407338,
234
+ 0.361119, 0.316836, 0.274846, 0.235450,
235
+ 0.198891, 0.165348, 0.134941, 0.107729,
236
+ 0.200938]
237
+
238
+ cheb_even_true = [0.203894, 0.107279, 0.133904,
239
+ 0.163608, 0.196338, 0.231986,
240
+ 0.270385, 0.311313, 0.354493,
241
+ 0.399594, 0.446233, 0.493983,
242
+ 0.542378, 0.590916, 0.639071,
243
+ 0.686302, 0.732055, 0.775783,
244
+ 0.816944, 0.855021, 0.889525,
245
+ 0.920006, 0.946060, 0.967339,
246
+ 0.983557, 0.994494, 1.000000,
247
+ 1.000000, 0.994494, 0.983557,
248
+ 0.967339, 0.946060, 0.920006,
249
+ 0.889525, 0.855021, 0.816944,
250
+ 0.775783, 0.732055, 0.686302,
251
+ 0.639071, 0.590916, 0.542378,
252
+ 0.493983, 0.446233, 0.399594,
253
+ 0.354493, 0.311313, 0.270385,
254
+ 0.231986, 0.196338, 0.163608,
255
+ 0.133904, 0.107279, 0.203894]
256
+
257
+
258
+ @skip_xp_backends('jax.numpy', reason='item assignment')
259
+ @skip_xp_backends('dask.array', reason='data-dependent output shapes')
228
260
  class TestChebWin:
229
261
 
230
- def test_basic(self):
262
+ def test_basic(self, xp):
231
263
  with suppress_warnings() as sup:
232
264
  sup.filter(UserWarning, "This window is not suitable")
233
- assert_allclose(windows.chebwin(6, 100),
234
- [0.1046401879356917, 0.5075781475823447, 1.0, 1.0,
235
- 0.5075781475823447, 0.1046401879356917])
236
- assert_allclose(windows.chebwin(7, 100),
237
- [0.05650405062850233, 0.316608530648474,
238
- 0.7601208123539079, 1.0, 0.7601208123539079,
239
- 0.316608530648474, 0.05650405062850233])
240
- assert_allclose(windows.chebwin(6, 10),
241
- [1.0, 0.6071201674458373, 0.6808391469897297,
242
- 0.6808391469897297, 0.6071201674458373, 1.0])
243
- assert_allclose(windows.chebwin(7, 10),
244
- [1.0, 0.5190521247588651, 0.5864059018130382,
245
- 0.6101519801307441, 0.5864059018130382,
246
- 0.5190521247588651, 1.0])
247
- assert_allclose(windows.chebwin(6, 10, False),
248
- [1.0, 0.5190521247588651, 0.5864059018130382,
249
- 0.6101519801307441, 0.5864059018130382,
250
- 0.5190521247588651])
251
-
252
- def test_cheb_odd_high_attenuation(self):
265
+ xp_assert_close(windows.chebwin(6, 100, xp=xp),
266
+ xp.asarray([0.1046401879356917, 0.5075781475823447,
267
+ 1.0, 1.0,
268
+ 0.5075781475823447, 0.1046401879356917],
269
+ dtype=xp.float64),
270
+ atol=1e-8
271
+ )
272
+ xp_assert_close(windows.chebwin(7, 100, xp=xp),
273
+ xp.asarray([0.05650405062850233, 0.316608530648474,
274
+ 0.7601208123539079, 1.0, 0.7601208123539079,
275
+ 0.316608530648474, 0.05650405062850233],
276
+ dtype=xp.float64))
277
+ xp_assert_close(windows.chebwin(6, 10, xp=xp),
278
+ xp.asarray([1.0, 0.6071201674458373, 0.6808391469897297,
279
+ 0.6808391469897297, 0.6071201674458373, 1.0],
280
+ dtype=xp.float64))
281
+ xp_assert_close(windows.chebwin(7, 10, xp=xp),
282
+ xp.asarray([1.0, 0.5190521247588651, 0.5864059018130382,
283
+ 0.6101519801307441, 0.5864059018130382,
284
+ 0.5190521247588651, 1.0], dtype=xp.float64))
285
+ xp_assert_close(windows.chebwin(6, 10, False, xp=xp),
286
+ xp.asarray([1.0, 0.5190521247588651, 0.5864059018130382,
287
+ 0.6101519801307441, 0.5864059018130382,
288
+ 0.5190521247588651], dtype=xp.float64))
289
+
290
+ def test_cheb_odd_high_attenuation(self, xp):
253
291
  with suppress_warnings() as sup:
254
292
  sup.filter(UserWarning, "This window is not suitable")
255
- cheb_odd = windows.chebwin(53, at=-40)
256
- assert_array_almost_equal(cheb_odd, cheb_odd_true, decimal=4)
293
+ cheb_odd = windows.chebwin(53, at=-40, xp=xp)
294
+ assert_array_almost_equal(cheb_odd, xp.asarray(cheb_odd_true), decimal=4)
257
295
 
258
- def test_cheb_even_high_attenuation(self):
296
+ def test_cheb_even_high_attenuation(self, xp):
259
297
  with suppress_warnings() as sup:
260
298
  sup.filter(UserWarning, "This window is not suitable")
261
- cheb_even = windows.chebwin(54, at=40)
262
- assert_array_almost_equal(cheb_even, cheb_even_true, decimal=4)
299
+ cheb_even = windows.chebwin(54, at=40, xp=xp)
300
+ assert_array_almost_equal(cheb_even, xp.asarray(cheb_even_true), decimal=4)
263
301
 
264
- def test_cheb_odd_low_attenuation(self):
265
- cheb_odd_low_at_true = array([1.000000, 0.519052, 0.586405,
266
- 0.610151, 0.586405, 0.519052,
267
- 1.000000])
302
+ def test_cheb_odd_low_attenuation(self, xp):
303
+ cheb_odd_low_at_true = xp.asarray([1.000000, 0.519052, 0.586405,
304
+ 0.610151, 0.586405, 0.519052,
305
+ 1.000000], dtype=xp.float64)
268
306
  with suppress_warnings() as sup:
269
307
  sup.filter(UserWarning, "This window is not suitable")
270
- cheb_odd = windows.chebwin(7, at=10)
308
+ cheb_odd = windows.chebwin(7, at=10, xp=xp)
271
309
  assert_array_almost_equal(cheb_odd, cheb_odd_low_at_true, decimal=4)
272
310
 
273
- def test_cheb_even_low_attenuation(self):
274
- cheb_even_low_at_true = array([1.000000, 0.451924, 0.51027,
275
- 0.541338, 0.541338, 0.51027,
276
- 0.451924, 1.000000])
311
+ def test_cheb_even_low_attenuation(self, xp):
312
+ cheb_even_low_at_true = xp.asarray([1.000000, 0.451924, 0.51027,
313
+ 0.541338, 0.541338, 0.51027,
314
+ 0.451924, 1.000000], dtype=xp.float64)
277
315
  with suppress_warnings() as sup:
278
316
  sup.filter(UserWarning, "This window is not suitable")
279
- cheb_even = windows.chebwin(8, at=-10)
317
+ cheb_even = windows.chebwin(8, at=-10, xp=xp)
280
318
  assert_array_almost_equal(cheb_even, cheb_even_low_at_true, decimal=4)
281
319
 
282
320
 
@@ -309,224 +347,255 @@ exponential_data = {
309
347
  }
310
348
 
311
349
 
312
- def test_exponential():
350
+ def test_exponential(xp):
313
351
  for k, v in exponential_data.items():
314
352
  if v is None:
315
- assert_raises(ValueError, windows.exponential, *k)
353
+ assert_raises(ValueError, windows.exponential, *k, xp=xp)
316
354
  else:
317
- win = windows.exponential(*k)
318
- assert_allclose(win, v, rtol=1e-14)
355
+ win = windows.exponential(*k, xp=xp)
356
+ xp_assert_close(win, xp.asarray(v), rtol=1e-14)
319
357
 
320
358
 
321
359
  class TestFlatTop:
322
360
 
323
- def test_basic(self):
324
- assert_allclose(windows.flattop(6, sym=False),
325
- [-0.000421051, -0.051263156, 0.19821053, 1.0,
326
- 0.19821053, -0.051263156])
327
- assert_allclose(windows.flattop(7, sym=False),
328
- [-0.000421051, -0.03684078115492348,
329
- 0.01070371671615342, 0.7808739149387698,
330
- 0.7808739149387698, 0.01070371671615342,
331
- -0.03684078115492348])
332
- assert_allclose(windows.flattop(6),
333
- [-0.000421051, -0.0677142520762119, 0.6068721525762117,
334
- 0.6068721525762117, -0.0677142520762119,
335
- -0.000421051])
336
- assert_allclose(windows.flattop(7, True),
337
- [-0.000421051, -0.051263156, 0.19821053, 1.0,
338
- 0.19821053, -0.051263156, -0.000421051])
361
+ def test_basic(self, xp):
362
+ xp_assert_close(windows.flattop(6, sym=False, xp=xp),
363
+ xp.asarray([-0.000421051, -0.051263156, 0.19821053, 1.0,
364
+ 0.19821053, -0.051263156], dtype=xp.float64))
365
+ xp_assert_close(windows.flattop(7, sym=False, xp=xp),
366
+ xp.asarray([-0.000421051, -0.03684078115492348,
367
+ 0.01070371671615342, 0.7808739149387698,
368
+ 0.7808739149387698, 0.01070371671615342,
369
+ -0.03684078115492348], dtype=xp.float64))
370
+ xp_assert_close(windows.flattop(6, xp=xp),
371
+ xp.asarray([-0.000421051, -0.0677142520762119,
372
+ 0.6068721525762117, 0.6068721525762117,
373
+ -0.0677142520762119, -0.000421051],
374
+ dtype=xp.float64))
375
+ xp_assert_close(windows.flattop(7, True, xp=xp),
376
+ xp.asarray([-0.000421051, -0.051263156, 0.19821053, 1.0,
377
+ 0.19821053, -0.051263156, -0.000421051],
378
+ dtype=xp.float64))
339
379
 
340
380
 
341
381
  class TestGaussian:
342
382
 
343
- def test_basic(self):
344
- assert_allclose(windows.gaussian(6, 1.0),
345
- [0.04393693362340742, 0.3246524673583497,
346
- 0.8824969025845955, 0.8824969025845955,
347
- 0.3246524673583497, 0.04393693362340742])
348
- assert_allclose(windows.gaussian(7, 1.2),
349
- [0.04393693362340742, 0.2493522087772962,
350
- 0.7066482778577162, 1.0, 0.7066482778577162,
351
- 0.2493522087772962, 0.04393693362340742])
352
- assert_allclose(windows.gaussian(7, 3),
353
- [0.6065306597126334, 0.8007374029168081,
354
- 0.9459594689067654, 1.0, 0.9459594689067654,
355
- 0.8007374029168081, 0.6065306597126334])
356
- assert_allclose(windows.gaussian(6, 3, False),
357
- [0.6065306597126334, 0.8007374029168081,
358
- 0.9459594689067654, 1.0, 0.9459594689067654,
359
- 0.8007374029168081])
383
+ def test_basic(self, xp):
384
+ xp_assert_close(windows.gaussian(6, 1.0, xp=xp),
385
+ xp.asarray([0.04393693362340742, 0.3246524673583497,
386
+ 0.8824969025845955, 0.8824969025845955,
387
+ 0.3246524673583497, 0.04393693362340742],
388
+ dtype=xp.float64))
389
+ xp_assert_close(windows.gaussian(7, 1.2, xp=xp),
390
+ xp.asarray([0.04393693362340742, 0.2493522087772962,
391
+ 0.7066482778577162, 1.0, 0.7066482778577162,
392
+ 0.2493522087772962, 0.04393693362340742],
393
+ dtype=xp.float64))
394
+ xp_assert_close(windows.gaussian(7, 3, xp=xp),
395
+ xp.asarray([0.6065306597126334, 0.8007374029168081,
396
+ 0.9459594689067654, 1.0, 0.9459594689067654,
397
+ 0.8007374029168081, 0.6065306597126334],
398
+ dtype=xp.float64))
399
+ xp_assert_close(windows.gaussian(6, 3, False, xp=xp),
400
+ xp.asarray([0.6065306597126334, 0.8007374029168081,
401
+ 0.9459594689067654, 1.0, 0.9459594689067654,
402
+ 0.8007374029168081], dtype=xp.float64))
360
403
 
361
404
 
362
405
  class TestGeneralCosine:
363
406
 
364
- def test_basic(self):
365
- assert_allclose(windows.general_cosine(5, [0.5, 0.3, 0.2]),
366
- [0.4, 0.3, 1, 0.3, 0.4])
367
- assert_allclose(windows.general_cosine(4, [0.5, 0.3, 0.2], sym=False),
368
- [0.4, 0.3, 1, 0.3])
407
+ def test_basic(self, xp):
408
+ a = xp.asarray([0.5, 0.3, 0.2])
409
+ xp_assert_close(windows.general_cosine(5, a),
410
+ xp.asarray([0.4, 0.3, 1, 0.3, 0.4], dtype=xp.float64))
411
+
412
+ a = xp.asarray([0.5, 0.3, 0.2])
413
+ xp_assert_close(windows.general_cosine(4, a, sym=False),
414
+ xp.asarray([0.4, 0.3, 1, 0.3], dtype=xp.float64))
369
415
 
370
416
 
371
417
  class TestGeneralHamming:
372
418
 
373
- def test_basic(self):
374
- assert_allclose(windows.general_hamming(5, 0.7),
375
- [0.4, 0.7, 1.0, 0.7, 0.4])
376
- assert_allclose(windows.general_hamming(5, 0.75, sym=False),
377
- [0.5, 0.6727457514, 0.9522542486,
378
- 0.9522542486, 0.6727457514])
379
- assert_allclose(windows.general_hamming(6, 0.75, sym=True),
380
- [0.5, 0.6727457514, 0.9522542486,
381
- 0.9522542486, 0.6727457514, 0.5])
419
+ def test_basic(self, xp):
420
+ xp_assert_close(windows.general_hamming(5, 0.7, xp=xp),
421
+ xp.asarray([0.4, 0.7, 1.0, 0.7, 0.4], dtype=xp.float64))
422
+ xp_assert_close(windows.general_hamming(5, 0.75, sym=False, xp=xp),
423
+ xp.asarray([0.5, 0.6727457514, 0.9522542486,
424
+ 0.9522542486, 0.6727457514], dtype=xp.float64))
425
+ xp_assert_close(windows.general_hamming(6, 0.75, sym=True, xp=xp),
426
+ xp.asarray([0.5, 0.6727457514, 0.9522542486,
427
+ 0.9522542486, 0.6727457514, 0.5], dtype=xp.float64))
382
428
 
383
429
 
384
430
  class TestHamming:
385
431
 
386
- def test_basic(self):
387
- assert_allclose(windows.hamming(6, False),
388
- [0.08, 0.31, 0.77, 1.0, 0.77, 0.31])
389
- assert_allclose(windows.hamming(7, sym=False),
390
- [0.08, 0.2531946911449826, 0.6423596296199047,
391
- 0.9544456792351128, 0.9544456792351128,
392
- 0.6423596296199047, 0.2531946911449826])
393
- assert_allclose(windows.hamming(6),
394
- [0.08, 0.3978521825875242, 0.9121478174124757,
395
- 0.9121478174124757, 0.3978521825875242, 0.08])
396
- assert_allclose(windows.hamming(7, sym=True),
397
- [0.08, 0.31, 0.77, 1.0, 0.77, 0.31, 0.08])
432
+ def test_basic(self, xp):
433
+ xp_assert_close(windows.hamming(6, False, xp=xp),
434
+ xp.asarray([0.08, 0.31, 0.77, 1.0, 0.77, 0.31],
435
+ dtype=xp.float64))
436
+ xp_assert_close(windows.hamming(7, sym=False, xp=xp),
437
+ xp.asarray([0.08, 0.2531946911449826, 0.6423596296199047,
438
+ 0.9544456792351128, 0.9544456792351128,
439
+ 0.6423596296199047, 0.2531946911449826],
440
+ dtype=xp.float64))
441
+ xp_assert_close(windows.hamming(6, xp=xp),
442
+ xp.asarray([0.08, 0.3978521825875242, 0.9121478174124757,
443
+ 0.9121478174124757, 0.3978521825875242, 0.08],
444
+ dtype=xp.float64))
445
+ xp_assert_close(windows.hamming(7, sym=True, xp=xp),
446
+ xp.asarray([0.08, 0.31, 0.77, 1.0, 0.77, 0.31, 0.08],
447
+ dtype=xp.float64))
398
448
 
399
449
 
400
450
  class TestHann:
401
451
 
402
- def test_basic(self):
403
- assert_allclose(windows.hann(6, sym=False),
404
- [0, 0.25, 0.75, 1.0, 0.75, 0.25],
452
+ def test_basic(self, xp):
453
+ xp_assert_close(windows.hann(6, sym=False, xp=xp),
454
+ xp.asarray([0, 0.25, 0.75, 1.0, 0.75, 0.25], dtype=xp.float64),
405
455
  rtol=1e-15, atol=1e-15)
406
- assert_allclose(windows.hann(7, sym=False),
407
- [0, 0.1882550990706332, 0.6112604669781572,
408
- 0.9504844339512095, 0.9504844339512095,
409
- 0.6112604669781572, 0.1882550990706332],
456
+ xp_assert_close(windows.hann(7, sym=False, xp=xp),
457
+ xp.asarray([0, 0.1882550990706332, 0.6112604669781572,
458
+ 0.9504844339512095, 0.9504844339512095,
459
+ 0.6112604669781572, 0.1882550990706332],
460
+ dtype=xp.float64),
410
461
  rtol=1e-15, atol=1e-15)
411
- assert_allclose(windows.hann(6, True),
412
- [0, 0.3454915028125263, 0.9045084971874737,
413
- 0.9045084971874737, 0.3454915028125263, 0],
462
+ xp_assert_close(windows.hann(6, True, xp=xp),
463
+ xp.asarray([0, 0.3454915028125263, 0.9045084971874737,
464
+ 0.9045084971874737, 0.3454915028125263, 0],
465
+ dtype=xp.float64),
414
466
  rtol=1e-15, atol=1e-15)
415
- assert_allclose(windows.hann(7),
416
- [0, 0.25, 0.75, 1.0, 0.75, 0.25, 0],
467
+ xp_assert_close(windows.hann(7, xp=xp),
468
+ xp.asarray([0, 0.25, 0.75, 1.0, 0.75, 0.25, 0],
469
+ dtype=xp.float64),
417
470
  rtol=1e-15, atol=1e-15)
418
471
 
419
472
 
420
473
  class TestKaiser:
421
474
 
422
- def test_basic(self):
423
- assert_allclose(windows.kaiser(6, 0.5),
424
- [0.9403061933191572, 0.9782962393705389,
425
- 0.9975765035372042, 0.9975765035372042,
426
- 0.9782962393705389, 0.9403061933191572])
427
- assert_allclose(windows.kaiser(7, 0.5),
428
- [0.9403061933191572, 0.9732402256999829,
429
- 0.9932754654413773, 1.0, 0.9932754654413773,
430
- 0.9732402256999829, 0.9403061933191572])
431
- assert_allclose(windows.kaiser(6, 2.7),
432
- [0.2603047507678832, 0.6648106293528054,
433
- 0.9582099802511439, 0.9582099802511439,
434
- 0.6648106293528054, 0.2603047507678832])
435
- assert_allclose(windows.kaiser(7, 2.7),
436
- [0.2603047507678832, 0.5985765418119844,
437
- 0.8868495172060835, 1.0, 0.8868495172060835,
438
- 0.5985765418119844, 0.2603047507678832])
439
- assert_allclose(windows.kaiser(6, 2.7, False),
440
- [0.2603047507678832, 0.5985765418119844,
441
- 0.8868495172060835, 1.0, 0.8868495172060835,
442
- 0.5985765418119844])
475
+ def test_basic(self, xp):
476
+ xp_assert_close(windows.kaiser(6, 0.5, xp=xp),
477
+ xp.asarray([0.9403061933191572, 0.9782962393705389,
478
+ 0.9975765035372042, 0.9975765035372042,
479
+ 0.9782962393705389, 0.9403061933191572],
480
+ dtype=xp.float64))
481
+ xp_assert_close(windows.kaiser(7, 0.5, xp=xp),
482
+ xp.asarray([0.9403061933191572, 0.9732402256999829,
483
+ 0.9932754654413773, 1.0, 0.9932754654413773,
484
+ 0.9732402256999829, 0.9403061933191572],
485
+ dtype=xp.float64))
486
+ xp_assert_close(windows.kaiser(6, 2.7, xp=xp),
487
+ xp.asarray([0.2603047507678832, 0.6648106293528054,
488
+ 0.9582099802511439, 0.9582099802511439,
489
+ 0.6648106293528054, 0.2603047507678832],
490
+ dtype=xp.float64))
491
+ xp_assert_close(windows.kaiser(7, 2.7, xp=xp),
492
+ xp.asarray([0.2603047507678832, 0.5985765418119844,
493
+ 0.8868495172060835, 1.0, 0.8868495172060835,
494
+ 0.5985765418119844, 0.2603047507678832],
495
+ dtype=xp.float64))
496
+ xp_assert_close(windows.kaiser(6, 2.7, False, xp=xp),
497
+ xp.asarray([0.2603047507678832, 0.5985765418119844,
498
+ 0.8868495172060835, 1.0, 0.8868495172060835,
499
+ 0.5985765418119844], dtype=xp.float64))
443
500
 
444
501
 
445
502
  class TestKaiserBesselDerived:
446
503
 
447
- def test_basic(self):
504
+ def test_basic(self, xp):
505
+ # cover case `M < 1`
506
+ w = windows.kaiser_bessel_derived(0.5, beta=4.0, xp=xp)
507
+ xp_assert_equal(w, xp.asarray([]))
508
+
448
509
  M = 100
449
- w = windows.kaiser_bessel_derived(M, beta=4.0)
510
+ w = windows.kaiser_bessel_derived(M, beta=4.0, xp=xp)
450
511
  w2 = windows.get_window(('kaiser bessel derived', 4.0),
451
- M, fftbins=False)
452
- assert_allclose(w, w2)
512
+ M, fftbins=False, xp=xp)
513
+ xp_assert_close(w, w2)
453
514
 
454
515
  # Test for Princen-Bradley condition
455
- assert_allclose(w[:M // 2] ** 2 + w[-M // 2:] ** 2, 1.)
516
+ actual = w[:M // 2] ** 2 + w[-M // 2:] ** 2
517
+ xp_assert_close(actual, xp.ones(actual.shape, dtype=actual.dtype))
456
518
 
457
519
  # Test actual values from other implementations
458
520
  # M = 2: sqrt(2) / 2
459
521
  # M = 4: 0.518562710536, 0.855039598640
460
522
  # M = 6: 0.436168993154, 0.707106781187, 0.899864772847
461
523
  # Ref:https://github.com/scipy/scipy/pull/4747#issuecomment-172849418
462
- assert_allclose(windows.kaiser_bessel_derived(2, beta=np.pi / 2)[:1],
463
- np.sqrt(2) / 2)
524
+ actual = windows.kaiser_bessel_derived(2, beta=np.pi / 2, xp=xp)[:1]
525
+ desired = xp.ones_like(actual) * math.sqrt(2) / 2.0
526
+ xp_assert_close(actual, desired)
464
527
 
465
- assert_allclose(windows.kaiser_bessel_derived(4, beta=np.pi / 2)[:2],
466
- [0.518562710536, 0.855039598640])
528
+ xp_assert_close(windows.kaiser_bessel_derived(4, beta=np.pi / 2, xp=xp)[:2],
529
+ xp.asarray([0.518562710536, 0.855039598640], dtype=xp.float64))
467
530
 
468
- assert_allclose(windows.kaiser_bessel_derived(6, beta=np.pi / 2)[:3],
469
- [0.436168993154, 0.707106781187, 0.899864772847])
531
+ xp_assert_close(windows.kaiser_bessel_derived(6, beta=np.pi / 2, xp=xp)[:3],
532
+ xp.asarray([0.436168993154, 0.707106781187, 0.899864772847],
533
+ dtype=xp.float64))
470
534
 
471
- def test_exceptions(self):
535
+ def test_exceptions(self, xp):
472
536
  M = 100
473
537
  # Assert ValueError for odd window length
474
538
  msg = ("Kaiser-Bessel Derived windows are only defined for even "
475
539
  "number of points")
476
540
  with assert_raises(ValueError, match=msg):
477
- windows.kaiser_bessel_derived(M + 1, beta=4.)
541
+ windows.kaiser_bessel_derived(M + 1, beta=4., xp=xp)
478
542
 
479
543
  # Assert ValueError for non-symmetric setting
480
544
  msg = ("Kaiser-Bessel Derived windows are only defined for "
481
545
  "symmetric shapes")
482
546
  with assert_raises(ValueError, match=msg):
483
- windows.kaiser_bessel_derived(M + 1, beta=4., sym=False)
547
+ windows.kaiser_bessel_derived(M + 1, beta=4., sym=False, xp=xp)
484
548
 
485
549
 
486
550
  class TestNuttall:
487
551
 
488
- def test_basic(self):
489
- assert_allclose(windows.nuttall(6, sym=False),
490
- [0.0003628, 0.0613345, 0.5292298, 1.0, 0.5292298,
491
- 0.0613345])
492
- assert_allclose(windows.nuttall(7, sym=False),
493
- [0.0003628, 0.03777576895352025, 0.3427276199688195,
494
- 0.8918518610776603, 0.8918518610776603,
495
- 0.3427276199688196, 0.0377757689535203])
496
- assert_allclose(windows.nuttall(6),
497
- [0.0003628, 0.1105152530498718, 0.7982580969501282,
498
- 0.7982580969501283, 0.1105152530498719, 0.0003628])
499
- assert_allclose(windows.nuttall(7, True),
500
- [0.0003628, 0.0613345, 0.5292298, 1.0, 0.5292298,
501
- 0.0613345, 0.0003628])
552
+ def test_basic(self, xp):
553
+ xp_assert_close(windows.nuttall(6, sym=False, xp=xp),
554
+ xp.asarray([0.0003628, 0.0613345, 0.5292298, 1.0, 0.5292298,
555
+ 0.0613345], dtype=xp.float64))
556
+ xp_assert_close(windows.nuttall(7, sym=False, xp=xp),
557
+ xp.asarray([0.0003628, 0.03777576895352025,
558
+ 0.3427276199688195,
559
+ 0.8918518610776603, 0.8918518610776603,
560
+ 0.3427276199688196, 0.0377757689535203],
561
+ dtype=xp.float64))
562
+ xp_assert_close(windows.nuttall(6, xp=xp),
563
+ xp.asarray([0.0003628, 0.1105152530498718,
564
+ 0.7982580969501282, 0.7982580969501283,
565
+ 0.1105152530498719, 0.0003628], dtype=xp.float64))
566
+ xp_assert_close(windows.nuttall(7, True, xp=xp),
567
+ xp.asarray([0.0003628, 0.0613345, 0.5292298, 1.0,
568
+ 0.5292298, 0.0613345, 0.0003628], dtype=xp.float64))
502
569
 
503
570
 
504
571
  class TestParzen:
505
572
 
506
- def test_basic(self):
507
- assert_allclose(windows.parzen(6),
508
- [0.009259259259259254, 0.25, 0.8611111111111112,
509
- 0.8611111111111112, 0.25, 0.009259259259259254])
510
- assert_allclose(windows.parzen(7, sym=True),
511
- [0.00583090379008747, 0.1574344023323616,
512
- 0.6501457725947521, 1.0, 0.6501457725947521,
513
- 0.1574344023323616, 0.00583090379008747])
514
- assert_allclose(windows.parzen(6, False),
515
- [0.00583090379008747, 0.1574344023323616,
516
- 0.6501457725947521, 1.0, 0.6501457725947521,
517
- 0.1574344023323616])
573
+ def test_basic(self, xp):
574
+ xp_assert_close(windows.parzen(6, xp=xp),
575
+ xp.asarray([0.009259259259259254, 0.25, 0.8611111111111112,
576
+ 0.8611111111111112, 0.25, 0.009259259259259254],
577
+ dtype=xp.float64))
578
+ xp_assert_close(windows.parzen(7, sym=True, xp=xp),
579
+ xp.asarray([0.00583090379008747, 0.1574344023323616,
580
+ 0.6501457725947521, 1.0, 0.6501457725947521,
581
+ 0.1574344023323616, 0.00583090379008747],
582
+ dtype=xp.float64))
583
+ xp_assert_close(windows.parzen(6, False, xp=xp),
584
+ xp.asarray([0.00583090379008747, 0.1574344023323616,
585
+ 0.6501457725947521, 1.0, 0.6501457725947521,
586
+ 0.1574344023323616], dtype=xp.float64))
518
587
 
519
588
 
520
589
  class TestTriang:
521
590
 
522
- def test_basic(self):
591
+ def test_basic(self, xp):
523
592
 
524
- assert_allclose(windows.triang(6, True),
525
- [1/6, 1/2, 5/6, 5/6, 1/2, 1/6])
526
- assert_allclose(windows.triang(7),
527
- [1/4, 1/2, 3/4, 1, 3/4, 1/2, 1/4])
528
- assert_allclose(windows.triang(6, sym=False),
529
- [1/4, 1/2, 3/4, 1, 3/4, 1/2])
593
+ xp_assert_close(windows.triang(6, True, xp=xp),
594
+ xp.asarray([1/6, 1/2, 5/6, 5/6, 1/2, 1/6], dtype=xp.float64))
595
+ xp_assert_close(windows.triang(7, xp=xp),
596
+ xp.asarray([1/4, 1/2, 3/4, 1, 3/4, 1/2, 1/4], dtype=xp.float64))
597
+ xp_assert_close(windows.triang(6, sym=False, xp=xp),
598
+ xp.asarray([1/4, 1/2, 3/4, 1, 3/4, 1/2], dtype=xp.float64))
530
599
 
531
600
 
532
601
  tukey_data = {
@@ -543,10 +612,10 @@ tukey_data = {
543
612
  1.0, 0.69134171618254492, 0.0]),
544
613
  (5, 1.0, True): array([0.0, 0.5, 1.0, 0.5, 0.0]),
545
614
 
546
- (6, 0): [1, 1, 1, 1, 1, 1],
547
- (7, 0): [1, 1, 1, 1, 1, 1, 1],
548
- (6, .25): [0, 1, 1, 1, 1, 0],
549
- (7, .25): [0, 1, 1, 1, 1, 1, 0],
615
+ (6, 0): [1.0, 1, 1, 1, 1, 1],
616
+ (7, 0): [1.0, 1, 1, 1, 1, 1, 1],
617
+ (6, .25): [0.0, 1, 1, 1, 1, 0],
618
+ (7, .25): [0.0, 1, 1, 1, 1, 1, 0],
550
619
  (6,): [0, 0.9045084971874737, 1.0, 1.0, 0.9045084971874735, 0],
551
620
  (7,): [0, 0.75, 1.0, 1.0, 1.0, 0.75, 0],
552
621
  (6, .75): [0, 0.5522642316338269, 1.0, 1.0, 0.5522642316338267, 0],
@@ -560,24 +629,30 @@ tukey_data = {
560
629
 
561
630
  class TestTukey:
562
631
 
563
- def test_basic(self):
632
+ def test_basic(self, xp):
564
633
  # Test against hardcoded data
565
634
  for k, v in tukey_data.items():
566
635
  if v is None:
567
- assert_raises(ValueError, windows.tukey, *k)
636
+ assert_raises(ValueError, windows.tukey, *k, xp=xp)
568
637
  else:
569
- win = windows.tukey(*k)
570
- assert_allclose(win, v, rtol=1e-15, atol=1e-15)
638
+ if is_torch(xp) and k in [(6,), (6, .75), (7, .75), (6,1)]:
639
+ atol_rtol = {'rtol': 3e-8, 'atol': 1e-8}
640
+ else:
641
+ atol_rtol = {'rtol': 1e-15, 'atol': 1e-15 }
642
+
643
+ win = windows.tukey(*k, xp=xp)
644
+ xp_assert_close(win, xp.asarray(v),
645
+ check_dtype=False, **atol_rtol)
571
646
 
572
- def test_extremes(self):
647
+ def test_extremes(self, xp):
573
648
  # Test extremes of alpha correspond to boxcar and hann
574
- tuk0 = windows.tukey(100, 0)
575
- box0 = windows.boxcar(100)
576
- assert_array_almost_equal(tuk0, box0)
649
+ tuk0 = windows.tukey(100, 0, xp=xp)
650
+ box0 = windows.boxcar(100, xp=xp)
651
+ xp_assert_close(tuk0, box0)
577
652
 
578
- tuk1 = windows.tukey(100, 1)
579
- han1 = windows.hann(100)
580
- assert_array_almost_equal(tuk1, han1)
653
+ tuk1 = windows.tukey(100, 1, xp=xp)
654
+ han1 = windows.hann(100, xp=xp)
655
+ xp_assert_close(tuk1, han1)
581
656
 
582
657
 
583
658
  dpss_data = {
@@ -591,46 +666,47 @@ dpss_data = {
591
666
  }
592
667
 
593
668
 
669
+ @skip_xp_backends(np_only=True, reason='banded linear algebra is numpy-only')
594
670
  class TestDPSS:
595
671
 
596
- def test_basic(self):
672
+ def test_basic(self, xp):
597
673
  # Test against hardcoded data
598
674
  for k, v in dpss_data.items():
599
- win, ratios = windows.dpss(*k, return_ratios=True)
600
- assert_allclose(win, v[0], atol=1e-7, err_msg=k)
601
- assert_allclose(ratios, v[1], rtol=1e-5, atol=1e-7, err_msg=k)
675
+ win, ratios = windows.dpss(*k, return_ratios=True, xp=xp)
676
+ xp_assert_close(win, v[0], atol=1e-7, err_msg=k)
677
+ xp_assert_close(ratios, v[1], rtol=1e-5, atol=1e-7, err_msg=k)
602
678
 
603
- def test_unity(self):
679
+ def test_unity(self, xp):
604
680
  # Test unity value handling (gh-2221)
605
681
  for M in range(1, 21):
606
682
  # corrected w/approximation (default)
607
- win = windows.dpss(M, M / 2.1)
683
+ win = windows.dpss(M, M / 2.1, xp=xp)
608
684
  expected = M % 2 # one for odd, none for even
609
- assert_equal(np.isclose(win, 1.).sum(), expected,
685
+ xp_assert_equal(np.isclose(win, 1.).sum(), expected,
610
686
  err_msg=f'{win}')
611
687
  # corrected w/subsample delay (slower)
612
- win_sub = windows.dpss(M, M / 2.1, norm='subsample')
688
+ win_sub = windows.dpss(M, M / 2.1, norm='subsample', xp=xp)
613
689
  if M > 2:
614
690
  # @M=2 the subsample doesn't do anything
615
- assert_equal(np.isclose(win_sub, 1.).sum(), expected,
691
+ xp_assert_equal(np.isclose(win_sub, 1.).sum(), expected,
616
692
  err_msg=f'{win_sub}')
617
- assert_allclose(win, win_sub, rtol=0.03) # within 3%
693
+ xp_assert_close(win, win_sub, rtol=0.03) # within 3%
618
694
  # not the same, l2-norm
619
- win_2 = windows.dpss(M, M / 2.1, norm=2)
695
+ win_2 = windows.dpss(M, M / 2.1, norm=2, xp=xp)
620
696
  expected = 1 if M == 1 else 0
621
- assert_equal(np.isclose(win_2, 1.).sum(), expected,
697
+ xp_assert_equal(np.isclose(win_2, 1.).sum(), expected,
622
698
  err_msg=f'{win_2}')
623
699
 
624
- def test_extremes(self):
700
+ def test_extremes(self, xp):
625
701
  # Test extremes of alpha
626
- lam = windows.dpss(31, 6, 4, return_ratios=True)[1]
627
- assert_array_almost_equal(lam, 1.)
628
- lam = windows.dpss(31, 7, 4, return_ratios=True)[1]
629
- assert_array_almost_equal(lam, 1.)
630
- lam = windows.dpss(31, 8, 4, return_ratios=True)[1]
631
- assert_array_almost_equal(lam, 1.)
632
-
633
- def test_degenerate(self):
702
+ lam = windows.dpss(31, 6, 4, return_ratios=True, xp=xp)[1]
703
+ xp_assert_close(lam, xp.ones_like(lam))
704
+ lam = windows.dpss(31, 7, 4, return_ratios=True, xp=xp)[1]
705
+ xp_assert_close(lam, xp.ones_like(lam))
706
+ lam = windows.dpss(31, 8, 4, return_ratios=True, xp=xp)[1]
707
+ xp_assert_close(lam, xp.ones_like(lam))
708
+
709
+ def test_degenerate(self, xp):
634
710
  # Test failures
635
711
  assert_raises(ValueError, windows.dpss, 4, 1.5, -1) # Bad Kmax
636
712
  assert_raises(ValueError, windows.dpss, 4, 1.5, -5)
@@ -640,10 +716,31 @@ class TestDPSS:
640
716
  assert_raises(ValueError, windows.dpss, 3, 0, 3)
641
717
  assert_raises(ValueError, windows.dpss, -1, 1, 3) # negative M
642
718
 
719
+ @skip_xp_backends(np_only=True)
720
+ def test_degenerate_signle_samples(self, xp):
721
+ # Single samples
722
+ w = windows.dpss(1, 1.)
723
+ xp_assert_equal(w, [1.])
724
+ w, ratio = windows.dpss(1, 1., return_ratios=True)
725
+ xp_assert_equal(w, [1.])
726
+ assert ratio == 1.
727
+ w, ratio = windows.dpss(1, 1., Kmax=4, return_ratios=True)
728
+ xp_assert_equal(w, [1.])
729
+ assert isinstance(ratio, np.ndarray)
730
+ xp_assert_equal(ratio, [1.])
731
+
732
+ assert_raises(ValueError, windows.dpss, 4, 1.5, -1, xp=xp) # Bad Kmax
733
+ assert_raises(ValueError, windows.dpss, 4, 1.5, -5, xp=xp)
734
+ assert_raises(TypeError, windows.dpss, 4, 1.5, 1.1, xp=xp)
735
+ assert_raises(ValueError, windows.dpss, 3, 1.5, 3, xp=xp) # NW must be < N/2.
736
+ assert_raises(ValueError, windows.dpss, 3, -1, 3, xp=xp) # NW must be pos
737
+ assert_raises(ValueError, windows.dpss, 3, 0, 3, xp=xp)
738
+ assert_raises(ValueError, windows.dpss, -1, 1, 3, xp=xp) # negative M
739
+
643
740
 
644
741
  class TestLanczos:
645
742
 
646
- def test_basic(self):
743
+ def test_basic(self, xp):
647
744
  # Analytical results:
648
745
  # sinc(x) = sinc(-x)
649
746
  # sinc(pi) = 0, sinc(0) = 1
@@ -652,151 +749,189 @@ class TestLanczos:
652
749
  # sinc(pi / 3) = 0.826993343
653
750
  # sinc(3 pi / 5) = 0.504551152
654
751
  # sinc(pi / 5) = 0.935489284
655
- assert_allclose(windows.lanczos(6, sym=False),
656
- [0., 0.413496672,
657
- 0.826993343, 1., 0.826993343,
658
- 0.413496672],
752
+ xp_assert_close(windows.lanczos(6, sym=False, xp=xp),
753
+ xp.asarray([0., 0.413496672,
754
+ 0.826993343, 1., 0.826993343,
755
+ 0.413496672], dtype=xp.float64),
659
756
  atol=1e-9)
660
- assert_allclose(windows.lanczos(6),
661
- [0., 0.504551152,
662
- 0.935489284, 0.935489284,
663
- 0.504551152, 0.],
757
+ xp_assert_close(windows.lanczos(6, xp=xp),
758
+ xp.asarray([0., 0.504551152,
759
+ 0.935489284, 0.935489284,
760
+ 0.504551152, 0.], dtype=xp.float64),
664
761
  atol=1e-9)
665
- assert_allclose(windows.lanczos(7, sym=True),
666
- [0., 0.413496672,
667
- 0.826993343, 1., 0.826993343,
668
- 0.413496672, 0.],
762
+ xp_assert_close(windows.lanczos(7, sym=True, xp=xp),
763
+ xp.asarray([0., 0.413496672,
764
+ 0.826993343, 1., 0.826993343,
765
+ 0.413496672, 0.], dtype=xp.float64),
669
766
  atol=1e-9)
670
767
 
671
- def test_array_size(self):
768
+ def test_array_size(self, xp):
672
769
  for n in [0, 10, 11]:
673
- assert_equal(len(windows.lanczos(n, sym=False)), n)
674
- assert_equal(len(windows.lanczos(n, sym=True)), n)
770
+ assert windows.lanczos(n, sym=False, xp=xp).shape[0] == n
771
+ assert windows.lanczos(n, sym=True, xp=xp).shape[0] == n
675
772
 
676
773
 
677
774
  class TestGetWindow:
678
775
 
679
- def test_boxcar(self):
680
- w = windows.get_window('boxcar', 12)
681
- assert_array_equal(w, np.ones_like(w))
776
+ def test_boxcar(self, xp):
777
+ w = windows.get_window('boxcar', 12, xp=xp)
778
+ xp_assert_equal(w, xp.ones_like(w))
682
779
 
683
780
  # window is a tuple of len 1
684
- w = windows.get_window(('boxcar',), 16)
685
- assert_array_equal(w, np.ones_like(w))
781
+ w = windows.get_window(('boxcar',), 16, xp=xp)
782
+ xp_assert_equal(w, xp.ones_like(w))
686
783
 
687
- def test_cheb_odd(self):
784
+ @skip_xp_backends('jax.numpy', reason='item assignment')
785
+ @skip_xp_backends('dask.array', reason='data-dependent output shapes')
786
+ def test_cheb_odd(self, xp):
688
787
  with suppress_warnings() as sup:
689
788
  sup.filter(UserWarning, "This window is not suitable")
690
- w = windows.get_window(('chebwin', -40), 53, fftbins=False)
691
- assert_array_almost_equal(w, cheb_odd_true, decimal=4)
789
+ w = windows.get_window(('chebwin', -40), 53, fftbins=False, xp=xp)
790
+ assert_array_almost_equal(
791
+ w, xp.asarray(cheb_odd_true, dtype=xp.float64), decimal=4
792
+ )
692
793
 
693
- def test_cheb_even(self):
794
+ @skip_xp_backends('jax.numpy', reason='item assignment')
795
+ @skip_xp_backends('dask.array', reason='data-dependent output shapes')
796
+ def test_cheb_even(self, xp):
694
797
  with suppress_warnings() as sup:
695
798
  sup.filter(UserWarning, "This window is not suitable")
696
- w = windows.get_window(('chebwin', 40), 54, fftbins=False)
697
- assert_array_almost_equal(w, cheb_even_true, decimal=4)
799
+ w = windows.get_window(('chebwin', 40), 54, fftbins=False, xp=xp)
800
+ assert_array_almost_equal(w, xp.asarray(cheb_even_true), decimal=4)
698
801
 
699
- def test_dpss(self):
700
- win1 = windows.get_window(('dpss', 3), 64, fftbins=False)
701
- win2 = windows.dpss(64, 3)
802
+ @skip_xp_backends(cpu_only=True, reason='eigh_tridiagonal is CPU-only')
803
+ def test_dpss(self, xp):
804
+ win1 = windows.get_window(('dpss', 3), 64, fftbins=False, xp=xp)
805
+ win2 = windows.dpss(64, 3, xp=xp)
702
806
  assert_array_almost_equal(win1, win2, decimal=4)
703
807
 
704
- def test_kaiser_float(self):
705
- win1 = windows.get_window(7.2, 64)
706
- win2 = windows.kaiser(64, 7.2, False)
707
- assert_allclose(win1, win2)
808
+ def test_kaiser_float(self, xp):
809
+ win1 = windows.get_window(7.2, 64, xp=xp)
810
+ win2 = windows.kaiser(64, 7.2, False, xp=xp)
811
+ xp_assert_close(win1, win2)
708
812
 
709
- def test_invalid_inputs(self):
813
+ def test_invalid_inputs(self, xp):
710
814
  # Window is not a float, tuple, or string
711
- assert_raises(ValueError, windows.get_window, set('hann'), 8)
815
+ assert_raises(ValueError, windows.get_window, set('hann'), 8, xp=xp)
712
816
 
713
817
  # Unknown window type error
714
- assert_raises(ValueError, windows.get_window, 'broken', 4)
818
+ assert_raises(ValueError, windows.get_window, 'broken', 4, xp=xp)
715
819
 
716
- def test_array_as_window(self):
717
- # GitHub issue 3603
820
+ @xfail_xp_backends(np_only=True, reason='TODO: make resample array API ready')
821
+ def test_array_as_window(self, xp):
822
+ # github issue 3603
718
823
  osfactor = 128
719
- sig = np.arange(128)
824
+ sig = xp.arange(128)
720
825
 
721
- win = windows.get_window(('kaiser', 8.0), osfactor // 2)
722
- with assert_raises(ValueError, match='must have the same length'):
826
+ win = windows.get_window(('kaiser', 8.0), osfactor // 2, xp=xp)
827
+ with assert_raises(ValueError, match='^window.shape='):
723
828
  resample(sig, len(sig) * osfactor, window=win)
724
829
 
725
- def test_general_cosine(self):
726
- assert_allclose(get_window(('general_cosine', [0.5, 0.3, 0.2]), 4),
727
- [0.4, 0.3, 1, 0.3])
728
- assert_allclose(get_window(('general_cosine', [0.5, 0.3, 0.2]), 4,
830
+ def test_general_cosine(self, xp):
831
+ xp_assert_close(get_window(('general_cosine', xp.asarray([0.5, 0.3, 0.2])), 4),
832
+ xp.asarray([0.4, 0.3, 1, 0.3], dtype=xp.float64))
833
+ xp_assert_close(get_window(('general_cosine', xp.asarray([0.5, 0.3, 0.2])), 4,
729
834
  fftbins=False),
730
- [0.4, 0.55, 0.55, 0.4])
731
-
732
- def test_general_hamming(self):
733
- assert_allclose(get_window(('general_hamming', 0.7), 5),
734
- [0.4, 0.6072949, 0.9427051, 0.9427051, 0.6072949])
735
- assert_allclose(get_window(('general_hamming', 0.7), 5, fftbins=False),
736
- [0.4, 0.7, 1.0, 0.7, 0.4])
737
-
738
- def test_lanczos(self):
739
- assert_allclose(get_window('lanczos', 6),
740
- [0., 0.413496672, 0.826993343, 1., 0.826993343,
741
- 0.413496672], atol=1e-9)
742
- assert_allclose(get_window('lanczos', 6, fftbins=False),
743
- [0., 0.504551152, 0.935489284, 0.935489284,
744
- 0.504551152, 0.], atol=1e-9)
745
- assert_allclose(get_window('lanczos', 6), get_window('sinc', 6))
746
-
747
-
748
- def test_windowfunc_basics():
835
+ xp.asarray([0.4, 0.55, 0.55, 0.4], dtype=xp.float64))
836
+
837
+ with pytest.raises(ValueError):
838
+ get_window(('general_cosine', [0.5, 0.3, 0.2]), 4, xp=xp)
839
+
840
+ def test_general_hamming(self, xp):
841
+ xp_assert_close(get_window(('general_hamming', 0.7), 5, xp=xp),
842
+ xp.asarray([0.4, 0.6072949, 0.9427051, 0.9427051, 0.6072949],
843
+ dtype=xp.float64))
844
+ xp_assert_close(get_window(('general_hamming', 0.7), 5, fftbins=False, xp=xp),
845
+ xp.asarray([0.4, 0.7, 1.0, 0.7, 0.4], dtype=xp.float64))
846
+
847
+ def test_lanczos(self, xp):
848
+ xp_assert_close(get_window('lanczos', 6, xp=xp),
849
+ xp.asarray([0., 0.413496672, 0.826993343, 1., 0.826993343,
850
+ 0.413496672], dtype=xp.float64), atol=1e-9)
851
+ xp_assert_close(get_window('lanczos', 6, fftbins=False, xp=xp),
852
+ xp.asarray([0., 0.504551152, 0.935489284, 0.935489284,
853
+ 0.504551152, 0.], dtype=xp.float64), atol=1e-9)
854
+ xp_assert_close(get_window('lanczos', 6, xp=xp),
855
+ get_window('sinc', 6, xp=xp))
856
+
857
+ def test_xp_default(self, xp):
858
+ # no explicit xp= argument, default to numpy
859
+ win = get_window('lanczos', 6)
860
+ assert isinstance(win, np.ndarray)
861
+
862
+ win = get_window('lanczos', 6, xp=xp)
863
+ if not is_numpy(xp):
864
+ assert not isinstance(win, np.ndarray)
865
+
866
+
867
+ @skip_xp_backends("dask.array", reason="https://github.com/dask/dask/issues/2620")
868
+ def test_windowfunc_basics(xp):
749
869
  for window_name, params in window_funcs:
750
870
  window = getattr(windows, window_name)
871
+ if is_jax(xp) and window_name in ['taylor', 'chebwin']:
872
+ pytest.skip(reason=f'{window_name = }: item assignment')
873
+ if window_name in ['dpss']:
874
+ if is_cupy(xp):
875
+ pytest.skip(reason='dpss window is not implemented for cupy')
876
+ if is_torch(xp) and SCIPY_DEVICE != 'cpu':
877
+ pytest.skip(reason='needs eight_tridiagonal which is CPU only')
878
+
751
879
  with suppress_warnings() as sup:
752
880
  sup.filter(UserWarning, "This window is not suitable")
753
881
  # Check symmetry for odd and even lengths
754
- w1 = window(8, *params, sym=True)
755
- w2 = window(7, *params, sym=False)
756
- assert_array_almost_equal(w1[:-1], w2)
882
+ w1 = window(8, *params, sym=True, xp=xp)
883
+ w2 = window(7, *params, sym=False, xp=xp)
884
+ xp_assert_close(w1[:-1], w2)
757
885
 
758
- w1 = window(9, *params, sym=True)
759
- w2 = window(8, *params, sym=False)
760
- assert_array_almost_equal(w1[:-1], w2)
886
+ w1 = window(9, *params, sym=True, xp=xp)
887
+ w2 = window(8, *params, sym=False, xp=xp)
888
+ xp_assert_close(w1[:-1], w2)
761
889
 
762
890
  # Check that functions run and output lengths are correct
763
- assert_equal(len(window(6, *params, sym=True)), 6)
764
- assert_equal(len(window(6, *params, sym=False)), 6)
765
- assert_equal(len(window(7, *params, sym=True)), 7)
766
- assert_equal(len(window(7, *params, sym=False)), 7)
891
+ assert window(6, *params, sym=True, xp=xp).shape[0] == 6
892
+ assert window(6, *params, sym=False, xp=xp).shape[0] == 6
893
+ assert window(7, *params, sym=True, xp=xp).shape[0] == 7
894
+ assert window(7, *params, sym=False, xp=xp).shape[0] == 7
767
895
 
768
896
  # Check invalid lengths
769
- assert_raises(ValueError, window, 5.5, *params)
770
- assert_raises(ValueError, window, -7, *params)
897
+ assert_raises(ValueError, window, 5.5, *params, xp=xp)
898
+ assert_raises(ValueError, window, -7, *params, xp=xp)
771
899
 
772
900
  # Check degenerate cases
773
- assert_array_equal(window(0, *params, sym=True), [])
774
- assert_array_equal(window(0, *params, sym=False), [])
775
- assert_array_equal(window(1, *params, sym=True), [1])
776
- assert_array_equal(window(1, *params, sym=False), [1])
901
+ xp_assert_equal(window(0, *params, sym=True, xp=xp),
902
+ xp.asarray([], dtype=xp.float64))
903
+ xp_assert_equal(window(0, *params, sym=False, xp=xp),
904
+ xp.asarray([], dtype=xp.float64))
905
+ xp_assert_equal(window(1, *params, sym=True, xp=xp),
906
+ xp.asarray([1.], dtype=xp.float64))
907
+ xp_assert_equal(window(1, *params, sym=False, xp=xp),
908
+ xp.asarray([1.], dtype=xp.float64))
777
909
 
778
910
  # Check dtype
779
- assert_(window(0, *params, sym=True).dtype == 'float')
780
- assert_(window(0, *params, sym=False).dtype == 'float')
781
- assert_(window(1, *params, sym=True).dtype == 'float')
782
- assert_(window(1, *params, sym=False).dtype == 'float')
783
- assert_(window(6, *params, sym=True).dtype == 'float')
784
- assert_(window(6, *params, sym=False).dtype == 'float')
911
+ assert window(0, *params, sym=True, xp=xp).dtype == xp.float64
912
+ assert window(0, *params, sym=False, xp=xp).dtype == xp.float64
913
+ assert window(1, *params, sym=True, xp=xp).dtype == xp.float64
914
+ assert window(1, *params, sym=False, xp=xp).dtype == xp.float64
915
+ assert window(6, *params, sym=True, xp=xp).dtype == xp.float64
916
+ assert window(6, *params, sym=False, xp=xp).dtype == xp.float64
785
917
 
786
918
  # Check normalization
787
- assert_array_less(window(10, *params, sym=True), 1.01)
788
- assert_array_less(window(10, *params, sym=False), 1.01)
789
- assert_array_less(window(9, *params, sym=True), 1.01)
790
- assert_array_less(window(9, *params, sym=False), 1.01)
919
+ assert xp.all(window(10, *params, sym=True, xp=xp) < 1.01)
920
+ assert xp.all(window(10, *params, sym=False, xp=xp) < 1.01)
921
+ assert xp.all(window(9, *params, sym=True, xp=xp) < 1.01)
922
+ assert xp.all(window(9, *params, sym=False, xp=xp) < 1.01)
791
923
 
792
924
  # Check that DFT-even spectrum is purely real for odd and even
793
- assert_allclose(fft(window(10, *params, sym=False)).imag,
794
- 0, atol=1e-14)
795
- assert_allclose(fft(window(11, *params, sym=False)).imag,
796
- 0, atol=1e-14)
925
+ res = fft(window(10, *params, sym=False, xp=xp))
926
+ res = xp.imag(res)
927
+ xp_assert_close(res, xp.zeros_like(res), atol=1e-14)
928
+
929
+ res = fft(window(11, *params, sym=False, xp=xp))
930
+ res = xp.imag(res)
931
+ xp_assert_close(res, xp.zeros_like(res), atol=1e-14)
797
932
 
798
933
 
799
- def test_needs_params():
934
+ def test_needs_params(xp):
800
935
  for winstr in ['kaiser', 'ksr', 'kaiser_bessel_derived', 'kbd',
801
936
  'gaussian', 'gauss', 'gss',
802
937
  'general gaussian', 'general_gaussian',
@@ -804,43 +939,49 @@ def test_needs_params():
804
939
  'dss', 'dpss', 'general cosine', 'general_cosine',
805
940
  'chebwin', 'cheb', 'general hamming', 'general_hamming',
806
941
  ]:
807
- assert_raises(ValueError, get_window, winstr, 7)
808
-
809
-
810
- def test_not_needs_params():
811
- for winstr in ['barthann',
812
- 'bartlett',
813
- 'blackman',
814
- 'blackmanharris',
815
- 'bohman',
816
- 'boxcar',
817
- 'cosine',
818
- 'flattop',
819
- 'hamming',
820
- 'nuttall',
821
- 'parzen',
822
- 'taylor',
823
- 'exponential',
824
- 'poisson',
825
- 'tukey',
826
- 'tuk',
827
- 'triangle',
828
- 'lanczos',
829
- 'sinc',
830
- ]:
831
- win = get_window(winstr, 7)
832
- assert_equal(len(win), 7)
833
-
834
-
835
- def test_symmetric():
942
+ assert_raises(ValueError, get_window, winstr, 7, xp=xp)
943
+
944
+
945
+ _winstr = ['barthann',
946
+ 'bartlett',
947
+ 'blackman',
948
+ 'blackmanharris',
949
+ 'bohman',
950
+ 'boxcar',
951
+ 'cosine',
952
+ 'flattop',
953
+ 'hamming',
954
+ 'nuttall',
955
+ 'parzen',
956
+ 'taylor',
957
+ 'exponential',
958
+ 'poisson',
959
+ 'tukey',
960
+ 'tuk',
961
+ 'triangle',
962
+ 'lanczos',
963
+ 'sinc',
964
+ ]
965
+
966
+
967
+ @pytest.mark.parametrize('winstr', _winstr)
968
+ def test_not_needs_params(xp, winstr):
969
+ if is_jax(xp) and winstr in ['taylor']:
970
+ pytest.skip(reason=f'{winstr}: item assignment')
971
+ win = get_window(winstr, 7, xp=xp)
972
+ assert win.shape[0] == 7
973
+
974
+
975
+ def test_symmetric(xp):
836
976
 
837
977
  for win in [windows.lanczos]:
838
978
  # Even sampling points
839
- w = win(4096)
840
- error = np.max(np.abs(w-np.flip(w)))
841
- assert_equal(error, 0.0)
979
+ w = win(4096, xp=xp)
980
+ flip = array_namespace(w).flip
981
+ error = xp.max(xp.abs(w - flip(w)))
982
+ xp_assert_equal(error, xp.asarray(0.0), check_dtype=False, check_0d=False)
842
983
 
843
984
  # Odd sampling points
844
- w = win(4097)
845
- error = np.max(np.abs(w-np.flip(w)))
846
- assert_equal(error, 0.0)
985
+ w = win(4097, xp=xp)
986
+ error = xp.max(xp.abs(w - flip(w)))
987
+ xp_assert_equal(error, xp.asarray(0.0), check_dtype=False, check_0d=False)