scipy 1.15.3__cp312-cp312-macosx_12_0_arm64.whl → 1.16.0rc2__cp312-cp312-macosx_12_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  2. scipy/__config__.py +8 -8
  3. scipy/__init__.py +3 -6
  4. scipy/_cyutility.cpython-312-darwin.so +0 -0
  5. scipy/_lib/_array_api.py +486 -161
  6. scipy/_lib/_array_api_compat_vendor.py +9 -0
  7. scipy/_lib/_bunch.py +4 -0
  8. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  9. scipy/_lib/_docscrape.py +1 -1
  10. scipy/_lib/_elementwise_iterative_method.py +15 -26
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +166 -35
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +263 -157
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  127. scipy/integrate/_ode.py +9 -2
  128. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_quad_vec.py +21 -29
  130. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  131. scipy/integrate/_quadpack_py.py +11 -7
  132. scipy/integrate/_quadrature.py +3 -3
  133. scipy/integrate/_rules/_base.py +2 -2
  134. scipy/integrate/_tanhsinh.py +48 -47
  135. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  136. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  137. scipy/integrate/tests/test__quad_vec.py +0 -6
  138. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  139. scipy/integrate/tests/test_cubature.py +21 -35
  140. scipy/integrate/tests/test_quadrature.py +6 -8
  141. scipy/integrate/tests/test_tanhsinh.py +56 -48
  142. scipy/interpolate/__init__.py +70 -58
  143. scipy/interpolate/_bary_rational.py +22 -22
  144. scipy/interpolate/_bsplines.py +119 -66
  145. scipy/interpolate/_cubic.py +65 -50
  146. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  148. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  149. scipy/interpolate/_fitpack2.py +9 -6
  150. scipy/interpolate/_fitpack_impl.py +32 -26
  151. scipy/interpolate/_fitpack_repro.py +23 -19
  152. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  153. scipy/interpolate/_interpolate.py +30 -12
  154. scipy/interpolate/_ndbspline.py +13 -18
  155. scipy/interpolate/_ndgriddata.py +5 -8
  156. scipy/interpolate/_polyint.py +95 -31
  157. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  158. scipy/interpolate/_rbf.py +2 -2
  159. scipy/interpolate/_rbfinterp.py +1 -1
  160. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  161. scipy/interpolate/_rgi.py +31 -26
  162. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  163. scipy/interpolate/dfitpack.py +0 -20
  164. scipy/interpolate/interpnd.py +1 -2
  165. scipy/interpolate/tests/test_bary_rational.py +2 -2
  166. scipy/interpolate/tests/test_bsplines.py +97 -1
  167. scipy/interpolate/tests/test_fitpack2.py +39 -1
  168. scipy/interpolate/tests/test_interpnd.py +32 -20
  169. scipy/interpolate/tests/test_interpolate.py +48 -4
  170. scipy/interpolate/tests/test_rgi.py +2 -1
  171. scipy/io/_fast_matrix_market/__init__.py +2 -0
  172. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  173. scipy/io/_harwell_boeing/hb.py +7 -11
  174. scipy/io/_idl.py +5 -7
  175. scipy/io/_netcdf.py +15 -5
  176. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  177. scipy/io/arff/tests/test_arffread.py +3 -3
  178. scipy/io/matlab/__init__.py +5 -3
  179. scipy/io/matlab/_mio.py +4 -1
  180. scipy/io/matlab/_mio5.py +19 -13
  181. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  183. scipy/io/matlab/_miobase.py +4 -1
  184. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  185. scipy/io/matlab/tests/test_mio.py +46 -18
  186. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  187. scipy/io/tests/test_mmio.py +7 -1
  188. scipy/io/tests/test_wavfile.py +41 -0
  189. scipy/io/wavfile.py +57 -10
  190. scipy/linalg/_basic.py +113 -86
  191. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  192. scipy/linalg/_decomp.py +22 -9
  193. scipy/linalg/_decomp_cholesky.py +28 -13
  194. scipy/linalg/_decomp_cossin.py +45 -30
  195. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  196. scipy/linalg/_decomp_ldl.py +4 -1
  197. scipy/linalg/_decomp_lu.py +18 -6
  198. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  199. scipy/linalg/_decomp_polar.py +2 -0
  200. scipy/linalg/_decomp_qr.py +6 -2
  201. scipy/linalg/_decomp_qz.py +3 -0
  202. scipy/linalg/_decomp_schur.py +3 -1
  203. scipy/linalg/_decomp_svd.py +13 -2
  204. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_expm_frechet.py +4 -0
  206. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  209. scipy/linalg/_matfuncs.py +187 -4
  210. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  212. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  213. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  214. scipy/linalg/_procrustes.py +2 -0
  215. scipy/linalg/_sketches.py +17 -6
  216. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  217. scipy/linalg/_solvers.py +7 -2
  218. scipy/linalg/_special_matrices.py +26 -36
  219. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  220. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  221. scipy/linalg/lapack.py +22 -2
  222. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  223. scipy/linalg/tests/test_basic.py +31 -16
  224. scipy/linalg/tests/test_batch.py +588 -0
  225. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  226. scipy/linalg/tests/test_decomp.py +40 -3
  227. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  228. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  229. scipy/linalg/tests/test_lapack.py +115 -7
  230. scipy/linalg/tests/test_matfuncs.py +157 -102
  231. scipy/linalg/tests/test_procrustes.py +0 -7
  232. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  233. scipy/linalg/tests/test_special_matrices.py +1 -5
  234. scipy/ndimage/__init__.py +1 -0
  235. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  236. scipy/ndimage/_delegators.py +8 -2
  237. scipy/ndimage/_filters.py +453 -5
  238. scipy/ndimage/_interpolation.py +36 -6
  239. scipy/ndimage/_measurements.py +4 -2
  240. scipy/ndimage/_morphology.py +5 -0
  241. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  242. scipy/ndimage/_ni_docstrings.py +5 -1
  243. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  244. scipy/ndimage/_ni_support.py +1 -5
  245. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  246. scipy/ndimage/_support_alternative_backends.py +18 -6
  247. scipy/ndimage/tests/test_filters.py +370 -259
  248. scipy/ndimage/tests/test_fourier.py +7 -9
  249. scipy/ndimage/tests/test_interpolation.py +68 -61
  250. scipy/ndimage/tests/test_measurements.py +18 -35
  251. scipy/ndimage/tests/test_morphology.py +143 -131
  252. scipy/ndimage/tests/test_splines.py +1 -3
  253. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  254. scipy/optimize/_basinhopping.py +13 -7
  255. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  256. scipy/optimize/_bracket.py +17 -24
  257. scipy/optimize/_chandrupatla.py +9 -10
  258. scipy/optimize/_cobyla_py.py +104 -123
  259. scipy/optimize/_constraints.py +14 -10
  260. scipy/optimize/_differentiable_functions.py +371 -230
  261. scipy/optimize/_differentialevolution.py +4 -3
  262. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_dual_annealing.py +1 -1
  264. scipy/optimize/_elementwise.py +1 -4
  265. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  267. scipy/optimize/_lbfgsb_py.py +57 -16
  268. scipy/optimize/_linprog_doc.py +2 -2
  269. scipy/optimize/_linprog_highs.py +2 -2
  270. scipy/optimize/_linprog_ip.py +25 -10
  271. scipy/optimize/_linprog_util.py +14 -16
  272. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  273. scipy/optimize/_lsq/common.py +3 -3
  274. scipy/optimize/_lsq/dogbox.py +16 -2
  275. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  276. scipy/optimize/_lsq/least_squares.py +198 -126
  277. scipy/optimize/_lsq/lsq_linear.py +6 -6
  278. scipy/optimize/_lsq/trf.py +35 -8
  279. scipy/optimize/_milp.py +3 -1
  280. scipy/optimize/_minimize.py +105 -36
  281. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  282. scipy/optimize/_minpack_py.py +21 -14
  283. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  284. scipy/optimize/_nnls.py +20 -21
  285. scipy/optimize/_nonlin.py +34 -3
  286. scipy/optimize/_numdiff.py +288 -110
  287. scipy/optimize/_optimize.py +86 -48
  288. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  289. scipy/optimize/_remove_redundancy.py +5 -5
  290. scipy/optimize/_root_scalar.py +1 -1
  291. scipy/optimize/_shgo.py +6 -0
  292. scipy/optimize/_shgo_lib/_complex.py +1 -1
  293. scipy/optimize/_slsqp_py.py +216 -124
  294. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  295. scipy/optimize/_spectral.py +1 -1
  296. scipy/optimize/_tnc.py +8 -1
  297. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  298. scipy/optimize/_trustregion.py +20 -6
  299. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  300. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  301. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  302. scipy/optimize/_trustregion_constr/projections.py +12 -8
  303. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  304. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  305. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  306. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  307. scipy/optimize/_trustregion_exact.py +0 -1
  308. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  309. scipy/optimize/_zeros_py.py +97 -17
  310. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  311. scipy/optimize/slsqp.py +0 -1
  312. scipy/optimize/tests/test__basinhopping.py +1 -1
  313. scipy/optimize/tests/test__differential_evolution.py +4 -4
  314. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  315. scipy/optimize/tests/test__numdiff.py +66 -22
  316. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  317. scipy/optimize/tests/test__shgo.py +9 -1
  318. scipy/optimize/tests/test_bracket.py +36 -46
  319. scipy/optimize/tests/test_chandrupatla.py +133 -135
  320. scipy/optimize/tests/test_cobyla.py +74 -45
  321. scipy/optimize/tests/test_constraints.py +1 -1
  322. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  323. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  324. scipy/optimize/tests/test_least_squares.py +125 -13
  325. scipy/optimize/tests/test_linear_assignment.py +3 -3
  326. scipy/optimize/tests/test_linprog.py +3 -3
  327. scipy/optimize/tests/test_lsq_linear.py +6 -6
  328. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  329. scipy/optimize/tests/test_minpack.py +4 -4
  330. scipy/optimize/tests/test_nnls.py +43 -3
  331. scipy/optimize/tests/test_nonlin.py +36 -0
  332. scipy/optimize/tests/test_optimize.py +95 -17
  333. scipy/optimize/tests/test_slsqp.py +36 -4
  334. scipy/optimize/tests/test_zeros.py +34 -1
  335. scipy/signal/__init__.py +12 -23
  336. scipy/signal/_delegators.py +568 -0
  337. scipy/signal/_filter_design.py +459 -241
  338. scipy/signal/_fir_filter_design.py +262 -90
  339. scipy/signal/_lti_conversion.py +3 -2
  340. scipy/signal/_ltisys.py +118 -91
  341. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  342. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  343. scipy/signal/_polyutils.py +172 -0
  344. scipy/signal/_short_time_fft.py +519 -70
  345. scipy/signal/_signal_api.py +30 -0
  346. scipy/signal/_signaltools.py +719 -399
  347. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  348. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  349. scipy/signal/_spectral_py.py +230 -50
  350. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  351. scipy/signal/_spline_filters.py +108 -68
  352. scipy/signal/_support_alternative_backends.py +73 -0
  353. scipy/signal/_upfirdn.py +4 -1
  354. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  355. scipy/signal/_waveforms.py +2 -11
  356. scipy/signal/_wavelets.py +1 -1
  357. scipy/signal/fir_filter_design.py +1 -0
  358. scipy/signal/spline.py +4 -11
  359. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  360. scipy/signal/tests/test_bsplines.py +114 -79
  361. scipy/signal/tests/test_cont2discrete.py +9 -2
  362. scipy/signal/tests/test_filter_design.py +721 -481
  363. scipy/signal/tests/test_fir_filter_design.py +332 -140
  364. scipy/signal/tests/test_savitzky_golay.py +4 -3
  365. scipy/signal/tests/test_short_time_fft.py +221 -3
  366. scipy/signal/tests/test_signaltools.py +2144 -1348
  367. scipy/signal/tests/test_spectral.py +50 -6
  368. scipy/signal/tests/test_splines.py +161 -96
  369. scipy/signal/tests/test_upfirdn.py +84 -50
  370. scipy/signal/tests/test_waveforms.py +20 -0
  371. scipy/signal/tests/test_windows.py +607 -466
  372. scipy/signal/windows/_windows.py +287 -148
  373. scipy/sparse/__init__.py +23 -4
  374. scipy/sparse/_base.py +270 -108
  375. scipy/sparse/_bsr.py +7 -4
  376. scipy/sparse/_compressed.py +59 -231
  377. scipy/sparse/_construct.py +90 -38
  378. scipy/sparse/_coo.py +115 -181
  379. scipy/sparse/_csc.py +4 -4
  380. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  381. scipy/sparse/_csr.py +2 -2
  382. scipy/sparse/_data.py +48 -48
  383. scipy/sparse/_dia.py +105 -18
  384. scipy/sparse/_dok.py +0 -23
  385. scipy/sparse/_index.py +4 -4
  386. scipy/sparse/_matrix.py +23 -0
  387. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  388. scipy/sparse/_sputils.py +37 -22
  389. scipy/sparse/base.py +0 -9
  390. scipy/sparse/bsr.py +0 -14
  391. scipy/sparse/compressed.py +0 -23
  392. scipy/sparse/construct.py +0 -6
  393. scipy/sparse/coo.py +0 -14
  394. scipy/sparse/csc.py +0 -3
  395. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  396. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  397. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  398. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  399. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  400. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  401. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  402. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  403. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  404. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  405. scipy/sparse/csr.py +0 -5
  406. scipy/sparse/data.py +1 -6
  407. scipy/sparse/dia.py +0 -7
  408. scipy/sparse/dok.py +0 -10
  409. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  410. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  411. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  412. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  413. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  414. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  415. scipy/sparse/linalg/_interface.py +17 -18
  416. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  417. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  418. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  419. scipy/sparse/linalg/_isolve/minres.py +5 -5
  420. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  421. scipy/sparse/linalg/_isolve/utils.py +2 -8
  422. scipy/sparse/linalg/_matfuncs.py +1 -1
  423. scipy/sparse/linalg/_norm.py +1 -1
  424. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  427. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  428. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  429. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  430. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  431. scipy/sparse/tests/test_base.py +214 -42
  432. scipy/sparse/tests/test_common1d.py +7 -7
  433. scipy/sparse/tests/test_construct.py +1 -1
  434. scipy/sparse/tests/test_coo.py +272 -4
  435. scipy/sparse/tests/test_sparsetools.py +5 -0
  436. scipy/sparse/tests/test_sputils.py +36 -7
  437. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  438. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  439. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  440. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  441. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  442. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  443. scipy/spatial/distance.py +49 -42
  444. scipy/spatial/tests/test_distance.py +15 -1
  445. scipy/spatial/tests/test_kdtree.py +1 -0
  446. scipy/spatial/tests/test_qhull.py +7 -2
  447. scipy/spatial/transform/__init__.py +5 -3
  448. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  449. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  450. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  451. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  452. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  453. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  454. scipy/special/__init__.py +1 -47
  455. scipy/special/_add_newdocs.py +34 -772
  456. scipy/special/_basic.py +22 -25
  457. scipy/special/_comb.cpython-312-darwin.so +0 -0
  458. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  459. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  460. scipy/special/_logsumexp.py +67 -58
  461. scipy/special/_orthogonal.pyi +1 -1
  462. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  463. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  464. scipy/special/_spherical_bessel.py +4 -4
  465. scipy/special/_support_alternative_backends.py +212 -119
  466. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  467. scipy/special/_testutils.py +4 -4
  468. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  469. scipy/special/_ufuncs.pyi +1 -0
  470. scipy/special/_ufuncs.pyx +215 -1400
  471. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  472. scipy/special/_ufuncs_cxx.pxd +2 -15
  473. scipy/special/_ufuncs_cxx.pyx +5 -44
  474. scipy/special/_ufuncs_cxx_defs.h +2 -16
  475. scipy/special/_ufuncs_defs.h +0 -8
  476. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  477. scipy/special/cython_special.pxd +1 -1
  478. scipy/special/tests/_cython_examples/meson.build +10 -1
  479. scipy/special/tests/test_basic.py +153 -20
  480. scipy/special/tests/test_boost_ufuncs.py +3 -0
  481. scipy/special/tests/test_cdflib.py +35 -11
  482. scipy/special/tests/test_gammainc.py +16 -0
  483. scipy/special/tests/test_hyp2f1.py +2 -2
  484. scipy/special/tests/test_log1mexp.py +85 -0
  485. scipy/special/tests/test_logsumexp.py +206 -64
  486. scipy/special/tests/test_mpmath.py +1 -0
  487. scipy/special/tests/test_nan_inputs.py +1 -1
  488. scipy/special/tests/test_orthogonal.py +17 -18
  489. scipy/special/tests/test_sf_error.py +3 -2
  490. scipy/special/tests/test_sph_harm.py +6 -7
  491. scipy/special/tests/test_support_alternative_backends.py +211 -76
  492. scipy/stats/__init__.py +4 -1
  493. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  494. scipy/stats/_axis_nan_policy.py +5 -12
  495. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  496. scipy/stats/_continued_fraction.py +387 -0
  497. scipy/stats/_continuous_distns.py +277 -310
  498. scipy/stats/_correlation.py +1 -1
  499. scipy/stats/_covariance.py +6 -3
  500. scipy/stats/_discrete_distns.py +39 -32
  501. scipy/stats/_distn_infrastructure.py +39 -12
  502. scipy/stats/_distribution_infrastructure.py +900 -238
  503. scipy/stats/_entropy.py +9 -10
  504. scipy/{_lib → stats}/_finite_differences.py +1 -1
  505. scipy/stats/_hypotests.py +83 -50
  506. scipy/stats/_kde.py +53 -49
  507. scipy/stats/_ksstats.py +1 -1
  508. scipy/stats/_levy_stable/__init__.py +7 -15
  509. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  510. scipy/stats/_morestats.py +118 -73
  511. scipy/stats/_mstats_basic.py +13 -17
  512. scipy/stats/_mstats_extras.py +8 -8
  513. scipy/stats/_multivariate.py +89 -113
  514. scipy/stats/_new_distributions.py +97 -20
  515. scipy/stats/_page_trend_test.py +12 -5
  516. scipy/stats/_probability_distribution.py +265 -43
  517. scipy/stats/_qmc.py +14 -9
  518. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  519. scipy/stats/_qmvnt.py +16 -95
  520. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  521. scipy/stats/_quantile.py +335 -0
  522. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  523. scipy/stats/_resampling.py +4 -29
  524. scipy/stats/_sampling.py +1 -1
  525. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  526. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  527. scipy/stats/_stats_mstats_common.py +21 -2
  528. scipy/stats/_stats_py.py +550 -476
  529. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  531. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  532. scipy/stats/_variation.py +6 -8
  533. scipy/stats/_wilcoxon.py +13 -7
  534. scipy/stats/tests/common_tests.py +6 -4
  535. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  536. scipy/stats/tests/test_continued_fraction.py +173 -0
  537. scipy/stats/tests/test_continuous.py +379 -60
  538. scipy/stats/tests/test_continuous_basic.py +18 -12
  539. scipy/stats/tests/test_discrete_basic.py +14 -8
  540. scipy/stats/tests/test_discrete_distns.py +16 -16
  541. scipy/stats/tests/test_distributions.py +95 -75
  542. scipy/stats/tests/test_entropy.py +40 -48
  543. scipy/stats/tests/test_fit.py +4 -3
  544. scipy/stats/tests/test_hypotests.py +153 -24
  545. scipy/stats/tests/test_kdeoth.py +109 -41
  546. scipy/stats/tests/test_marray.py +289 -0
  547. scipy/stats/tests/test_morestats.py +79 -47
  548. scipy/stats/tests/test_mstats_basic.py +3 -3
  549. scipy/stats/tests/test_multivariate.py +434 -83
  550. scipy/stats/tests/test_qmc.py +13 -10
  551. scipy/stats/tests/test_quantile.py +199 -0
  552. scipy/stats/tests/test_rank.py +119 -112
  553. scipy/stats/tests/test_resampling.py +47 -56
  554. scipy/stats/tests/test_sampling.py +9 -4
  555. scipy/stats/tests/test_stats.py +799 -939
  556. scipy/stats/tests/test_variation.py +8 -6
  557. scipy/version.py +2 -2
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  560. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +561 -568
  561. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  562. scipy/_lib/array_api_extra/_funcs.py +0 -484
  563. scipy/_lib/array_api_extra/_typing.py +0 -8
  564. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  565. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  566. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  567. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  568. scipy/spatial/qhull_src/COPYING.txt +0 -38
  569. scipy/special/libsf_error_state.dylib +0 -0
  570. scipy/special/tests/test_log_softmax.py +0 -109
  571. scipy/special/tests/test_xsf_cuda.py +0 -114
  572. scipy/special/xsf/binom.h +0 -89
  573. scipy/special/xsf/cdflib.h +0 -100
  574. scipy/special/xsf/cephes/airy.h +0 -307
  575. scipy/special/xsf/cephes/besselpoly.h +0 -51
  576. scipy/special/xsf/cephes/beta.h +0 -257
  577. scipy/special/xsf/cephes/cbrt.h +0 -131
  578. scipy/special/xsf/cephes/chbevl.h +0 -85
  579. scipy/special/xsf/cephes/chdtr.h +0 -193
  580. scipy/special/xsf/cephes/const.h +0 -87
  581. scipy/special/xsf/cephes/ellie.h +0 -293
  582. scipy/special/xsf/cephes/ellik.h +0 -251
  583. scipy/special/xsf/cephes/ellpe.h +0 -107
  584. scipy/special/xsf/cephes/ellpk.h +0 -117
  585. scipy/special/xsf/cephes/expn.h +0 -260
  586. scipy/special/xsf/cephes/gamma.h +0 -398
  587. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  588. scipy/special/xsf/cephes/hyperg.h +0 -361
  589. scipy/special/xsf/cephes/i0.h +0 -149
  590. scipy/special/xsf/cephes/i1.h +0 -158
  591. scipy/special/xsf/cephes/igam.h +0 -421
  592. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  593. scipy/special/xsf/cephes/igami.h +0 -313
  594. scipy/special/xsf/cephes/j0.h +0 -225
  595. scipy/special/xsf/cephes/j1.h +0 -198
  596. scipy/special/xsf/cephes/jv.h +0 -715
  597. scipy/special/xsf/cephes/k0.h +0 -164
  598. scipy/special/xsf/cephes/k1.h +0 -163
  599. scipy/special/xsf/cephes/kn.h +0 -243
  600. scipy/special/xsf/cephes/lanczos.h +0 -112
  601. scipy/special/xsf/cephes/ndtr.h +0 -275
  602. scipy/special/xsf/cephes/poch.h +0 -85
  603. scipy/special/xsf/cephes/polevl.h +0 -167
  604. scipy/special/xsf/cephes/psi.h +0 -194
  605. scipy/special/xsf/cephes/rgamma.h +0 -111
  606. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  607. scipy/special/xsf/cephes/shichi.h +0 -248
  608. scipy/special/xsf/cephes/sici.h +0 -224
  609. scipy/special/xsf/cephes/sindg.h +0 -221
  610. scipy/special/xsf/cephes/tandg.h +0 -139
  611. scipy/special/xsf/cephes/trig.h +0 -58
  612. scipy/special/xsf/cephes/unity.h +0 -186
  613. scipy/special/xsf/cephes/zeta.h +0 -172
  614. scipy/special/xsf/config.h +0 -304
  615. scipy/special/xsf/digamma.h +0 -205
  616. scipy/special/xsf/error.h +0 -57
  617. scipy/special/xsf/evalpoly.h +0 -47
  618. scipy/special/xsf/expint.h +0 -266
  619. scipy/special/xsf/hyp2f1.h +0 -694
  620. scipy/special/xsf/iv_ratio.h +0 -173
  621. scipy/special/xsf/lambertw.h +0 -150
  622. scipy/special/xsf/loggamma.h +0 -163
  623. scipy/special/xsf/sici.h +0 -200
  624. scipy/special/xsf/tools.h +0 -427
  625. scipy/special/xsf/trig.h +0 -164
  626. scipy/special/xsf/wright_bessel.h +0 -843
  627. scipy/special/xsf/zlog1.h +0 -35
  628. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  629. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
