scipy 1.15.3__cp313-cp313-macosx_14_0_arm64.whl → 1.16.0__cp313-cp313-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 (632) hide show
  1. scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. scipy/.dylibs/libgfortran.5.dylib +0 -0
  3. scipy/.dylibs/libquadmath.0.dylib +0 -0
  4. scipy/__config__.py +5 -5
  5. scipy/__init__.py +3 -6
  6. scipy/_cyutility.cpython-313-darwin.so +0 -0
  7. scipy/_lib/_array_api.py +486 -161
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_bunch.py +4 -0
  10. scipy/_lib/_ccallback_c.cpython-313-darwin.so +0 -0
  11. scipy/_lib/_docscrape.py +1 -1
  12. scipy/_lib/_elementwise_iterative_method.py +15 -26
  13. scipy/_lib/_sparse.py +41 -0
  14. scipy/_lib/_test_deprecation_call.cpython-313-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_def.cpython-313-darwin.so +0 -0
  16. scipy/_lib/_testutils.py +6 -2
  17. scipy/_lib/_util.py +222 -125
  18. scipy/_lib/array_api_compat/__init__.py +4 -4
  19. scipy/_lib/array_api_compat/_internal.py +19 -6
  20. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  21. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  22. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  23. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  24. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  25. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  26. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  27. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  28. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  29. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  30. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  31. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  32. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  33. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  34. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  35. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  36. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  37. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  38. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  39. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  40. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  41. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  42. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  43. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  44. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  45. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  46. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  47. scipy/_lib/array_api_extra/__init__.py +26 -3
  48. scipy/_lib/array_api_extra/_delegation.py +171 -0
  49. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  50. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  51. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  52. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  53. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  54. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  61. scipy/_lib/array_api_extra/testing.py +359 -0
  62. scipy/_lib/decorator.py +2 -2
  63. scipy/_lib/doccer.py +1 -7
  64. scipy/_lib/messagestream.cpython-313-darwin.so +0 -0
  65. scipy/_lib/pyprima/__init__.py +212 -0
  66. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  67. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  68. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  69. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  70. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  71. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  72. scipy/_lib/pyprima/cobyla/update.py +289 -0
  73. scipy/_lib/pyprima/common/__init__.py +0 -0
  74. scipy/_lib/pyprima/common/_bounds.py +34 -0
  75. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  76. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  77. scipy/_lib/pyprima/common/_project.py +173 -0
  78. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  79. scipy/_lib/pyprima/common/consts.py +47 -0
  80. scipy/_lib/pyprima/common/evaluate.py +99 -0
  81. scipy/_lib/pyprima/common/history.py +38 -0
  82. scipy/_lib/pyprima/common/infos.py +30 -0
  83. scipy/_lib/pyprima/common/linalg.py +435 -0
  84. scipy/_lib/pyprima/common/message.py +290 -0
  85. scipy/_lib/pyprima/common/powalg.py +131 -0
  86. scipy/_lib/pyprima/common/preproc.py +277 -0
  87. scipy/_lib/pyprima/common/present.py +5 -0
  88. scipy/_lib/pyprima/common/ratio.py +54 -0
  89. scipy/_lib/pyprima/common/redrho.py +47 -0
  90. scipy/_lib/pyprima/common/selectx.py +296 -0
  91. scipy/_lib/tests/test__util.py +105 -121
  92. scipy/_lib/tests/test_array_api.py +166 -35
  93. scipy/_lib/tests/test_bunch.py +7 -0
  94. scipy/_lib/tests/test_ccallback.py +2 -10
  95. scipy/_lib/tests/test_public_api.py +13 -0
  96. scipy/cluster/_hierarchy.cpython-313-darwin.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-313-darwin.so +0 -0
  98. scipy/cluster/_vq.cpython-313-darwin.so +0 -0
  99. scipy/cluster/hierarchy.py +393 -223
  100. scipy/cluster/tests/test_hierarchy.py +273 -335
  101. scipy/cluster/tests/test_vq.py +45 -61
  102. scipy/cluster/vq.py +39 -35
  103. scipy/conftest.py +282 -151
  104. scipy/constants/_constants.py +4 -1
  105. scipy/constants/tests/test_codata.py +2 -2
  106. scipy/constants/tests/test_constants.py +11 -18
  107. scipy/datasets/_download_all.py +15 -1
  108. scipy/datasets/_fetchers.py +7 -1
  109. scipy/datasets/_utils.py +1 -1
  110. scipy/differentiate/_differentiate.py +25 -25
  111. scipy/differentiate/tests/test_differentiate.py +24 -25
  112. scipy/fft/_basic.py +20 -0
  113. scipy/fft/_helper.py +3 -34
  114. scipy/fft/_pocketfft/helper.py +29 -1
  115. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  116. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  117. scipy/fft/_realtransforms.py +13 -0
  118. scipy/fft/tests/test_basic.py +27 -25
  119. scipy/fft/tests/test_fftlog.py +16 -7
  120. scipy/fft/tests/test_helper.py +18 -34
  121. scipy/fft/tests/test_real_transforms.py +8 -10
  122. scipy/fftpack/convolve.cpython-313-darwin.so +0 -0
  123. scipy/fftpack/tests/test_basic.py +2 -4
  124. scipy/fftpack/tests/test_real_transforms.py +8 -9
  125. scipy/integrate/_bvp.py +9 -3
  126. scipy/integrate/_cubature.py +3 -2
  127. scipy/integrate/_dop.cpython-313-darwin.so +0 -0
  128. scipy/integrate/_lsoda.cpython-313-darwin.so +0 -0
  129. scipy/integrate/_ode.py +9 -2
  130. scipy/integrate/_odepack.cpython-313-darwin.so +0 -0
  131. scipy/integrate/_quad_vec.py +21 -29
  132. scipy/integrate/_quadpack.cpython-313-darwin.so +0 -0
  133. scipy/integrate/_quadpack_py.py +11 -7
  134. scipy/integrate/_quadrature.py +3 -3
  135. scipy/integrate/_rules/_base.py +2 -2
  136. scipy/integrate/_tanhsinh.py +48 -47
  137. scipy/integrate/_test_odeint_banded.cpython-313-darwin.so +0 -0
  138. scipy/integrate/_vode.cpython-313-darwin.so +0 -0
  139. scipy/integrate/tests/test__quad_vec.py +0 -6
  140. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  141. scipy/integrate/tests/test_cubature.py +21 -35
  142. scipy/integrate/tests/test_quadrature.py +6 -8
  143. scipy/integrate/tests/test_tanhsinh.py +56 -48
  144. scipy/interpolate/__init__.py +70 -58
  145. scipy/interpolate/_bary_rational.py +22 -22
  146. scipy/interpolate/_bsplines.py +119 -66
  147. scipy/interpolate/_cubic.py +65 -50
  148. scipy/interpolate/_dfitpack.cpython-313-darwin.so +0 -0
  149. scipy/interpolate/_dierckx.cpython-313-darwin.so +0 -0
  150. scipy/interpolate/_fitpack.cpython-313-darwin.so +0 -0
  151. scipy/interpolate/_fitpack2.py +9 -6
  152. scipy/interpolate/_fitpack_impl.py +32 -26
  153. scipy/interpolate/_fitpack_repro.py +23 -19
  154. scipy/interpolate/_interpnd.cpython-313-darwin.so +0 -0
  155. scipy/interpolate/_interpolate.py +30 -12
  156. scipy/interpolate/_ndbspline.py +13 -18
  157. scipy/interpolate/_ndgriddata.py +5 -8
  158. scipy/interpolate/_polyint.py +95 -31
  159. scipy/interpolate/_ppoly.cpython-313-darwin.so +0 -0
  160. scipy/interpolate/_rbf.py +2 -2
  161. scipy/interpolate/_rbfinterp.py +1 -1
  162. scipy/interpolate/_rbfinterp_pythran.cpython-313-darwin.so +0 -0
  163. scipy/interpolate/_rgi.py +31 -26
  164. scipy/interpolate/_rgi_cython.cpython-313-darwin.so +0 -0
  165. scipy/interpolate/dfitpack.py +0 -20
  166. scipy/interpolate/interpnd.py +1 -2
  167. scipy/interpolate/tests/test_bary_rational.py +2 -2
  168. scipy/interpolate/tests/test_bsplines.py +97 -1
  169. scipy/interpolate/tests/test_fitpack2.py +39 -1
  170. scipy/interpolate/tests/test_interpnd.py +32 -20
  171. scipy/interpolate/tests/test_interpolate.py +48 -4
  172. scipy/interpolate/tests/test_rgi.py +2 -1
  173. scipy/io/_fast_matrix_market/__init__.py +2 -0
  174. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  175. scipy/io/_harwell_boeing/hb.py +7 -11
  176. scipy/io/_idl.py +5 -7
  177. scipy/io/_netcdf.py +15 -5
  178. scipy/io/_test_fortran.cpython-313-darwin.so +0 -0
  179. scipy/io/arff/tests/test_arffread.py +3 -3
  180. scipy/io/matlab/__init__.py +5 -3
  181. scipy/io/matlab/_mio.py +4 -1
  182. scipy/io/matlab/_mio5.py +19 -13
  183. scipy/io/matlab/_mio5_utils.cpython-313-darwin.so +0 -0
  184. scipy/io/matlab/_mio_utils.cpython-313-darwin.so +0 -0
  185. scipy/io/matlab/_miobase.py +4 -1
  186. scipy/io/matlab/_streams.cpython-313-darwin.so +0 -0
  187. scipy/io/matlab/tests/test_mio.py +46 -18
  188. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  189. scipy/io/tests/test_mmio.py +7 -1
  190. scipy/io/tests/test_wavfile.py +41 -0
  191. scipy/io/wavfile.py +57 -10
  192. scipy/linalg/_basic.py +113 -86
  193. scipy/linalg/_cythonized_array_utils.cpython-313-darwin.so +0 -0
  194. scipy/linalg/_decomp.py +22 -9
  195. scipy/linalg/_decomp_cholesky.py +28 -13
  196. scipy/linalg/_decomp_cossin.py +45 -30
  197. scipy/linalg/_decomp_interpolative.cpython-313-darwin.so +0 -0
  198. scipy/linalg/_decomp_ldl.py +4 -1
  199. scipy/linalg/_decomp_lu.py +18 -6
  200. scipy/linalg/_decomp_lu_cython.cpython-313-darwin.so +0 -0
  201. scipy/linalg/_decomp_polar.py +2 -0
  202. scipy/linalg/_decomp_qr.py +6 -2
  203. scipy/linalg/_decomp_qz.py +3 -0
  204. scipy/linalg/_decomp_schur.py +3 -1
  205. scipy/linalg/_decomp_svd.py +13 -2
  206. scipy/linalg/_decomp_update.cpython-313-darwin.so +0 -0
  207. scipy/linalg/_expm_frechet.py +4 -0
  208. scipy/linalg/_fblas.cpython-313-darwin.so +0 -0
  209. scipy/linalg/_flapack.cpython-313-darwin.so +0 -0
  210. scipy/linalg/_linalg_pythran.cpython-313-darwin.so +0 -0
  211. scipy/linalg/_matfuncs.py +187 -4
  212. scipy/linalg/_matfuncs_expm.cpython-313-darwin.so +0 -0
  213. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-darwin.so +0 -0
  214. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  215. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-darwin.so +0 -0
  216. scipy/linalg/_procrustes.py +2 -0
  217. scipy/linalg/_sketches.py +17 -6
  218. scipy/linalg/_solve_toeplitz.cpython-313-darwin.so +0 -0
  219. scipy/linalg/_solvers.py +7 -2
  220. scipy/linalg/_special_matrices.py +26 -36
  221. scipy/linalg/blas.py +35 -24
  222. scipy/linalg/cython_blas.cpython-313-darwin.so +0 -0
  223. scipy/linalg/cython_lapack.cpython-313-darwin.so +0 -0
  224. scipy/linalg/lapack.py +22 -2
  225. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  226. scipy/linalg/tests/test_basic.py +31 -16
  227. scipy/linalg/tests/test_batch.py +588 -0
  228. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  229. scipy/linalg/tests/test_decomp.py +40 -3
  230. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  231. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  232. scipy/linalg/tests/test_lapack.py +115 -7
  233. scipy/linalg/tests/test_matfuncs.py +157 -102
  234. scipy/linalg/tests/test_procrustes.py +0 -7
  235. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  236. scipy/linalg/tests/test_special_matrices.py +1 -5
  237. scipy/ndimage/__init__.py +1 -0
  238. scipy/ndimage/_cytest.cpython-313-darwin.so +0 -0
  239. scipy/ndimage/_delegators.py +8 -2
  240. scipy/ndimage/_filters.py +453 -5
  241. scipy/ndimage/_interpolation.py +36 -6
  242. scipy/ndimage/_measurements.py +4 -2
  243. scipy/ndimage/_morphology.py +5 -0
  244. scipy/ndimage/_nd_image.cpython-313-darwin.so +0 -0
  245. scipy/ndimage/_ni_docstrings.py +5 -1
  246. scipy/ndimage/_ni_label.cpython-313-darwin.so +0 -0
  247. scipy/ndimage/_ni_support.py +1 -5
  248. scipy/ndimage/_rank_filter_1d.cpython-313-darwin.so +0 -0
  249. scipy/ndimage/_support_alternative_backends.py +18 -6
  250. scipy/ndimage/tests/test_filters.py +370 -259
  251. scipy/ndimage/tests/test_fourier.py +7 -9
  252. scipy/ndimage/tests/test_interpolation.py +68 -61
  253. scipy/ndimage/tests/test_measurements.py +18 -35
  254. scipy/ndimage/tests/test_morphology.py +143 -131
  255. scipy/ndimage/tests/test_splines.py +1 -3
  256. scipy/odr/__odrpack.cpython-313-darwin.so +0 -0
  257. scipy/optimize/_basinhopping.py +13 -7
  258. scipy/optimize/_bglu_dense.cpython-313-darwin.so +0 -0
  259. scipy/optimize/_bracket.py +17 -24
  260. scipy/optimize/_chandrupatla.py +9 -10
  261. scipy/optimize/_cobyla_py.py +104 -123
  262. scipy/optimize/_constraints.py +14 -10
  263. scipy/optimize/_differentiable_functions.py +371 -230
  264. scipy/optimize/_differentialevolution.py +4 -3
  265. scipy/optimize/_direct.cpython-313-darwin.so +0 -0
  266. scipy/optimize/_dual_annealing.py +1 -1
  267. scipy/optimize/_elementwise.py +1 -4
  268. scipy/optimize/_group_columns.cpython-313-darwin.so +0 -0
  269. scipy/optimize/_lbfgsb.cpython-313-darwin.so +0 -0
  270. scipy/optimize/_lbfgsb_py.py +80 -24
  271. scipy/optimize/_linprog_doc.py +2 -2
  272. scipy/optimize/_linprog_highs.py +2 -2
  273. scipy/optimize/_linprog_ip.py +25 -10
  274. scipy/optimize/_linprog_util.py +14 -16
  275. scipy/optimize/_lsap.cpython-313-darwin.so +0 -0
  276. scipy/optimize/_lsq/common.py +3 -3
  277. scipy/optimize/_lsq/dogbox.py +16 -2
  278. scipy/optimize/_lsq/givens_elimination.cpython-313-darwin.so +0 -0
  279. scipy/optimize/_lsq/least_squares.py +198 -126
  280. scipy/optimize/_lsq/lsq_linear.py +6 -6
  281. scipy/optimize/_lsq/trf.py +35 -8
  282. scipy/optimize/_milp.py +3 -1
  283. scipy/optimize/_minimize.py +105 -36
  284. scipy/optimize/_minpack.cpython-313-darwin.so +0 -0
  285. scipy/optimize/_minpack_py.py +21 -14
  286. scipy/optimize/_moduleTNC.cpython-313-darwin.so +0 -0
  287. scipy/optimize/_nnls.py +20 -21
  288. scipy/optimize/_nonlin.py +34 -3
  289. scipy/optimize/_numdiff.py +288 -110
  290. scipy/optimize/_optimize.py +86 -48
  291. scipy/optimize/_pava_pybind.cpython-313-darwin.so +0 -0
  292. scipy/optimize/_remove_redundancy.py +5 -5
  293. scipy/optimize/_root_scalar.py +1 -1
  294. scipy/optimize/_shgo.py +6 -0
  295. scipy/optimize/_shgo_lib/_complex.py +1 -1
  296. scipy/optimize/_slsqp_py.py +216 -124
  297. scipy/optimize/_slsqplib.cpython-313-darwin.so +0 -0
  298. scipy/optimize/_spectral.py +1 -1
  299. scipy/optimize/_tnc.py +8 -1
  300. scipy/optimize/_trlib/_trlib.cpython-313-darwin.so +0 -0
  301. scipy/optimize/_trustregion.py +20 -6
  302. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  303. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  304. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  305. scipy/optimize/_trustregion_constr/projections.py +12 -8
  306. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  307. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  308. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  309. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  310. scipy/optimize/_trustregion_exact.py +0 -1
  311. scipy/optimize/_zeros.cpython-313-darwin.so +0 -0
  312. scipy/optimize/_zeros_py.py +97 -17
  313. scipy/optimize/cython_optimize/_zeros.cpython-313-darwin.so +0 -0
  314. scipy/optimize/slsqp.py +0 -1
  315. scipy/optimize/tests/test__basinhopping.py +1 -1
  316. scipy/optimize/tests/test__differential_evolution.py +4 -4
  317. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  318. scipy/optimize/tests/test__numdiff.py +66 -22
  319. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  320. scipy/optimize/tests/test__shgo.py +9 -1
  321. scipy/optimize/tests/test_bracket.py +36 -46
  322. scipy/optimize/tests/test_chandrupatla.py +133 -135
  323. scipy/optimize/tests/test_cobyla.py +74 -45
  324. scipy/optimize/tests/test_constraints.py +1 -1
  325. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  326. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  327. scipy/optimize/tests/test_least_squares.py +125 -13
  328. scipy/optimize/tests/test_linear_assignment.py +3 -3
  329. scipy/optimize/tests/test_linprog.py +3 -3
  330. scipy/optimize/tests/test_lsq_linear.py +6 -6
  331. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  332. scipy/optimize/tests/test_minpack.py +4 -4
  333. scipy/optimize/tests/test_nnls.py +43 -3
  334. scipy/optimize/tests/test_nonlin.py +36 -0
  335. scipy/optimize/tests/test_optimize.py +98 -20
  336. scipy/optimize/tests/test_slsqp.py +36 -4
  337. scipy/optimize/tests/test_zeros.py +34 -1
  338. scipy/signal/__init__.py +12 -23
  339. scipy/signal/_delegators.py +568 -0
  340. scipy/signal/_filter_design.py +459 -241
  341. scipy/signal/_fir_filter_design.py +262 -90
  342. scipy/signal/_lti_conversion.py +3 -2
  343. scipy/signal/_ltisys.py +118 -91
  344. scipy/signal/_max_len_seq_inner.cpython-313-darwin.so +0 -0
  345. scipy/signal/_peak_finding_utils.cpython-313-darwin.so +0 -0
  346. scipy/signal/_polyutils.py +172 -0
  347. scipy/signal/_short_time_fft.py +519 -70
  348. scipy/signal/_signal_api.py +30 -0
  349. scipy/signal/_signaltools.py +719 -399
  350. scipy/signal/_sigtools.cpython-313-darwin.so +0 -0
  351. scipy/signal/_sosfilt.cpython-313-darwin.so +0 -0
  352. scipy/signal/_spectral_py.py +230 -50
  353. scipy/signal/_spline.cpython-313-darwin.so +0 -0
  354. scipy/signal/_spline_filters.py +108 -68
  355. scipy/signal/_support_alternative_backends.py +73 -0
  356. scipy/signal/_upfirdn.py +4 -1
  357. scipy/signal/_upfirdn_apply.cpython-313-darwin.so +0 -0
  358. scipy/signal/_waveforms.py +2 -11
  359. scipy/signal/_wavelets.py +1 -1
  360. scipy/signal/fir_filter_design.py +1 -0
  361. scipy/signal/spline.py +4 -11
  362. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  363. scipy/signal/tests/test_bsplines.py +114 -79
  364. scipy/signal/tests/test_cont2discrete.py +9 -2
  365. scipy/signal/tests/test_filter_design.py +721 -481
  366. scipy/signal/tests/test_fir_filter_design.py +332 -140
  367. scipy/signal/tests/test_savitzky_golay.py +4 -3
  368. scipy/signal/tests/test_short_time_fft.py +221 -3
  369. scipy/signal/tests/test_signaltools.py +2145 -1349
  370. scipy/signal/tests/test_spectral.py +50 -6
  371. scipy/signal/tests/test_splines.py +161 -96
  372. scipy/signal/tests/test_upfirdn.py +84 -50
  373. scipy/signal/tests/test_waveforms.py +20 -0
  374. scipy/signal/tests/test_windows.py +607 -466
  375. scipy/signal/windows/_windows.py +287 -148
  376. scipy/sparse/__init__.py +23 -4
  377. scipy/sparse/_base.py +270 -108
  378. scipy/sparse/_bsr.py +7 -4
  379. scipy/sparse/_compressed.py +59 -231
  380. scipy/sparse/_construct.py +90 -38
  381. scipy/sparse/_coo.py +115 -181
  382. scipy/sparse/_csc.py +4 -4
  383. scipy/sparse/_csparsetools.cpython-313-darwin.so +0 -0
  384. scipy/sparse/_csr.py +2 -2
  385. scipy/sparse/_data.py +48 -48
  386. scipy/sparse/_dia.py +105 -18
  387. scipy/sparse/_dok.py +0 -23
  388. scipy/sparse/_index.py +4 -4
  389. scipy/sparse/_matrix.py +23 -0
  390. scipy/sparse/_sparsetools.cpython-313-darwin.so +0 -0
  391. scipy/sparse/_sputils.py +37 -22
  392. scipy/sparse/base.py +0 -9
  393. scipy/sparse/bsr.py +0 -14
  394. scipy/sparse/compressed.py +0 -23
  395. scipy/sparse/construct.py +0 -6
  396. scipy/sparse/coo.py +0 -14
  397. scipy/sparse/csc.py +0 -3
  398. scipy/sparse/csgraph/_flow.cpython-313-darwin.so +0 -0
  399. scipy/sparse/csgraph/_matching.cpython-313-darwin.so +0 -0
  400. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-darwin.so +0 -0
  401. scipy/sparse/csgraph/_reordering.cpython-313-darwin.so +0 -0
  402. scipy/sparse/csgraph/_shortest_path.cpython-313-darwin.so +0 -0
  403. scipy/sparse/csgraph/_tools.cpython-313-darwin.so +0 -0
  404. scipy/sparse/csgraph/_traversal.cpython-313-darwin.so +0 -0
  405. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  406. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  407. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  408. scipy/sparse/csr.py +0 -5
  409. scipy/sparse/data.py +1 -6
  410. scipy/sparse/dia.py +0 -7
  411. scipy/sparse/dok.py +0 -10
  412. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-darwin.so +0 -0
  413. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  414. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  415. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-darwin.so +0 -0
  416. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  417. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  418. scipy/sparse/linalg/_interface.py +17 -18
  419. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  420. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  421. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  422. scipy/sparse/linalg/_isolve/minres.py +5 -5
  423. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  424. scipy/sparse/linalg/_isolve/utils.py +2 -8
  425. scipy/sparse/linalg/_matfuncs.py +1 -1
  426. scipy/sparse/linalg/_norm.py +1 -1
  427. scipy/sparse/linalg/_propack/_cpropack.cpython-313-darwin.so +0 -0
  428. scipy/sparse/linalg/_propack/_dpropack.cpython-313-darwin.so +0 -0
  429. scipy/sparse/linalg/_propack/_spropack.cpython-313-darwin.so +0 -0
  430. scipy/sparse/linalg/_propack/_zpropack.cpython-313-darwin.so +0 -0
  431. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  432. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  433. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  434. scipy/sparse/tests/test_base.py +214 -42
  435. scipy/sparse/tests/test_common1d.py +7 -7
  436. scipy/sparse/tests/test_construct.py +1 -1
  437. scipy/sparse/tests/test_coo.py +272 -4
  438. scipy/sparse/tests/test_sparsetools.py +5 -0
  439. scipy/sparse/tests/test_sputils.py +36 -7
  440. scipy/spatial/_ckdtree.cpython-313-darwin.so +0 -0
  441. scipy/spatial/_distance_pybind.cpython-313-darwin.so +0 -0
  442. scipy/spatial/_distance_wrap.cpython-313-darwin.so +0 -0
  443. scipy/spatial/_hausdorff.cpython-313-darwin.so +0 -0
  444. scipy/spatial/_qhull.cpython-313-darwin.so +0 -0
  445. scipy/spatial/_voronoi.cpython-313-darwin.so +0 -0
  446. scipy/spatial/distance.py +49 -42
  447. scipy/spatial/tests/test_distance.py +15 -1
  448. scipy/spatial/tests/test_kdtree.py +1 -0
  449. scipy/spatial/tests/test_qhull.py +7 -2
  450. scipy/spatial/transform/__init__.py +5 -3
  451. scipy/spatial/transform/_rigid_transform.cpython-313-darwin.so +0 -0
  452. scipy/spatial/transform/_rotation.cpython-313-darwin.so +0 -0
  453. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  454. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  455. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  456. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  457. scipy/special/__init__.py +1 -47
  458. scipy/special/_add_newdocs.py +34 -772
  459. scipy/special/_basic.py +22 -25
  460. scipy/special/_comb.cpython-313-darwin.so +0 -0
  461. scipy/special/_ellip_harm_2.cpython-313-darwin.so +0 -0
  462. scipy/special/_gufuncs.cpython-313-darwin.so +0 -0
  463. scipy/special/_logsumexp.py +67 -58
  464. scipy/special/_orthogonal.pyi +1 -1
  465. scipy/special/_specfun.cpython-313-darwin.so +0 -0
  466. scipy/special/_special_ufuncs.cpython-313-darwin.so +0 -0
  467. scipy/special/_spherical_bessel.py +4 -4
  468. scipy/special/_support_alternative_backends.py +212 -119
  469. scipy/special/_test_internal.cpython-313-darwin.so +0 -0
  470. scipy/special/_testutils.py +4 -4
  471. scipy/special/_ufuncs.cpython-313-darwin.so +0 -0
  472. scipy/special/_ufuncs.pyi +1 -0
  473. scipy/special/_ufuncs.pyx +215 -1400
  474. scipy/special/_ufuncs_cxx.cpython-313-darwin.so +0 -0
  475. scipy/special/_ufuncs_cxx.pxd +2 -15
  476. scipy/special/_ufuncs_cxx.pyx +5 -44
  477. scipy/special/_ufuncs_cxx_defs.h +2 -16
  478. scipy/special/_ufuncs_defs.h +0 -8
  479. scipy/special/cython_special.cpython-313-darwin.so +0 -0
  480. scipy/special/cython_special.pxd +1 -1
  481. scipy/special/tests/_cython_examples/meson.build +10 -1
  482. scipy/special/tests/test_basic.py +153 -20
  483. scipy/special/tests/test_boost_ufuncs.py +3 -0
  484. scipy/special/tests/test_cdflib.py +35 -11
  485. scipy/special/tests/test_gammainc.py +16 -0
  486. scipy/special/tests/test_hyp2f1.py +2 -2
  487. scipy/special/tests/test_log1mexp.py +85 -0
  488. scipy/special/tests/test_logsumexp.py +206 -64
  489. scipy/special/tests/test_mpmath.py +1 -0
  490. scipy/special/tests/test_nan_inputs.py +1 -1
  491. scipy/special/tests/test_orthogonal.py +17 -18
  492. scipy/special/tests/test_sf_error.py +3 -2
  493. scipy/special/tests/test_sph_harm.py +6 -7
  494. scipy/special/tests/test_support_alternative_backends.py +211 -76
  495. scipy/stats/__init__.py +4 -1
  496. scipy/stats/_ansari_swilk_statistics.cpython-313-darwin.so +0 -0
  497. scipy/stats/_axis_nan_policy.py +5 -12
  498. scipy/stats/_biasedurn.cpython-313-darwin.so +0 -0
  499. scipy/stats/_continued_fraction.py +387 -0
  500. scipy/stats/_continuous_distns.py +277 -310
  501. scipy/stats/_correlation.py +1 -1
  502. scipy/stats/_covariance.py +6 -3
  503. scipy/stats/_discrete_distns.py +39 -32
  504. scipy/stats/_distn_infrastructure.py +39 -12
  505. scipy/stats/_distribution_infrastructure.py +920 -238
  506. scipy/stats/_entropy.py +9 -10
  507. scipy/{_lib → stats}/_finite_differences.py +1 -1
  508. scipy/stats/_hypotests.py +83 -50
  509. scipy/stats/_kde.py +53 -49
  510. scipy/stats/_ksstats.py +1 -1
  511. scipy/stats/_levy_stable/__init__.py +7 -15
  512. scipy/stats/_levy_stable/levyst.cpython-313-darwin.so +0 -0
  513. scipy/stats/_morestats.py +118 -73
  514. scipy/stats/_mstats_basic.py +13 -17
  515. scipy/stats/_mstats_extras.py +8 -8
  516. scipy/stats/_multivariate.py +89 -113
  517. scipy/stats/_new_distributions.py +97 -20
  518. scipy/stats/_page_trend_test.py +12 -5
  519. scipy/stats/_probability_distribution.py +265 -43
  520. scipy/stats/_qmc.py +14 -9
  521. scipy/stats/_qmc_cy.cpython-313-darwin.so +0 -0
  522. scipy/stats/_qmvnt.py +16 -95
  523. scipy/stats/_qmvnt_cy.cpython-313-darwin.so +0 -0
  524. scipy/stats/_quantile.py +335 -0
  525. scipy/stats/_rcont/rcont.cpython-313-darwin.so +0 -0
  526. scipy/stats/_resampling.py +5 -30
  527. scipy/stats/_sampling.py +1 -1
  528. scipy/stats/_sobol.cpython-313-darwin.so +0 -0
  529. scipy/stats/_stats.cpython-313-darwin.so +0 -0
  530. scipy/stats/_stats_mstats_common.py +21 -2
  531. scipy/stats/_stats_py.py +551 -477
  532. scipy/stats/_stats_pythran.cpython-313-darwin.so +0 -0
  533. scipy/stats/_unuran/unuran_wrapper.cpython-313-darwin.so +0 -0
  534. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  535. scipy/stats/_variation.py +6 -8
  536. scipy/stats/_wilcoxon.py +13 -7
  537. scipy/stats/tests/common_tests.py +6 -4
  538. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  539. scipy/stats/tests/test_continued_fraction.py +173 -0
  540. scipy/stats/tests/test_continuous.py +379 -60
  541. scipy/stats/tests/test_continuous_basic.py +18 -12
  542. scipy/stats/tests/test_discrete_basic.py +14 -8
  543. scipy/stats/tests/test_discrete_distns.py +16 -16
  544. scipy/stats/tests/test_distributions.py +95 -75
  545. scipy/stats/tests/test_entropy.py +40 -48
  546. scipy/stats/tests/test_fit.py +4 -3
  547. scipy/stats/tests/test_hypotests.py +153 -24
  548. scipy/stats/tests/test_kdeoth.py +109 -41
  549. scipy/stats/tests/test_marray.py +289 -0
  550. scipy/stats/tests/test_morestats.py +81 -49
  551. scipy/stats/tests/test_mstats_basic.py +3 -3
  552. scipy/stats/tests/test_multivariate.py +434 -83
  553. scipy/stats/tests/test_qmc.py +13 -10
  554. scipy/stats/tests/test_quantile.py +199 -0
  555. scipy/stats/tests/test_rank.py +119 -112
  556. scipy/stats/tests/test_resampling.py +47 -56
  557. scipy/stats/tests/test_sampling.py +9 -4
  558. scipy/stats/tests/test_stats.py +799 -939
  559. scipy/stats/tests/test_variation.py +8 -6
  560. scipy/version.py +2 -2
  561. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  562. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/METADATA +11 -11
  563. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/RECORD +564 -571
  564. scipy-1.16.0.dist-info/WHEEL +6 -0
  565. scipy/_lib/array_api_extra/_funcs.py +0 -484
  566. scipy/_lib/array_api_extra/_typing.py +0 -8
  567. scipy/interpolate/_bspl.cpython-313-darwin.so +0 -0
  568. scipy/optimize/_cobyla.cpython-313-darwin.so +0 -0
  569. scipy/optimize/_cython_nnls.cpython-313-darwin.so +0 -0
  570. scipy/optimize/_slsqp.cpython-313-darwin.so +0 -0
  571. scipy/spatial/qhull_src/COPYING.txt +0 -38
  572. scipy/special/libsf_error_state.dylib +0 -0
  573. scipy/special/tests/test_log_softmax.py +0 -109
  574. scipy/special/tests/test_xsf_cuda.py +0 -114
  575. scipy/special/xsf/binom.h +0 -89
  576. scipy/special/xsf/cdflib.h +0 -100
  577. scipy/special/xsf/cephes/airy.h +0 -307
  578. scipy/special/xsf/cephes/besselpoly.h +0 -51
  579. scipy/special/xsf/cephes/beta.h +0 -257
  580. scipy/special/xsf/cephes/cbrt.h +0 -131
  581. scipy/special/xsf/cephes/chbevl.h +0 -85
  582. scipy/special/xsf/cephes/chdtr.h +0 -193
  583. scipy/special/xsf/cephes/const.h +0 -87
  584. scipy/special/xsf/cephes/ellie.h +0 -293
  585. scipy/special/xsf/cephes/ellik.h +0 -251
  586. scipy/special/xsf/cephes/ellpe.h +0 -107
  587. scipy/special/xsf/cephes/ellpk.h +0 -117
  588. scipy/special/xsf/cephes/expn.h +0 -260
  589. scipy/special/xsf/cephes/gamma.h +0 -398
  590. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  591. scipy/special/xsf/cephes/hyperg.h +0 -361
  592. scipy/special/xsf/cephes/i0.h +0 -149
  593. scipy/special/xsf/cephes/i1.h +0 -158
  594. scipy/special/xsf/cephes/igam.h +0 -421
  595. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  596. scipy/special/xsf/cephes/igami.h +0 -313
  597. scipy/special/xsf/cephes/j0.h +0 -225
  598. scipy/special/xsf/cephes/j1.h +0 -198
  599. scipy/special/xsf/cephes/jv.h +0 -715
  600. scipy/special/xsf/cephes/k0.h +0 -164
  601. scipy/special/xsf/cephes/k1.h +0 -163
  602. scipy/special/xsf/cephes/kn.h +0 -243
  603. scipy/special/xsf/cephes/lanczos.h +0 -112
  604. scipy/special/xsf/cephes/ndtr.h +0 -275
  605. scipy/special/xsf/cephes/poch.h +0 -85
  606. scipy/special/xsf/cephes/polevl.h +0 -167
  607. scipy/special/xsf/cephes/psi.h +0 -194
  608. scipy/special/xsf/cephes/rgamma.h +0 -111
  609. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  610. scipy/special/xsf/cephes/shichi.h +0 -248
  611. scipy/special/xsf/cephes/sici.h +0 -224
  612. scipy/special/xsf/cephes/sindg.h +0 -221
  613. scipy/special/xsf/cephes/tandg.h +0 -139
  614. scipy/special/xsf/cephes/trig.h +0 -58
  615. scipy/special/xsf/cephes/unity.h +0 -186
  616. scipy/special/xsf/cephes/zeta.h +0 -172
  617. scipy/special/xsf/config.h +0 -304
  618. scipy/special/xsf/digamma.h +0 -205
  619. scipy/special/xsf/error.h +0 -57
  620. scipy/special/xsf/evalpoly.h +0 -47
  621. scipy/special/xsf/expint.h +0 -266
  622. scipy/special/xsf/hyp2f1.h +0 -694
  623. scipy/special/xsf/iv_ratio.h +0 -173
  624. scipy/special/xsf/lambertw.h +0 -150
  625. scipy/special/xsf/loggamma.h +0 -163
  626. scipy/special/xsf/sici.h +0 -200
  627. scipy/special/xsf/tools.h +0 -427
  628. scipy/special/xsf/trig.h +0 -164
  629. scipy/special/xsf/wright_bessel.h +0 -843
  630. scipy/special/xsf/zlog1.h +0 -35
  631. scipy/stats/_mvn.cpython-313-darwin.so +0 -0
  632. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -4,7 +4,7 @@ from itertools import combinations, product