2
  from scipy._lib._array_api import (
3
- is_cupy, is_numpy, is_torch, array_namespace,
3
+ is_cupy, is_numpy,
4
4
  xp_assert_close, xp_assert_equal, assert_array_almost_equal
5
5
  )
6
6
  import pytest
@@ -10,12 +10,9 @@ from scipy import ndimage
10
10
 
11
11
  from . import types
12
12
 
13
- from scipy.conftest import array_api_compatible
14
13
  skip_xp_backends = pytest.mark.skip_xp_backends
15
14
  xfail_xp_backends = pytest.mark.xfail_xp_backends
16
- pytestmark = [array_api_compatible, pytest.mark.usefixtures("skip_xp_backends"),
17
- pytest.mark.usefixtures("xfail_xp_backends"),
18
- skip_xp_backends(cpu_only=True, exceptions=['cupy', 'jax.numpy'],)]
15
+ pytestmark = [skip_xp_backends(cpu_only=True, exceptions=['cupy', 'jax.numpy'])]
19
16
 
20
17
 
21
18
  class TestNdimageMorphology:
@@ -118,7 +115,7 @@ class TestNdimageMorphology:
118
115
  [0, 1, 2, 3, 4, 5, 6, 7, 8],
119
116
  [0, 1, 2, 3, 4, 5, 6, 7, 8]]]