4
4
 
5
5
  import pytest
6
6
  import numpy as np
7
- from numpy.testing import (assert_allclose, assert_equal, assert_array_equal,
7
+ from numpy.testing import (assert_allclose, assert_equal, assert_array_equal,
8
8
  assert_array_less)
9
9
 
10
10
  from scipy.spatial import distance
@@ -144,6 +144,7 @@ class TestUtils:
144
144
  with pytest.raises(ValueError, match=r"'toto' is not a valid ..."):
145
145
  qmc.discrepancy(sample, method="toto")
146
146
 
147
+ @pytest.mark.thread_unsafe
147
148
  def test_discrepancy_parallel(self, monkeypatch):
148
149
  sample = np.array([[2, 1, 1, 2, 2, 2],
149
150
  [1, 2, 2, 2, 2, 2],
@@ -228,6 +229,7 @@ class TestUtils:
228
229
  reason="minimum_spanning_tree ignores zero distances (#18892)",
229
230
  strict=True,
230
231
  )
232
+ @pytest.mark.thread_unsafe
231
233
  def test_geometric_discrepancy_mst_with_zero_distances(self):
232
234
  sample = np.array([[0, 0], [0, 0], [0, 1]])
233
235
  assert_allclose(qmc.geometric_discrepancy(sample, method='mst'), 0.5)
@@ -600,6 +602,7 @@ class QMCEngineTests:
600
602
  None,
601
603
  ),
602
604
  )