120
117
  expected = xp.asarray(expected)
121
- assert_array_almost_equal(expected, ft)
118
+ assert_array_almost_equal(ft, expected)
122
119
 
123
120
  @xfail_xp_backends('cupy', reason='CuPy does not have distance_transform_bf.')
124
121
  @pytest.mark.parametrize('dtype', types)
@@ -224,7 +221,7 @@ class TestNdimageMorphology:
224
221
  for ft in fts:
225
222
  assert_array_almost_equal(tft, ft)
226
223
 
227
- @xfail_xp_backends('cupy', reason='CuPy does not have distance_transform_bf.')
224
+ @xfail_xp_backends('cupy', reason='CuPy does not have distance_transform_bf')
228
225
  @pytest.mark.parametrize('dtype', types)
229
226
  def test_distance_transform_bf05(self, dtype, xp):
230
227
  dtype = getattr(xp, dtype)
@@ -273,7 +270,7 @@ class TestNdimageMorphology:
273
270
  expected = xp.asarray(expected)
274
271
  assert_array_almost_equal(ft, expected)
275
272
 
276
- @xfail_xp_backends('cupy', reason='CuPy does not have distance_transform_bf.')
273
+ @xfail_xp_backends('cupy', reason='CuPy does not have distance_transform_bf')
277
274
  @pytest.mark.parametrize('dtype', types)