605
+ @pytest.mark.thread_unsafe
603
606
  def test_reset(self, scramble, rng):
604
607
  engine = self.engine(d=2, scramble=scramble, rng=rng)
605
608
  ref_sample = engine.random(n=8)
@@ -951,8 +954,8 @@ class TestPoisson(QMCEngineTests):
951
954
  sample = engine.random(30)
952
955
 
953
956
  for point in sample:
954
- assert_array_less(point, u_bounds)
955
- assert_array_less(l_bounds, point)
957
+ assert_array_less(point, u_bounds)
958
+ assert_array_less(l_bounds, point)
956
959
 
957
960
  @pytest.mark.parametrize("u_bounds", [[-1, -2, -1], [1, 2, 1]])
958
961
  def test_sample_inside_upper_bounds(self, u_bounds):
@@ -964,15 +967,15 @@ class TestPoisson(QMCEngineTests):
964
967
  sample = engine.random(30)
965
968
 
966
969
  for point in sample:
967
- assert_array_less(point, u_bounds)
968
- assert_array_less(l_bounds, point)
970
+ assert_array_less(point, u_bounds)
971
+ assert_array_less(l_bounds, point)
969
972
 
970
973
  def test_inconsistent_bound_value(self):
971
974
  radius = 0.2
972
975
  l_bounds=[3, 2, 1]
973
976
  u_bounds=[-1, -2, -1]
974
977
  with pytest.raises(
975
- ValueError,
978
+ ValueError,
976
979
  match="Bounds are not consistent 'l_bounds' < 'u_bounds'"):
977
980
  self.qmce(d=3, radius=radius, l_bounds=l_bounds, u_bounds=u_bounds)
978
981
 
@@ -981,14 +984,14 @@ class TestPoisson(QMCEngineTests):
981
984
  def test_inconsistent_bounds(self, u_bounds, l_bounds):
982
985
  radius = 0.2
983
986
  with pytest.raises(
984
- ValueError,
985
- match="'l_bounds' and 'u_bounds' must be broadcastable and respect"
987
+ ValueError,
988
+ match="'l_bounds' and 'u_bounds' must be broadcastable and respect"
986
989
  " the sample dimension"):
987
990
  self.qmce(
988
- d=3, radius=radius,
991
+ d=3, radius=radius,
989
992
  l_bounds=l_bounds, u_bounds=u_bounds
990
993
  )
991
-
994
+
992
995
  def test_raises(self):
993
996
  message = r"'toto' is not a valid hypersphere sampling"
994
997
  with pytest.raises(ValueError, match=message):
@@ -0,0 +1,199 @@
1
+ import pytest
2
+ import numpy as np
3
+
4
+ from scipy import stats
5
+ from scipy._lib._array_api import xp_default_dtype, is_numpy, is_torch, SCIPY_ARRAY_API
6
+ from scipy._lib._array_api_no_0d import xp_assert_close, xp_assert_equal
7
+ from scipy._lib._util import _apply_over_batch
8
+
9
+ skip_xp_backends = pytest.mark.skip_xp_backends
10
+
11
+
12
+ @_apply_over_batch(('x', 1), ('p', 1))
13
+ def quantile_reference_last_axis(x, p, nan_policy, method):
14
+ if nan_policy == 'omit':
15
+ x = x[~np.isnan(x)]
16
+ p_mask = np.isnan(p)
17
+ p = p.copy()
18
+ p[p_mask] = 0.5
19
+ if method == 'harrell-davis':
20
+ # hdquantiles returns masked element if length along axis is 1 (bug)
21
+ res = (np.full_like(p, x[0]) if x.size == 1
22
+ else stats.mstats.hdquantiles(x, p).data)
23
+ if nan_policy == 'propagate' and np.any(np.isnan(x)):
24
+ res[:] = np.nan
25
+ else:
26
+ res = np.quantile(x, p)
27
+ res[p_mask] = np.nan
28
+ return res
29
+
30
+
31
+ def quantile_reference(x, p, *, axis, nan_policy, keepdims, method):
32
+ x, p = np.moveaxis(x, axis, -1), np.moveaxis(p, axis, -1)
33
+ res = quantile_reference_last_axis(x, p, nan_policy, method)
34
+ res = np.moveaxis(res, -1, axis)
35
+ if not keepdims:
36
+ res = np.squeeze(res, axis=axis)
37
+ return res
38
+
39
+
40
+ @skip_xp_backends('dask.array', reason="No take_along_axis yet.")
41
+ @skip_xp_backends('jax.numpy', reason="No mutation.")
42
+ class TestQuantile:
43
+
44
+ def test_input_validation(self, xp):
45
+ x = xp.asarray([1, 2, 3])
46
+ p = xp.asarray(0.5)
47
+
48
+ message = "`x` must have real dtype."
49
+ with pytest.raises(ValueError, match=message):
50
+ stats.quantile(xp.asarray([True, False]), p)
51
+ with pytest.raises(ValueError):
52
+ stats.quantile(xp.asarray([1+1j, 2]), p)
53
+
54
+ message = "`p` must have real floating dtype."
55
+ with pytest.raises(ValueError, match=message):
56
+ stats.quantile(x, xp.asarray([0, 1]))
57
+
58
+ message = "`axis` must be an integer or None."
59
+ with pytest.raises(ValueError, match=message):
60
+ stats.quantile(x, p, axis=0.5)
61
+ with pytest.raises(ValueError, match=message):
62
+ stats.quantile(x, p, axis=(0, -1))
63
+
64
+ message = "`axis` is not compatible with the shapes of the inputs."
65
+ with pytest.raises(ValueError, match=message):
66
+ stats.quantile(x, p, axis=2)
67
+
68
+ message = "The input contains nan values"
69
+ with pytest.raises(ValueError, match=message):
70
+ stats.quantile(xp.asarray([xp.nan, 1, 2]), p, nan_policy='raise')
71
+
72
+ message = "method` must be one of..."
73
+ with pytest.raises(ValueError, match=message):
74
+ stats.quantile(x, p, method='a duck')
75
+
76
+ message = "If specified, `keepdims` must be True or False."
77
+ with pytest.raises(ValueError, match=message):
78
+ stats.quantile(x, p, keepdims=42)
79
+
80
+ message = "`keepdims` may be False only if the length of `p` along `axis` is 1."
81
+ with pytest.raises(ValueError, match=message):
82
+ stats.quantile(x, xp.asarray([0.5, 0.6]), keepdims=False)
83
+
84
+ @pytest.mark.parametrize('method',
85
+ ['inverted_cdf', 'averaged_inverted_cdf', 'closest_observation',
86
+ 'hazen', 'interpolated_inverted_cdf', 'linear',
87
+ 'median_unbiased', 'normal_unbiased', 'weibull'])
88
+ @pytest.mark.parametrize('shape_x, shape_p, axis',
89
+ [(10, None, -1), (10, 10, -1), (10, (2, 3), -1),
90
+ ((10, 2), None, 0), ((10, 2), None, 0),])
91
+ def test_against_numpy(self, method, shape_x, shape_p, axis, xp):
92
+ dtype = xp_default_dtype(xp)
93
+ rng = np.random.default_rng(23458924568734956)
94
+ x = rng.random(size=shape_x)
95
+ p = rng.random(size=shape_p)
96
+ ref = np.quantile(x, p, method=method, axis=axis)
97
+
98
+ x, p = xp.asarray(x, dtype=dtype), xp.asarray(p, dtype=dtype)
99
+ res = stats.quantile(x, p, method=method, axis=axis)
100
+
101
+ xp_assert_close(res, xp.asarray(ref, dtype=dtype))
102
+
103
+ @skip_xp_backends(cpu_only=True, reason="PyTorch doesn't have `betainc`.")
104
+ @pytest.mark.parametrize('axis', [0, 1])
105
+ @pytest.mark.parametrize('keepdims', [False, True])
106
+ @pytest.mark.parametrize('nan_policy', ['omit', 'propagate', 'marray'])
107
+ @pytest.mark.parametrize('dtype', ['float32', 'float64'])
108
+ @pytest.mark.parametrize('method', ['linear', 'harrell-davis'])
109
+ def test_against_reference(self, axis, keepdims, nan_policy, dtype, method, xp):
110
+ rng = np.random.default_rng(23458924568734956)
111
+ shape = (5, 6)
112
+ x = rng.random(size=shape).astype(dtype)
113
+ p = rng.random(size=shape).astype(dtype)
114
+ mask = rng.random(size=shape) > 0.8
115
+ assert np.any(mask)
116
+ x[mask] = np.nan
117
+ if not keepdims:
118
+ p = np.mean(p, axis=axis, keepdims=True)
119
+
120
+ # inject p = 0 and p = 1 to test edge cases
121
+ # Currently would fail with CuPy/JAX (cupy/cupy#8934, jax-ml/jax#21900);
122
+ # remove the `if` when those are resolved.
123
+ if is_numpy(xp):
124
+ p0 = p.ravel()
125
+ p0[1] = 0.
126
+ p0[-2] = 1.
127
+
128
+ dtype = getattr(xp, dtype)
129
+
130
+ if nan_policy == 'marray':
131
+ if method == 'harrell-davis':
132
+ pytest.skip("Needs gh-22490")
133
+ if is_torch(xp):
134
+ pytest.skip("sum_cpu not implemented for UInt64, see "
135
+ "data-apis/array-api-compat#242")
136
+ if not SCIPY_ARRAY_API:
137
+ pytest.skip("MArray is only available if SCIPY_ARRAY_API=1")
138
+ marray = pytest.importorskip('marray')
139
+ kwargs = dict(axis=axis, keepdims=keepdims, method=method)
140
+ mxp = marray._get_namespace(xp)
141
+ x_mp = mxp.asarray(x, mask=mask)
142
+ res = stats.quantile(x_mp, mxp.asarray(p), **kwargs)
143
+ ref = quantile_reference(x, p, nan_policy='omit', **kwargs)
144
+ xp_assert_close(res.data, xp.asarray(ref, dtype=dtype))
145
+ return
146
+
147
+ kwargs = dict(axis=axis, keepdims=keepdims,
148
+ nan_policy=nan_policy, method=method)
149
+ res = stats.quantile(xp.asarray(x), xp.asarray(p), **kwargs)
150
+ ref = quantile_reference(x, p, **kwargs)
151
+ xp_assert_close(res, xp.asarray(ref, dtype=dtype))
152
+
153
+ def test_integer_input_output_dtype(self, xp):
154
+ res = stats.quantile(xp.arange(10, dtype=xp.int64), 0.5)
155
+ assert res.dtype == xp_default_dtype(xp)
156
+
157
+ @pytest.mark.parametrize('x, p, ref, kwargs',
158
+ [([], 0.5, np.nan, {}),
159
+ ([1, 2, 3], [-1, 0, 1, 1.5, np.nan], [np.nan, 1, 3, np.nan, np.nan], {}),
160
+ ([1, 2, 3], [], [], {}),
161
+ ([[np.nan, 2]], 0.5, [np.nan, 2], {'nan_policy': 'omit'}),
162
+ ([[], []], 0.5, np.full(2, np.nan), {'axis': -1}),
163
+ ([[], []], 0.5, np.zeros((0,)), {'axis': 0, 'keepdims': False}),
164
+ ([[], []], 0.5, np.zeros((1, 0)), {'axis': 0, 'keepdims': True}),
165
+ ([], [0.5, 0.6], np.full(2, np.nan), {}),
166
+ (np.arange(1, 28).reshape((3, 3, 3)), 0.5, [[[14.]]],
167
+ {'axis': None, 'keepdims': True}),
168
+ ([[1, 2], [3, 4]], [0.25, 0.5, 0.75], [[1.75, 2.5, 3.25]],
169
+ {'axis': None, 'keepdims': True}),])
170
+ def test_edge_cases(self, x, p, ref, kwargs, xp):
171
+ default_dtype = xp_default_dtype(xp)
172
+ x, p, ref = xp.asarray(x), xp.asarray(p), xp.asarray(ref, dtype=default_dtype)
173
+ res = stats.quantile(x, p, **kwargs)
174
+ xp_assert_equal(res, ref)
175
+
176
+ @pytest.mark.parametrize('axis', [0, 1, 2])
177
+ @pytest.mark.parametrize('keepdims', [False, True])
178
+ def test_size_0(self, axis, keepdims, xp):
179
+ shape = [3, 4, 0]
180
+ out_shape = shape.copy()
181
+ if keepdims:
182
+ out_shape[axis] = 1
183
+ else:
184
+ out_shape.pop(axis)
185
+ res = stats.quantile(xp.zeros(tuple(shape)), 0.5, axis=axis, keepdims=keepdims)
186
+ assert res.shape == tuple(out_shape)
187
+
188
+ @pytest.mark.parametrize('method',
189
+ ['inverted_cdf', 'averaged_inverted_cdf', 'closest_observation'])
190
+ def test_transition(self, method, xp):
191
+ # test that values of discontinuous estimators are correct when
192
+ # p*n + m - 1 is integral.
193
+ if method == 'closest_observation' and np.__version__ < '2.0.1':
194
+ pytest.skip('Bug in np.quantile (numpy/numpy#26656) fixed in 2.0.1')
195
+ x = np.arange(8., dtype=np.float64)
196
+ p = np.arange(0, 1.0625, 0.0625)
197
+ res = stats.quantile(xp.asarray(x), xp.asarray(p), method=method)
198
+ ref = np.quantile(x, p, method=method)
199
+ xp_assert_equal(res, xp.asarray(ref, dtype=xp.float64))
@@ -2,10 +2,10 @@ import numpy as np
2
2
  from numpy.testing import assert_equal, assert_array_equal