278
275
  def test_distance_transform_bf06(self, dtype, xp):
279
276
  dtype = getattr(xp, dtype)
@@ -322,10 +319,8 @@ class TestNdimageMorphology:
322
319
  expected = xp.asarray(expected)
323
320
  assert_array_almost_equal(ft, expected)
324
321
 
322
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_bf")
325
323
  def test_distance_transform_bf07(self, xp):
326
- if is_cupy(xp):
327
- pytest.xfail("CuPy does not have distance_transform_bf.")
328
-
329
324
  # test input validation per discussion on PR #13302
330
325
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
331
326
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -341,11 +336,10 @@ class TestNdimageMorphology:
341
336
  data, return_distances=False, return_indices=False
342
337
  )
343
338
 
339
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_cdt")
344
340
  @pytest.mark.parametrize('dtype', types)
345
341
  def test_distance_transform_cdt01(self, dtype, xp):
346
342
  dtype = getattr(xp, dtype)
347
- if is_cupy(xp):
348
- pytest.xfail("CuPy does not have distance_transform_cdt.")
349
343
 
350
344
  # chamfer type distance (cdt) transform
351
345
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -383,12 +377,10 @@ class TestNdimageMorphology:
383
377
  expected = xp.asarray(expected)
384
378
  assert_array_almost_equal(ft, expected)
385
379
 
380
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_cdt")
386
381
  @pytest.mark.parametrize('dtype', types)
387
382
  def test_distance_transform_cdt02(self, dtype, xp):
388
383
  dtype = getattr(xp, dtype)
389
- if is_cupy(xp):
390
- pytest.xfail("CuPy does not have distance_transform_cdt.")
391
-
392
384
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
393
385
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
394
386
  [0, 0, 0, 1, 1, 1, 0, 0, 0],
@@ -500,13 +492,11 @@ class TestNdimageMorphology:
500
492
  indices=indices_out
501
493
  )
502
494
 
495
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_cdt")
496
+ @xfail_xp_backends("torch", reason="int overflow")
503
497
  @pytest.mark.parametrize('dtype', types)
504
498
  def test_distance_transform_cdt05(self, dtype, xp):
505
499
  dtype = getattr(xp, dtype)
506
- if is_cupy(xp):
507
- pytest.xfail("CuPy does not have distance_transform_cdt.")
508
- elif is_torch(xp):
509
- pytest.xfail("int overflow")
510
500
 
511
501
  # test custom metric type per discussion on issue #17381
512
502
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -522,11 +512,10 @@ class TestNdimageMorphology:
522
512
  actual = ndimage.distance_transform_cdt(data, metric=metric_arg)
523
513
  assert xp.sum(actual) == -21
524
514
 
515
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_bf")
525
516
  @pytest.mark.parametrize('dtype', types)
526
517
  def test_distance_transform_edt01(self, dtype, xp):
527
518
  dtype = getattr(xp, dtype)
528
- if is_cupy(xp):
529
- pytest.xfail("CuPy does not have distance_transform_bf")
530
519
 
531
520
  # euclidean distance transform (edt)
532
521
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -617,11 +606,10 @@ class TestNdimageMorphology:
617
606
  for ft in fts:
618
607
  assert_array_almost_equal(tft, ft)
619
608
 
609
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_bf")
620
610
  @pytest.mark.parametrize('dtype', types)
621
611
  def test_distance_transform_edt03(self, dtype, xp):
622
612
  dtype = getattr(xp, dtype)
623
- if is_cupy(xp):
624
- pytest.xfail("CuPy does not have distance_transform_bf")
625
613
 
626
614
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
627
615
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -634,13 +622,12 @@ class TestNdimageMorphology:
634
622
  [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=dtype)
635
623
  ref = ndimage.distance_transform_bf(data, 'euclidean', sampling=[2, 2])
636
624
  out = ndimage.distance_transform_edt(data, sampling=[2, 2])
637
- assert_array_almost_equal(ref, out)
625
+ assert_array_almost_equal(out, ref)
638
626
 
627
+ @xfail_xp_backends("cupy", reason="CuPy does not have distance_transform_bf")
639
628
  @pytest.mark.parametrize('dtype', types)
640
629
  def test_distance_transform_edt4(self, dtype, xp):
641
630
  dtype = getattr(xp, dtype)
642
- if is_cupy(xp):
643
- pytest.xfail("CuPy does not have distance_transform_bf")
644
631
 