3
3
  import pytest
4
4
 
5
+ from scipy import stats
5
6
  from scipy.conftest import skip_xp_invalid_arg
6
7
  from scipy.stats import rankdata, tiecorrect
7
- from scipy._lib._util import np_long
8
-
8
+ from scipy._lib._array_api import xp_assert_equal, make_xp_test_case
9
9
 
10
10
  class TestTieCorrect:
11
11
 
@@ -73,63 +73,69 @@ class TestTieCorrect:
73
73
  assert_equal(out, 1.0 - k * (ntie**3 - ntie) / float(n**3 - n))
74
74
 
75
75
 
76
+ @make_xp_test_case(stats.rankdata)
76
77
  class TestRankData:
77
78
 
78
- def test_empty(self):
79
- """stats.rankdata([]) should return an empty array."""
80
- a = np.array([], dtype=int)
79
+ def desired_dtype(self, method='average', has_nans=False, *, xp):
80
+ if has_nans:
81
+ return xp.asarray(1.).dtype
82
+ return xp.asarray(1.).dtype if method=='average' else xp.asarray(1).dtype
83
+
84
+ def test_empty(self, xp):
85
+ """stats.rankdata of empty array should return an empty array."""
86
+ a = xp.asarray([], dtype=xp.int64)
81
87
  r = rankdata(a)