645
632
  data = xp.asarray([[0, 0, 0, 0, 0, 0, 0, 0, 0],
646
633
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -653,14 +640,17 @@ class TestNdimageMorphology:
653
640
  [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=dtype)
654
641
  ref = ndimage.distance_transform_bf(data, 'euclidean', sampling=[2, 1])
655
642
  out = ndimage.distance_transform_edt(data, sampling=[2, 1])
656
- assert_array_almost_equal(ref, out)
643
+ assert_array_almost_equal(out, ref)
657
644
 
645
+ @xfail_xp_backends(
646
+ "cupy", reason="Only 2D and 3D distance transforms are supported in CuPy"
647
+ )
658
648
  def test_distance_transform_edt5(self, xp):
659
649
  # Ticket #954 regression test
660
- out = ndimage.distance_transform_edt(False)
661
- assert_array_almost_equal(out, [0.])
650
+ out = ndimage.distance_transform_edt(xp.asarray(False))
651
+ assert_array_almost_equal(out, xp.asarray([0.]))
662
652
 
663
- @skip_xp_backends(
653
+ @xfail_xp_backends(
664
654
  np_only=True, reason='XXX: does not raise unless indices is a numpy array'
665
655
  )
666
656
  def test_distance_transform_edt6(self, xp):
@@ -683,20 +673,28 @@ class TestNdimageMorphology:
683
673
  distances=distances_out
684
674
  )
685
675
 
676
+ @skip_xp_backends(np_only=True,
677
+ reason="generate_binary_structure always generates numpy objects")
686
678
  def test_generate_structure01(self, xp):
687
679
  struct = ndimage.generate_binary_structure(0, 1)
688
680
  assert struct == 1
689
681
 
682
+ @skip_xp_backends(np_only=True,
683
+ reason="generate_binary_structure always generates numpy objects")
690
684
  def test_generate_structure02(self, xp):
691
685
  struct = ndimage.generate_binary_structure(1, 1)
692
686
  assert_array_almost_equal(struct, [1, 1, 1])
693
687
 
688
+ @skip_xp_backends(np_only=True,
689
+ reason="generate_binary_structure always generates numpy objects")
694
690
  def test_generate_structure03(self, xp):
695
691
  struct = ndimage.generate_binary_structure(2, 1)
696
692
  assert_array_almost_equal(struct, [[0, 1, 0],
697
693
  [1, 1, 1],
698
694
  [0, 1, 0]])
699
695
 
696
+ @skip_xp_backends(np_only=True,
697
+ reason="generate_binary_structure always generates numpy objects")
700
698
  def test_generate_structure04(self, xp):
701
699
  struct = ndimage.generate_binary_structure(2, 2)
702
700
  assert_array_almost_equal(struct, [[1, 1, 1],
@@ -783,6 +781,15 @@ class TestNdimageMorphology:
783
781
  out = ndimage.binary_erosion(data)
784
782
  assert_array_almost_equal(out, xp.asarray([0, 1, 0]))
785
783
 
784
+ @pytest.mark.parametrize('dtype', types)
785
+ @xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/issues/8912")
786
+ def test_binary_erosion05_broadcasted(self, dtype, xp):
787
+ dtype = getattr(xp, dtype)
788
+ data = xp.ones((1, ), dtype=dtype)
789
+ data = xp.broadcast_to(data, (3, ))
790
+ out = ndimage.binary_erosion(data)
791
+ assert_array_almost_equal(out, xp.asarray([0, 1, 0]))
792
+
786
793
  @pytest.mark.parametrize('dtype', types)
787
794
  def test_binary_erosion06(self, dtype, xp):
788
795
  dtype = getattr(xp, dtype)
@@ -1039,10 +1046,10 @@ class TestNdimageMorphology:
1039
1046
  origin=(-1, -1))
1040
1047
  assert_array_almost_equal(out, expected)
1041
1048
 
1049
+ @xfail_xp_backends(
1050
+ "cupy", reason="CuPy: NotImplementedError: only brute_force iteration"
1051
+ )
1042
1052
  def test_binary_erosion27(self, xp):
1043
- if is_cupy(xp):
1044
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1045
-
1046
1053
  struct = [[0, 1, 0],
1047
1054
  [1, 1, 1],
1048
1055
  [0, 1, 0]]
@@ -1067,9 +1074,10 @@ class TestNdimageMorphology:
1067
1074
  iterations=2)
1068
1075
  assert_array_almost_equal(out, expected)
1069
1076
 
1070
- @skip_xp_backends(
1071
- np_only=True, reason='inplace out= arguments are numpy-specific'
1072
- )
1077
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1078
+ reason='inplace out= arguments are numpy-specific')
1079
+ @xfail_xp_backends("cupy",
1080
+ reason="NotImplementedError: only brute_force iteration")
1073
1081
  def test_binary_erosion28(self, xp):
1074
1082
  struct = [[0, 1, 0],
1075
1083
  [1, 1, 1],
@@ -1098,10 +1106,10 @@ class TestNdimageMorphology:
1098
1106
  iterations=2, output=out)
1099
1107
  assert_array_almost_equal(out, expected)
1100
1108
 
1109
+ @xfail_xp_backends(
1110
+ "cupy", reason="CuPy: NotImplementedError: only brute_force iteration"
1111
+ )
1101
1112
  def test_binary_erosion29(self, xp):
1102
- if is_cupy(xp):
1103
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1104
-
1105
1113
  struct = [[0, 1, 0],
1106
1114
  [1, 1, 1],
1107
1115
  [0, 1, 0]]
@@ -1126,13 +1134,11 @@ class TestNdimageMorphology:
1126
1134
  border_value=1, iterations=3)
1127
1135
  assert_array_almost_equal(out, expected)
1128
1136
 
1129
- @skip_xp_backends(
1130
- np_only=True, reason='inplace out= arguments are numpy-specific'
1131
- )
1137
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1138
+ reason='inplace out= arguments are numpy-specific')
1139
+ @xfail_xp_backends("cupy",
1140
+ reason="NotImplementedError: only brute_force iteration")
1132
1141
  def test_binary_erosion30(self, xp):
1133
- if is_cupy(xp):
1134
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1135
-
1136
1142
  struct = [[0, 1, 0],
1137
1143
  [1, 1, 1],
1138
1144
  [0, 1, 0]]
@@ -1165,9 +1171,8 @@ class TestNdimageMorphology:
1165
1171
  iterations=3, output=data)
1166
1172
  assert_array_almost_equal(data, expected)
1167
1173
 
1168
- @skip_xp_backends(
1169
- np_only=True, reason='inplace out= arguments are numpy-specific'
1170
- )
1174
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1175
+ reason='inplace out= arguments are numpy-specific')
1171
1176
  def test_binary_erosion31(self, xp):
1172
1177
  struct = [[0, 1, 0],
1173
1178
  [1, 1, 1],
@@ -1196,10 +1201,9 @@ class TestNdimageMorphology:
1196
1201
  iterations=1, output=out, origin=(-1, -1))
1197
1202
  assert_array_almost_equal(out, expected)
1198
1203
 
1204
+ @xfail_xp_backends("cupy",
1205
+ reason="NotImplementedError: only brute_force iteration")
1199
1206
  def test_binary_erosion32(self, xp):
1200
- if is_cupy(xp):
1201
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1202
-
1203
1207
  struct = [[0, 1, 0],
1204
1208
  [1, 1, 1],
1205
1209
  [0, 1, 0]]
@@ -1224,10 +1228,9 @@ class TestNdimageMorphology:
1224
1228
  border_value=1, iterations=2)
1225
1229
  assert_array_almost_equal(out, expected)
1226
1230
 
1231
+ @xfail_xp_backends("cupy",
1232
+ reason="NotImplementedError: only brute_force iteration")
1227
1233
  def test_binary_erosion33(self, xp):
1228
- if is_cupy(xp):
1229
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1230
-
1231
1234
  struct = [[0, 1, 0],
1232
1235
  [1, 1, 1],
1233
1236
  [0, 1, 0]]
@@ -1293,9 +1296,8 @@ class TestNdimageMorphology:
1293
1296
  border_value=1, mask=mask)