82
- assert_array_equal(r, np.array([], dtype=np.float64))
88
+ xp_assert_equal(r, xp.asarray([], dtype=self.desired_dtype(xp=xp)))
89
+
90
+ def test_list(self):
91
+ # test that NumPy still accepts lists
83
92
  r = rankdata([])
84
- assert_array_equal(r, np.array([], dtype=np.float64))
93
+ assert_array_equal(r, np.array([]))
94
+
95
+ r = rankdata([40, 10, 30, 10, 50])
96
+ assert_equal(r, [4.0, 1.5, 3.0, 1.5, 5.0])
85
97
 
86
98
  @pytest.mark.parametrize("shape", [(0, 1, 2)])
87
99
  @pytest.mark.parametrize("axis", [None, *range(3)])
88
- def test_empty_multidim(self, shape, axis):
89
- a = np.empty(shape, dtype=int)
100
+ def test_empty_multidim(self, shape, axis, xp):
101
+ a = xp.empty(shape, dtype=xp.int64)
90
102
  r = rankdata(a, axis=axis)
91
103
  expected_shape = (0,) if axis is None else shape
92
- assert_equal(r.shape, expected_shape)
93
- assert_equal(r.dtype, np.float64)
104
+ xp_assert_equal(r, xp.empty(expected_shape, dtype=self.desired_dtype(xp=xp)))
94
105
 
95
- def test_one(self):
106
+ def test_one(self, xp):
96
107
  """Check stats.rankdata with an array of length 1."""
97
108
  data = [100]
98
- a = np.array(data, dtype=int)
109
+ a = xp.asarray(data, dtype=xp.int64)
99
110
  r = rankdata(a)
100
- assert_array_equal(r, np.array([1.0], dtype=np.float64))
101
- r = rankdata(data)
102
- assert_array_equal(r, np.array([1.0], dtype=np.float64))
111
+ xp_assert_equal(r, xp.asarray([1.0], dtype=self.desired_dtype(xp=xp)))
103
112
 
104
- def test_basic(self):
113
+ def test_basic(self, xp):
105
114
  """Basic tests of stats.rankdata."""
115
+ desired_dtype = self.desired_dtype(xp=xp)
116
+
106
117
  data = [100, 10, 50]
107
- expected = np.array([3.0, 1.0, 2.0], dtype=np.float64)
108
- a = np.array(data, dtype=int)
118
+ expected = xp.asarray([3.0, 1.0, 2.0], dtype=desired_dtype)
119
+ a = xp.asarray(data, dtype=xp.int64)
109
120
  r = rankdata(a)
110
- assert_array_equal(r, expected)
111
- r = rankdata(data)
112
- assert_array_equal(r, expected)
121
+ xp_assert_equal(r, expected)
113
122
 
114
123
  data = [40, 10, 30, 10, 50]
115
- expected = np.array([4.0, 1.5, 3.0, 1.5, 5.0], dtype=np.float64)
116
- a = np.array(data, dtype=int)
124
+ expected = xp.asarray([4.0, 1.5, 3.0, 1.5, 5.0], dtype=desired_dtype)
125
+ a = xp.asarray(data, dtype=xp.int64)
117
126
  r = rankdata(a)
118
- assert_array_equal(r, expected)
119
- r = rankdata(data)
120
- assert_array_equal(r, expected)
127
+ xp_assert_equal(r, expected)
121
128
 
122
129
  data = [20, 20, 20, 10, 10, 10]
123
- expected = np.array([5.0, 5.0, 5.0, 2.0, 2.0, 2.0], dtype=np.float64)
124
- a = np.array(data, dtype=int)
130
+ expected = xp.asarray([5.0, 5.0, 5.0, 2.0, 2.0, 2.0], dtype=desired_dtype)
131
+ a = xp.asarray(data, dtype=xp.int64)
125
132
  r = rankdata(a)
126
- assert_array_equal(r, expected)
127
- r = rankdata(data)
128
- assert_array_equal(r, expected)
129
- # The docstring states explicitly that the argument is flattened.
130
- a2d = a.reshape(2, 3)
133
+ xp_assert_equal(r, expected)
134
+
135
+ # # The docstring states explicitly that the argument is flattened.
136
+ a2d = xp.reshape(a, (2, 3))
131
137
  r = rankdata(a2d)
132
- assert_array_equal(r, expected)
138
+ xp_assert_equal(r, expected)
133
139
 
134
140
  @skip_xp_invalid_arg
135
141
  def test_rankdata_object_string(self):
@@ -165,50 +171,51 @@ class TestRankData:
165
171
  val = np.array([0, 1, 2, 2.718, 3, 3.141], dtype='object')
166
172
  check_ranks(np.random.choice(val, 200).astype('object'))
167
173
 
168
- def test_large_int(self):
169
- data = np.array([2**60, 2**60+1], dtype=np.uint64)
174
+ def test_large_int(self, xp):
175
+ if hasattr(xp, 'uint64'):
176
+ data = xp.asarray([2**60, 2**60+1], dtype=xp.uint64)
177
+ r = rankdata(data)
178
+ xp_assert_equal(r, xp.asarray([1.0, 2.0], dtype=self.desired_dtype(xp=xp)))
179
+
180
+ data = xp.asarray([2**60, 2**60+1], dtype=xp.int64)
170
181
  r = rankdata(data)
171
- assert_array_equal(r, [1.0, 2.0])
182
+ xp_assert_equal(r, xp.asarray([1.0, 2.0], dtype=self.desired_dtype(xp=xp)))
172
183
 
173
- data = np.array([2**60, 2**60+1], dtype=np.int64)
184
+ data = xp.asarray([2**60, -2**60+1], dtype=xp.int64)
174
185
  r = rankdata(data)
175
- assert_array_equal(r, [1.0, 2.0])
186
+ xp_assert_equal(r, xp.asarray([2.0, 1.0], dtype=self.desired_dtype(xp=xp)))
176
187
 
177
- data = np.array([2**60, -2**60+1], dtype=np.int64)
188
+ @pytest.mark.parametrize('n', [10000, 100000, 1000000])
189
+ def test_big_tie(self, n, xp):
190
+ data = xp.ones(n)
178
191
  r = rankdata(data)
179
- assert_array_equal(r, [2.0, 1.0])
192
+ expected_rank = 0.5 * (n + 1)
193
+ ref = xp.asarray(expected_rank * data, dtype=self.desired_dtype(xp=xp))
194
+ xp_assert_equal(r, ref)
180
195
 