1294
1297
  assert_array_almost_equal(out, expected)
1295
1298
 
1296
- @skip_xp_backends(
1297
- np_only=True, reason='inplace out= arguments are numpy-specific'
1298
- )
1299
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1300
+ reason='inplace out= arguments are numpy-specific')
1299
1301
  def test_binary_erosion35(self, xp):
1300
1302
  struct = [[0, 1, 0],
1301
1303
  [1, 1, 1],
@@ -1337,10 +1339,9 @@ class TestNdimageMorphology:
1337
1339
  origin=(-1, -1), mask=mask)
1338
1340
  assert_array_almost_equal(out, expected)
1339
1341
 
1342
+ @xfail_xp_backends("cupy",
1343
+ reason="NotImplementedError: only brute_force iteration")
1340
1344
  def test_binary_erosion36(self, xp):
1341
- if is_cupy(xp):
1342
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1343
-
1344
1345
  struct = [[0, 1, 0],
1345
1346
  [1, 0, 1],
1346
1347
  [0, 1, 0]]
@@ -1381,9 +1382,10 @@ class TestNdimageMorphology:
1381
1382
  border_value=1, origin=(-1, -1))
1382
1383
  assert_array_almost_equal(out, expected)
1383
1384
 
1384
- @skip_xp_backends(
1385
- np_only=True, reason='inplace out= arguments are numpy-specific'
1386
- )
1385
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1386
+ reason='inplace out= arguments are numpy-specific')
1387
+ @xfail_xp_backends("cupy",
1388
+ reason="NotImplementedError: only brute_force iteration")
1387
1389
  def test_binary_erosion37(self, xp):
1388
1390
  a = np.asarray([[1, 0, 1],
1389
1391
  [0, 1, 0],
@@ -1407,9 +1409,10 @@ class TestNdimageMorphology:
1407
1409
  with assert_raises(TypeError):
1408
1410
  _ = ndimage.binary_erosion(data, iterations=iterations)
1409
1411
 
1410
- @skip_xp_backends(
1411
- np_only=True, reason='inplace out= arguments are numpy-specific'
1412
- )
1412
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1413
+ reason='inplace out= arguments are numpy-specific')
1414
+ @xfail_xp_backends("cupy",
1415
+ reason="NotImplementedError: only brute_force iteration")
1413
1416
  def test_binary_erosion39(self, xp):
1414
1417
  iterations = np.int32(3)
1415
1418
  struct = [[0, 1, 0],
@@ -1439,9 +1442,10 @@ class TestNdimageMorphology:
1439
1442
  iterations=iterations, output=out)
1440
1443
  assert_array_almost_equal(out, expected)
1441
1444
 
1442
- @skip_xp_backends(
1443
- np_only=True, reason='inplace out= arguments are numpy-specific'
1444
- )
1445
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1446
+ reason='inplace out= arguments are numpy-specific')
1447
+ @xfail_xp_backends("cupy",
1448
+ reason="NotImplementedError: only brute_force iteration")
1445
1449
  def test_binary_erosion40(self, xp):
1446
1450
  iterations = np.int64(3)
1447
1451
  struct = [[0, 1, 0],
@@ -1506,6 +1510,14 @@ class TestNdimageMorphology:
1506
1510
  out = ndimage.binary_dilation(data)
1507
1511
  assert_array_almost_equal(out, xp.asarray([1, 1, 1]))
1508
1512
 
1513
+ @pytest.mark.parametrize('dtype', types)
1514
+ def test_binary_dilation05_broadcasted(self, dtype, xp):
1515
+ dtype = getattr(xp, dtype)
1516
+ data = xp.ones((1, ), dtype=dtype)
1517
+ data = xp.broadcast_to(data, (3,))
1518
+ out = ndimage.binary_dilation(data)
1519
+ assert_array_almost_equal(out, xp.asarray([1, 1, 1]))
1520
+
1509
1521
  @pytest.mark.parametrize('dtype', types)
1510
1522
  def test_binary_dilation06(self, dtype, xp):
1511
1523
  dtype = getattr(xp, dtype)
@@ -1801,10 +1813,9 @@ class TestNdimageMorphology:
1801
1813
  out = ndimage.binary_dilation(data, border_value=1)
1802
1814
  assert_array_almost_equal(out, expected)
1803
1815
 
1816
+ @xfail_xp_backends("cupy",
1817
+ reason="NotImplementedError: only brute_force iteration")
1804
1818
  def test_binary_dilation29(self, xp):
1805
- if is_cupy(xp):
1806
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1807
-
1808
1819
  struct = [[0, 1],
1809
1820
  [1, 1]]
1810
1821
  expected = [[0, 0, 0, 0, 0],
@@ -1823,10 +1834,11 @@ class TestNdimageMorphology:
1823
1834
  out = ndimage.binary_dilation(data, struct, iterations=2)
1824
1835
  assert_array_almost_equal(out, expected)
1825
1836
 
1826
- @skip_xp_backends(np_only=True, reason='output= arrays are numpy-specific')
1837
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1838
+ reason='output= arrays are numpy-specific')
1839
+ @xfail_xp_backends("cupy",
1840
+ reason="NotImplementedError: only brute_force iteration")
1827
1841
  def test_binary_dilation30(self, xp):
1828
- if is_cupy(xp):
1829
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1830
1842
  struct = [[0, 1],
1831
1843
  [1, 1]]
1832
1844
  expected = [[0, 0, 0, 0, 0],
@@ -1847,10 +1859,9 @@ class TestNdimageMorphology:
1847
1859
  ndimage.binary_dilation(data, struct, iterations=2, output=out)
1848
1860
  assert_array_almost_equal(out, expected)
1849
1861
 
1862
+ @xfail_xp_backends("cupy",
1863
+ reason="NotImplementedError: only brute_force iteration")
1850
1864
  def test_binary_dilation31(self, xp):
1851
- if is_cupy(xp):
1852
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1853
-
1854
1865
  struct = [[0, 1],
1855
1866
  [1, 1]]
1856
1867
  expected = [[0, 0, 0, 1, 0],
@@ -1869,11 +1880,11 @@ class TestNdimageMorphology:
1869
1880
  out = ndimage.binary_dilation(data, struct, iterations=3)
1870
1881
  assert_array_almost_equal(out, expected)
1871
1882
 
1872
- @skip_xp_backends(np_only=True, reason='output= arrays are numpy-specific')
1883
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1884
+ reason='output= arrays are numpy-specific')
1885
+ @xfail_xp_backends("cupy",
1886
+ reason="NotImplementedError: only brute_force iteration")
1873
1887
  def test_binary_dilation32(self, xp):
1874
- if is_cupy(xp):
1875
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1876
-
1877
1888
  struct = [[0, 1],
1878
1889
  [1, 1]]
1879
1890
  expected = [[0, 0, 0, 1, 0],
@@ -1894,9 +1905,9 @@ class TestNdimageMorphology:
1894
1905
  ndimage.binary_dilation(data, struct, iterations=3, output=out)
1895
1906
  assert_array_almost_equal(out, expected)
1896
1907
 
1908
+ @xfail_xp_backends("cupy",
1909
+ reason="NotImplementedError: only brute_force iteration")
1897
1910
  def test_binary_dilation33(self, xp):
1898
- if is_cupy(xp):
1899
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1900
1911
  struct = [[0, 1, 0],
1901
1912
  [1, 1, 1],
1902
1913
  [0, 1, 0]]
@@ -1933,13 +1944,11 @@ class TestNdimageMorphology:
1933
1944
  mask=mask, border_value=0)
1934
1945
  assert_array_almost_equal(out, expected)
1935
1946
 
1936
- @skip_xp_backends(
1937
- np_only=True, reason='inplace output= arrays are numpy-specific',
1938
- )
1947
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
1948
+ reason='inplace output= arrays are numpy-specific')
1949
+ @xfail_xp_backends("cupy",
1950
+ reason="NotImplementedError: only brute_force iteration")
1939
1951
  def test_binary_dilation34(self, xp):
1940
- if is_cupy(xp):
1941
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
1942
-
1943
1952
  struct = [[0, 1, 0],
1944
1953
  [1, 1, 1],
1945
1954
  [0, 1, 0]]
@@ -2322,7 +2331,8 @@ class TestNdimageMorphology:
2322
2331
  [2, 3, 1, 3, 1],
2323
2332
  [5, 5, 3, 3, 1]]))