181
- def test_big_tie(self):
182
- for n in [10000, 100000, 1000000]:
183
- data = np.ones(n, dtype=int)
184
- r = rankdata(data)
185
- expected_rank = 0.5 * (n + 1)
186
- assert_array_equal(r, expected_rank * data,
187
- "test failed with n=%d" % n)
188
-
189
- def test_axis(self):
190
- data = [[0, 2, 1],
191
- [4, 2, 2]]
192
- expected0 = [[1., 1.5, 1.],
193
- [2., 1.5, 2.]]
196
+ def test_axis(self, xp):
197
+ data = xp.asarray([[0, 2, 1], [4, 2, 2]])
198
+
199
+ expected0 = xp.asarray([[1., 1.5, 1.], [2., 1.5, 2.]])
194
200
  r0 = rankdata(data, axis=0)
195
- assert_array_equal(r0, expected0)
196
- expected1 = [[1., 3., 2.],
197
- [3., 1.5, 1.5]]
201
+ xp_assert_equal(r0, expected0)
202
+
203
+ expected1 = xp.asarray([[1., 3., 2.], [3., 1.5, 1.5]])
198
204
  r1 = rankdata(data, axis=1)
199
- assert_array_equal(r1, expected1)
205
+ xp_assert_equal(r1, expected1)
200
206
 
201
- methods = ["average", "min", "max", "dense", "ordinal"]
202
- dtypes = [np.float64] + [np_long]*4
207
+ methods= ["average", "min", "max", "dense", "ordinal"]
203
208
 
204
209
  @pytest.mark.parametrize("axis", [0, 1])
205
- @pytest.mark.parametrize("method, dtype", zip(methods, dtypes))
206
- def test_size_0_axis(self, axis, method, dtype):
210
+ @pytest.mark.parametrize("method", methods)
211
+ def test_size_0_axis(self, axis, method, xp):
207
212
  shape = (3, 0)
208
- data = np.zeros(shape)
213
+ desired_dtype = self.desired_dtype(method, xp=xp)
214
+ data = xp.zeros(shape)
209
215
  r = rankdata(data, method=method, axis=axis)
210
216
  assert_equal(r.shape, shape)
211
- assert_equal(r.dtype, dtype)
217
+ assert_equal(r.dtype, desired_dtype)
218
+ xp_assert_equal(r, xp.empty(shape, dtype=desired_dtype))
212
219
 
213
220
  @pytest.mark.parametrize('axis', range(3))
214
221
  @pytest.mark.parametrize('method', methods)
@@ -289,50 +296,50 @@ class TestRankData:
289
296
  [np.nan, np.nan, np.nan],
290
297
  [1, 2.5, 2.5]])
291
298
 
292
-
293
- _cases = (
294
- # values, method, expected
295
- ([], 'average', []),
296
- ([], 'min', []),
297
- ([], 'max', []),
298
- ([], 'dense', []),
299
- ([], 'ordinal', []),
300
- #
301
- ([100], 'average', [1.0]),
302
- ([100], 'min', [1.0]),
303
- ([100], 'max', [1.0]),
304
- ([100], 'dense', [1.0]),
305
- ([100], 'ordinal', [1.0]),
306
- #
307
- ([100, 100, 100], 'average', [2.0, 2.0, 2.0]),
308
- ([100, 100, 100], 'min', [1.0, 1.0, 1.0]),
309
- ([100, 100, 100], 'max', [3.0, 3.0, 3.0]),
310
- ([100, 100, 100], 'dense', [1.0, 1.0, 1.0]),
311
- ([100, 100, 100], 'ordinal', [1.0, 2.0, 3.0]),
312
- #
313
- ([100, 300, 200], 'average', [1.0, 3.0, 2.0]),
314
- ([100, 300, 200], 'min', [1.0, 3.0, 2.0]),
315
- ([100, 300, 200], 'max', [1.0, 3.0, 2.0]),
316
- ([100, 300, 200], 'dense', [1.0, 3.0, 2.0]),
317
- ([100, 300, 200], 'ordinal', [1.0, 3.0, 2.0]),
318
- #
319
- ([100, 200, 300, 200], 'average', [1.0, 2.5, 4.0, 2.5]),
320
- ([100, 200, 300, 200], 'min', [1.0, 2.0, 4.0, 2.0]),
321
- ([100, 200, 300, 200], 'max', [1.0, 3.0, 4.0, 3.0]),
322
- ([100, 200, 300, 200], 'dense', [1.0, 2.0, 3.0, 2.0]),
323
- ([100, 200, 300, 200], 'ordinal', [1.0, 2.0, 4.0, 3.0]),
324
- #
325
- ([100, 200, 300, 200, 100], 'average', [1.5, 3.5, 5.0, 3.5, 1.5]),
326
- ([100, 200, 300, 200, 100], 'min', [1.0, 3.0, 5.0, 3.0, 1.0]),
327
- ([100, 200, 300, 200, 100], 'max', [2.0, 4.0, 5.0, 4.0, 2.0]),
328
- ([100, 200, 300, 200, 100], 'dense', [1.0, 2.0, 3.0, 2.0, 1.0]),
329
- ([100, 200, 300, 200, 100], 'ordinal', [1.0, 3.0, 5.0, 4.0, 2.0]),
330
- #
331
- ([10] * 30, 'ordinal', np.arange(1.0, 31.0)),
332
- )
333
-
334
-
335
- def test_cases():
336
- for values, method, expected in _cases:
337
- r = rankdata(values, method=method)
338
- assert_array_equal(r, expected)
299
+ _rankdata_cases = (
300
+ # values, method, expected
301
+ ([], 'average', []),
302
+ ([], 'min', []),
303
+ ([], 'max', []),
304
+ ([], 'dense', []),
305
+ ([], 'ordinal', []),
306
+ #
307
+ ([100], 'average', [1.0]),
308
+ ([100], 'min', [1.0]),
309
+ ([100], 'max', [1.0]),
310
+ ([100], 'dense', [1.0]),
311
+ ([100], 'ordinal', [1.0]),
312
+ #
313
+ ([100, 100, 100], 'average', [2.0, 2.0, 2.0]),
314
+ ([100, 100, 100], 'min', [1.0, 1.0, 1.0]),
315
+ ([100, 100, 100], 'max', [3.0, 3.0, 3.0]),
316
+ ([100, 100, 100], 'dense', [1.0, 1.0, 1.0]),
317
+ ([100, 100, 100], 'ordinal', [1.0, 2.0, 3.0]),
318
+ #
319
+ ([100, 300, 200], 'average', [1.0, 3.0, 2.0]),
320
+ ([100, 300, 200], 'min', [1.0, 3.0, 2.0]),
321
+ ([100, 300, 200], 'max', [1.0, 3.0, 2.0]),
322
+ ([100, 300, 200], 'dense', [1.0, 3.0, 2.0]),
323
+ ([100, 300, 200], 'ordinal', [1.0, 3.0, 2.0]),
324
+ #
325
+ ([100, 200, 300, 200], 'average', [1.0, 2.5, 4.0, 2.5]),
326
+ ([100, 200, 300, 200], 'min', [1.0, 2.0, 4.0, 2.0]),
327
+ ([100, 200, 300, 200], 'max', [1.0, 3.0, 4.0, 3.0]),
328
+ ([100, 200, 300, 200], 'dense', [1.0, 2.0, 3.0, 2.0]),
329
+ ([100, 200, 300, 200], 'ordinal', [1.0, 2.0, 4.0, 3.0]),
330
+ #
331
+ ([100, 200, 300, 200, 100], 'average', [1.5, 3.5, 5.0, 3.5, 1.5]),
332
+ ([100, 200, 300, 200, 100], 'min', [1.0, 3.0, 5.0, 3.0, 1.0]),
333
+ ([100, 200, 300, 200, 100], 'max', [2.0, 4.0, 5.0, 4.0, 2.0]),
334
+ ([100, 200, 300, 200, 100], 'dense', [1.0, 2.0, 3.0, 2.0, 1.0]),
335
+ ([100, 200, 300, 200, 100], 'ordinal', [1.0, 3.0, 5.0, 4.0, 2.0]),
336
+ #
337
+ ([10] * 30, 'ordinal', np.arange(1.0, 31.0)),
338
+ )
339
+
340
+ @pytest.mark.parametrize('case', _rankdata_cases)
341
+ def test_cases(self, case, xp):
342
+ values, method, expected = case
343
+ r = rankdata(xp.asarray(values), method=method)
344
+ ref = xp.asarray(expected, dtype=self.desired_dtype(method, xp=xp))
345
+ xp_assert_equal(r, ref)