2324
2333
 
2325
- @skip_xp_backends("jax.numpy", reason="output array is read-only.")
2334
+ @skip_xp_backends("jax.numpy", reason="output=array requires buffer view")
2335
+ @skip_xp_backends("dask.array", reason="output=array requires buffer view")
2326
2336
  @xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/issues/8398")
2327
2337
  def test_grey_erosion01_overlap(self, xp):
2328
2338
 
@@ -2437,7 +2447,7 @@ class TestNdimageMorphology:
2437
2447
  tmp = ndimage.grey_dilation(array, footprint=footprint)
2438
2448
  expected = ndimage.grey_erosion(tmp, footprint=footprint)
2439
2449
  output = ndimage.grey_closing(array, footprint=footprint)
2440
- assert_array_almost_equal(expected, output)
2450
+ assert_array_almost_equal(output, expected)
2441
2451
 
2442
2452
  def test_grey_closing02(self, xp):
2443
2453
  array = xp.asarray([[3, 2, 5, 1, 4],
@@ -2451,7 +2461,7 @@ class TestNdimageMorphology:
2451
2461
  structure=structure)
2452
2462
  output = ndimage.grey_closing(array, footprint=footprint,
2453
2463
  structure=structure)
2454
- assert_array_almost_equal(expected, output)
2464
+ assert_array_almost_equal(output, expected)
2455
2465
 
2456
2466
  @skip_xp_backends(np_only=True, reason='output= arrays are numpy-specific')
2457
2467
  def test_morphological_gradient01(self, xp):
@@ -2468,7 +2478,7 @@ class TestNdimageMorphology:
2468
2478
  output = xp.zeros(array.shape, dtype=array.dtype)
2469
2479
  ndimage.morphological_gradient(array, footprint=footprint,
2470
2480
  structure=structure, output=output)
2471
- assert_array_almost_equal(expected, output)
2481
+ assert_array_almost_equal(output, expected)
2472
2482
 
2473
2483
  def test_morphological_gradient02(self, xp):
2474
2484
  array = xp.asarray([[3, 2, 5, 1, 4],
@@ -2483,7 +2493,7 @@ class TestNdimageMorphology:
2483
2493
  expected = tmp1 - tmp2
2484
2494
  output = ndimage.morphological_gradient(array, footprint=footprint,
2485
2495
  structure=structure)
2486
- assert_array_almost_equal(expected, output)
2496
+ assert_array_almost_equal(output, expected)
2487
2497
 
2488
2498
  @skip_xp_backends(np_only=True, reason='output= arrays are numpy-specific')
2489
2499
  def test_morphological_laplace01(self, xp):
@@ -2500,7 +2510,7 @@ class TestNdimageMorphology:
2500
2510
  output = xp.zeros(array.shape, dtype=array.dtype)
2501
2511
  ndimage.morphological_laplace(array, footprint=footprint,
2502
2512
  structure=structure, output=output)
2503
- assert_array_almost_equal(expected, output)
2513
+ assert_array_almost_equal(output, expected)
2504
2514
 
2505
2515
  def test_morphological_laplace02(self, xp):
2506
2516
  array = xp.asarray([[3, 2, 5, 1, 4],
@@ -2515,9 +2525,10 @@ class TestNdimageMorphology:
2515
2525
  expected = tmp1 + tmp2 - 2 * array
2516
2526
  output = ndimage.morphological_laplace(array, footprint=footprint,
2517
2527
  structure=structure)
2518
- assert_array_almost_equal(expected, output)
2528
+ assert_array_almost_equal(output, expected)
2519
2529
 
2520
- @skip_xp_backends("jax.numpy", reason="output array is read-only.")
2530
+ @skip_xp_backends("jax.numpy", reason="output=array requires buffer view")
2531
+ @skip_xp_backends("dask.array", reason="output=array requires buffer view")
2521
2532
  def test_white_tophat01(self, xp):
2522
2533
  array = xp.asarray([[3, 2, 5, 1, 4],
2523
2534
  [7, 6, 9, 3, 5],
@@ -2530,7 +2541,7 @@ class TestNdimageMorphology:
2530
2541
  output = xp.zeros(array.shape, dtype=array.dtype)
2531
2542
  ndimage.white_tophat(array, footprint=footprint,
2532
2543
  structure=structure, output=output)
2533
- assert_array_almost_equal(expected, output)
2544
+ assert_array_almost_equal(output, expected)
2534
2545
 
2535
2546
  def test_white_tophat02(self, xp):
2536
2547
  array = xp.asarray([[3, 2, 5, 1, 4],
@@ -2543,7 +2554,7 @@ class TestNdimageMorphology:
2543
2554
  expected = array - tmp
2544
2555
  output = ndimage.white_tophat(array, footprint=footprint,
2545
2556
  structure=structure)
2546
- assert_array_almost_equal(expected, output)
2557
+ assert_array_almost_equal(output, expected)
2547
2558
 
2548
2559
  @xfail_xp_backends('cupy', reason="cupy#8399")
2549
2560
  def test_white_tophat03(self, xp):
@@ -2568,9 +2579,10 @@ class TestNdimageMorphology:
2568
2579
  expected = xp.asarray(expected)
2569
2580
 
2570
2581
  output = ndimage.white_tophat(array, structure=structure)
2571
- xp_assert_equal(expected, output)
2582
+ xp_assert_equal(output, expected)
2572
2583
 
2573
- @skip_xp_backends("jax.numpy", reason="output array is read-only.")
2584
+ @skip_xp_backends("jax.numpy", reason="output=array requires buffer view")
2585
+ @skip_xp_backends("dask.array", reason="output=array requires buffer view")
2574
2586
  def test_white_tophat04(self, xp):
2575
2587
  array = np.eye(5, dtype=bool)
2576
2588
  structure = np.ones((3, 3), dtype=bool)
@@ -2582,7 +2594,8 @@ class TestNdimageMorphology:
2582
2594
  output = xp.empty_like(array, dtype=xp.float64)
2583
2595
  ndimage.white_tophat(array, structure=structure, output=output)
2584
2596
 
2585
- @skip_xp_backends("jax.numpy", reason="output array is read-only.")
2597
+ @skip_xp_backends("jax.numpy", reason="output=array requires buffer view")
2598
+ @skip_xp_backends("dask.array", reason="output=array requires buffer view")
2586
2599
  def test_black_tophat01(self, xp):
2587
2600
  array = xp.asarray([[3, 2, 5, 1, 4],
2588
2601
  [7, 6, 9, 3, 5],
@@ -2595,7 +2608,7 @@ class TestNdimageMorphology:
2595
2608
  output = xp.zeros(array.shape, dtype=array.dtype)
2596
2609
  ndimage.black_tophat(array, footprint=footprint,
2597
2610
  structure=structure, output=output)
2598
- assert_array_almost_equal(expected, output)
2611
+ assert_array_almost_equal(output, expected)
2599
2612
 
2600
2613
  def test_black_tophat02(self, xp):
2601
2614
  array = xp.asarray([[3, 2, 5, 1, 4],
@@ -2608,7 +2621,7 @@ class TestNdimageMorphology:
2608
2621
  expected = tmp - array
2609
2622
  output = ndimage.black_tophat(array, footprint=footprint,
2610
2623
  structure=structure)
2611
- assert_array_almost_equal(expected, output)
2624
+ assert_array_almost_equal(output, expected)
2612
2625
 
2613
2626
  @xfail_xp_backends('cupy', reason="cupy/cupy#8399")
2614
2627
  def test_black_tophat03(self, xp):
@@ -2633,9 +2646,10 @@ class TestNdimageMorphology:
2633
2646
  expected = xp.asarray(expected)
2634
2647
 
2635
2648
  output = ndimage.black_tophat(array, structure=structure)
2636
- xp_assert_equal(expected, output)
2649
+ xp_assert_equal(output, expected)
2637
2650
 
2638
- @skip_xp_backends("jax.numpy", reason="output array is read-only.")
2651
+ @skip_xp_backends("jax.numpy", reason="output=array requires buffer view")
2652
+ @skip_xp_backends("dask.array", reason="output=array requires buffer view")
2639
2653
  def test_black_tophat04(self, xp):
2640
2654
  array = xp.asarray(np.eye(5, dtype=bool))
2641
2655
  structure = xp.asarray(np.ones((3, 3), dtype=bool))
@@ -2700,11 +2714,10 @@ class TestNdimageMorphology:
2700
2714
  out = func(data, axes=axes, **kwargs)
2701
2715
  xp_assert_close(out, expected)
2702
2716
 
2717
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
2718
+ reason="inplace output= is numpy-specific")
2703
2719
  @pytest.mark.parametrize('dtype', types)
2704
2720
  def test_hit_or_miss01(self, dtype, xp):
2705
- if not (is_numpy(xp) or is_cupy(xp)):
2706
- pytest.xfail("inplace output= is numpy-specific")
2707
-
2708
2721
  dtype = getattr(xp, dtype)
2709
2722
  struct = [[0, 1, 0],
2710
2723
  [1, 1, 1],
@@ -2729,7 +2742,7 @@ class TestNdimageMorphology:
2729
2742
  [0, 0, 0, 0, 0]], dtype=dtype)
2730
2743
  out = xp.asarray(np.zeros(data.shape, dtype=bool))
2731
2744
  ndimage.binary_hit_or_miss(data, struct, output=out)
2732
- assert_array_almost_equal(expected, out)
2745
+ assert_array_almost_equal(out, expected)
2733
2746
 
2734
2747
  @pytest.mark.parametrize('dtype', types)
2735
2748
  def test_hit_or_miss02(self, dtype, xp):
@@ -2748,7 +2761,7 @@ class TestNdimageMorphology:
2748
2761
  [0, 1, 0, 1, 1, 1, 1, 0],
2749
2762
  [0, 0, 0, 0, 0, 0, 0, 0]], dtype=dtype)
2750
2763
  out = ndimage.binary_hit_or_miss(data, struct)
2751
- assert_array_almost_equal(expected, out)
2764
+ assert_array_almost_equal(out, expected)
2752
2765
 
2753
2766
  @pytest.mark.parametrize('dtype', types)
2754
2767
  def test_hit_or_miss03(self, dtype, xp):
@@ -2779,7 +2792,7 @@ class TestNdimageMorphology:
2779
2792
  [0, 1, 1, 1, 1, 1, 1, 0],
2780
2793
  [0, 0, 0, 0, 0, 0, 0, 0]], dtype=dtype)
2781
2794
  out = ndimage.binary_hit_or_miss(data, struct1, struct2)
2782
- assert_array_almost_equal(expected, out)
2795
+ assert_array_almost_equal(out, expected)
2783
2796
 
2784
2797
 
2785
2798
  class TestDilateFix:
@@ -2800,9 +2813,7 @@ class TestDilateFix:
2800
2813
  if is_numpy(xp):
2801
2814
  self.dilated3x3 = dilated3x3.view(xp.uint8)
2802
2815
  else:
2803
- astype = array_namespace(dilated3x3).astype
2804
- self.dilated3x3 = astype(dilated3x3, xp.uint8)
2805
-
2816
+ self.dilated3x3 = xp.astype(dilated3x3, xp.uint8)
2806
2817
 
2807
2818
  def test_dilation_square_structure(self, xp):
2808
2819
  self._setup(xp)
@@ -2874,14 +2885,12 @@ def test_binary_closing_noninteger_iterations(xp):
2874
2885
  assert_raises(TypeError, ndimage.binary_closing, data, iterations=1.5)
2875
2886
 
2876
2887
 
2888
+ @xfail_xp_backends(
2889
+ "cupy", reason="CuPy: NotImplementedError: only brute_force iteration"
2890
+ )
2877
2891
  def test_binary_closing_noninteger_brute_force_passes_when_true(xp):
2878
- # regression test for gh-9905, gh-9909: ValueError for
2879
- # non integer iterations
2880
- if is_cupy(xp):
2881
- pytest.xfail("CuPy: NotImplementedError: only brute_force iteration")
2882
-
2892
+ # regression test for gh-9905, gh-9909: ValueError for non integer iterations
2883
2893
  data = xp.ones([1])
2884
-
2885
2894
  xp_assert_equal(ndimage.binary_erosion(data, iterations=2, brute_force=1.5),
2886
2895
  ndimage.binary_erosion(data, iterations=2, brute_force=bool(1.5))
2887
2896
  )
@@ -2890,6 +2899,9 @@ def test_binary_closing_noninteger_brute_force_passes_when_true(xp):
2890
2899
  )
2891
2900
 
2892
2901
 
2902
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
2903
+ reason="inplace output= is numpy-specific")
2904
+ @xfail_xp_backends("cupy", reason="NotImplementedError: only brute_force iteration")
2893
2905
  @pytest.mark.parametrize(
2894
2906
  'function',
2895
2907
  ['binary_erosion', 'binary_dilation', 'binary_opening', 'binary_closing'],
@@ -2899,6 +2911,7 @@ def test_binary_closing_noninteger_brute_force_passes_when_true(xp):
2899
2911
  def test_binary_input_as_output(function, iterations, brute_force, xp):
2900
2912
  rstate = np.random.RandomState(123)
2901
2913
  data = rstate.randint(low=0, high=2, size=100).astype(bool)
2914
+ data = xp.asarray(data)
2902
2915
  ndi_func = getattr(ndimage, function)
2903
2916
 
2904
2917
  # input data is not modified
@@ -2908,15 +2921,15 @@ def test_binary_input_as_output(function, iterations, brute_force, xp):
2908
2921
 
2909
2922
  # data should now contain the expected result
2910
2923
  ndi_func(data, brute_force=brute_force, iterations=iterations, output=data)
2911
- xp_assert_equal(expected, data)
2924
+ xp_assert_equal(data, expected)
2912
2925
 
2913
2926
 
2927
+ @skip_xp_backends(np_only=True, exceptions=["cupy"],
2928
+ reason="inplace output= is numpy-specific")
2914
2929
  def test_binary_hit_or_miss_input_as_output(xp):
2915
- if not (is_numpy(xp) or is_cupy(xp)):
2916
- pytest.xfail("inplace output= is numpy-specific")
2917
-
2918
2930
  rstate = np.random.RandomState(123)
2919
2931
  data = rstate.randint(low=0, high=2, size=100).astype(bool)
2932
+ data = xp.asarray(data)
2920
2933
 
2921
2934
  # input data is not modified
2922
2935
  data_orig = data.copy()
@@ -2925,13 +2938,12 @@ def test_binary_hit_or_miss_input_as_output(xp):
2925
2938
 
2926
2939
  # data should now contain the expected result
2927
2940
  ndimage.binary_hit_or_miss(data, output=data)
2928
- xp_assert_equal(expected, data)
2941
+ xp_assert_equal(data, expected)
2929
2942
 
2930
2943
 
2944
+ @xfail_xp_backends("cupy",
2945
+ reason="CuPy does not have distance_transform_cdt")
2931
2946
  def test_distance_transform_cdt_invalid_metric(xp):
2932
- if is_cupy(xp):
2933
- pytest.xfail("CuPy does not have distance_transform_cdt")
2934
-
2935
2947
  msg = 'invalid metric provided'
2936
2948
  with pytest.raises(ValueError, match=msg):
2937
2949
  ndimage.distance_transform_cdt(xp.ones((5, 5)),