scipy 1.15.2__cp313-cp313t-macosx_14_0_arm64.whl → 1.16.0__cp313-cp313t-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (642) hide show
  1. scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. scipy/.dylibs/libgfortran.5.dylib +0 -0
  3. scipy/.dylibs/libquadmath.0.dylib +0 -0
  4. scipy/__config__.py +5 -5
  5. scipy/__init__.py +3 -6
  6. scipy/_cyutility.cpython-313t-darwin.so +0 -0
  7. scipy/_lib/_array_api.py +497 -161
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_bunch.py +4 -0
  10. scipy/_lib/_ccallback_c.cpython-313t-darwin.so +0 -0
  11. scipy/_lib/_docscrape.py +1 -1
  12. scipy/_lib/_elementwise_iterative_method.py +15 -26
  13. scipy/_lib/_sparse.py +41 -0
  14. scipy/_lib/_test_ccallback.cpython-313t-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_call.cpython-313t-darwin.so +0 -0
  16. scipy/_lib/_test_deprecation_def.cpython-313t-darwin.so +0 -0
  17. scipy/_lib/_testutils.py +6 -2
  18. scipy/_lib/_util.py +222 -125
  19. scipy/_lib/array_api_compat/__init__.py +4 -4
  20. scipy/_lib/array_api_compat/_internal.py +19 -6
  21. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  22. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  23. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  24. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  25. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  26. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  27. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  28. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  29. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  30. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  31. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  32. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  33. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  34. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  35. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  36. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  37. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  38. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  39. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  40. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  41. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  42. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  43. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  44. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  45. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  46. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  47. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  48. scipy/_lib/array_api_extra/__init__.py +26 -3
  49. scipy/_lib/array_api_extra/_delegation.py +171 -0
  50. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  51. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  52. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  53. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  54. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  55. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  61. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  62. scipy/_lib/array_api_extra/testing.py +359 -0
  63. scipy/_lib/decorator.py +2 -2
  64. scipy/_lib/doccer.py +1 -7
  65. scipy/_lib/messagestream.cpython-313t-darwin.so +0 -0
  66. scipy/_lib/pyprima/__init__.py +212 -0
  67. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  68. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  69. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  70. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  71. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  72. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  73. scipy/_lib/pyprima/cobyla/update.py +289 -0
  74. scipy/_lib/pyprima/common/__init__.py +0 -0
  75. scipy/_lib/pyprima/common/_bounds.py +34 -0
  76. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  77. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  78. scipy/_lib/pyprima/common/_project.py +173 -0
  79. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  80. scipy/_lib/pyprima/common/consts.py +47 -0
  81. scipy/_lib/pyprima/common/evaluate.py +99 -0
  82. scipy/_lib/pyprima/common/history.py +38 -0
  83. scipy/_lib/pyprima/common/infos.py +30 -0
  84. scipy/_lib/pyprima/common/linalg.py +435 -0
  85. scipy/_lib/pyprima/common/message.py +290 -0
  86. scipy/_lib/pyprima/common/powalg.py +131 -0
  87. scipy/_lib/pyprima/common/preproc.py +277 -0
  88. scipy/_lib/pyprima/common/present.py +5 -0
  89. scipy/_lib/pyprima/common/ratio.py +54 -0
  90. scipy/_lib/pyprima/common/redrho.py +47 -0
  91. scipy/_lib/pyprima/common/selectx.py +296 -0
  92. scipy/_lib/tests/test__util.py +105 -121
  93. scipy/_lib/tests/test_array_api.py +169 -34
  94. scipy/_lib/tests/test_bunch.py +7 -0
  95. scipy/_lib/tests/test_ccallback.py +2 -10
  96. scipy/_lib/tests/test_public_api.py +13 -0
  97. scipy/cluster/_hierarchy.cpython-313t-darwin.so +0 -0
  98. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  99. scipy/cluster/_vq.cpython-313t-darwin.so +0 -0
  100. scipy/cluster/hierarchy.py +393 -223
  101. scipy/cluster/tests/test_hierarchy.py +273 -335
  102. scipy/cluster/tests/test_vq.py +45 -61
  103. scipy/cluster/vq.py +39 -35
  104. scipy/conftest.py +282 -151
  105. scipy/constants/_constants.py +4 -1
  106. scipy/constants/tests/test_codata.py +2 -2
  107. scipy/constants/tests/test_constants.py +11 -18
  108. scipy/datasets/_download_all.py +15 -1
  109. scipy/datasets/_fetchers.py +7 -1
  110. scipy/datasets/_utils.py +1 -1
  111. scipy/differentiate/_differentiate.py +25 -25
  112. scipy/differentiate/tests/test_differentiate.py +24 -25
  113. scipy/fft/_basic.py +20 -0
  114. scipy/fft/_helper.py +3 -34
  115. scipy/fft/_pocketfft/helper.py +29 -1
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-313t-darwin.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-313t-darwin.so +0 -0
  129. scipy/integrate/_ivp/common.py +3 -3
  130. scipy/integrate/_ivp/ivp.py +9 -2
  131. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  132. scipy/integrate/_lsoda.cpython-313t-darwin.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-313t-darwin.so +0 -0
  137. scipy/integrate/_quadpack_py.py +11 -7
  138. scipy/integrate/_quadrature.py +3 -3
  139. scipy/integrate/_rules/_base.py +2 -2
  140. scipy/integrate/_tanhsinh.py +57 -54
  141. scipy/integrate/_test_odeint_banded.cpython-313t-darwin.so +0 -0
  142. scipy/integrate/_vode.cpython-313t-darwin.so +0 -0
  143. scipy/integrate/tests/test__quad_vec.py +0 -6
  144. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  145. scipy/integrate/tests/test_cubature.py +21 -35
  146. scipy/integrate/tests/test_quadrature.py +6 -8
  147. scipy/integrate/tests/test_tanhsinh.py +61 -43
  148. scipy/interpolate/__init__.py +70 -58
  149. scipy/interpolate/_bary_rational.py +22 -22
  150. scipy/interpolate/_bsplines.py +119 -66
  151. scipy/interpolate/_cubic.py +65 -50
  152. scipy/interpolate/_dfitpack.cpython-313t-darwin.so +0 -0
  153. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  154. scipy/interpolate/_fitpack.cpython-313t-darwin.so +0 -0
  155. scipy/interpolate/_fitpack2.py +9 -6
  156. scipy/interpolate/_fitpack_impl.py +32 -26
  157. scipy/interpolate/_fitpack_repro.py +23 -19
  158. scipy/interpolate/_interpnd.cpython-313t-darwin.so +0 -0
  159. scipy/interpolate/_interpolate.py +30 -12
  160. scipy/interpolate/_ndbspline.py +13 -18
  161. scipy/interpolate/_ndgriddata.py +5 -8
  162. scipy/interpolate/_polyint.py +95 -31
  163. scipy/interpolate/_ppoly.cpython-313t-darwin.so +0 -0
  164. scipy/interpolate/_rbf.py +2 -2
  165. scipy/interpolate/_rbfinterp.py +1 -1
  166. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  167. scipy/interpolate/_rgi.py +31 -26
  168. scipy/interpolate/_rgi_cython.cpython-313t-darwin.so +0 -0
  169. scipy/interpolate/dfitpack.py +0 -20
  170. scipy/interpolate/interpnd.py +1 -2
  171. scipy/interpolate/tests/test_bary_rational.py +2 -2
  172. scipy/interpolate/tests/test_bsplines.py +97 -1
  173. scipy/interpolate/tests/test_fitpack2.py +39 -1
  174. scipy/interpolate/tests/test_interpnd.py +32 -20
  175. scipy/interpolate/tests/test_interpolate.py +48 -4
  176. scipy/interpolate/tests/test_rgi.py +2 -1
  177. scipy/io/_fast_matrix_market/__init__.py +2 -0
  178. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  179. scipy/io/_harwell_boeing/hb.py +7 -11
  180. scipy/io/_idl.py +5 -7
  181. scipy/io/_netcdf.py +15 -5
  182. scipy/io/_test_fortran.cpython-313t-darwin.so +0 -0
  183. scipy/io/arff/tests/test_arffread.py +3 -3
  184. scipy/io/matlab/__init__.py +5 -3
  185. scipy/io/matlab/_mio.py +4 -1
  186. scipy/io/matlab/_mio5.py +19 -13
  187. scipy/io/matlab/_mio5_utils.cpython-313t-darwin.so +0 -0
  188. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  189. scipy/io/matlab/_miobase.py +4 -1
  190. scipy/io/matlab/_streams.cpython-313t-darwin.so +0 -0
  191. scipy/io/matlab/tests/test_mio.py +46 -18
  192. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  193. scipy/io/tests/test_mmio.py +7 -1
  194. scipy/io/tests/test_wavfile.py +41 -0
  195. scipy/io/wavfile.py +57 -10
  196. scipy/linalg/_basic.py +113 -86
  197. scipy/linalg/_cythonized_array_utils.cpython-313t-darwin.so +0 -0
  198. scipy/linalg/_decomp.py +22 -9
  199. scipy/linalg/_decomp_cholesky.py +28 -13
  200. scipy/linalg/_decomp_cossin.py +45 -30
  201. scipy/linalg/_decomp_interpolative.cpython-313t-darwin.so +0 -0
  202. scipy/linalg/_decomp_ldl.py +4 -1
  203. scipy/linalg/_decomp_lu.py +18 -6
  204. scipy/linalg/_decomp_lu_cython.cpython-313t-darwin.so +0 -0
  205. scipy/linalg/_decomp_polar.py +2 -0
  206. scipy/linalg/_decomp_qr.py +6 -2
  207. scipy/linalg/_decomp_qz.py +3 -0
  208. scipy/linalg/_decomp_schur.py +3 -1
  209. scipy/linalg/_decomp_svd.py +13 -2
  210. scipy/linalg/_decomp_update.cpython-313t-darwin.so +0 -0
  211. scipy/linalg/_expm_frechet.py +4 -0
  212. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  213. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  214. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_matfuncs.py +187 -4
  216. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  217. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  218. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  219. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  220. scipy/linalg/_procrustes.py +2 -0
  221. scipy/linalg/_sketches.py +17 -6
  222. scipy/linalg/_solve_toeplitz.cpython-313t-darwin.so +0 -0
  223. scipy/linalg/_solvers.py +7 -2
  224. scipy/linalg/_special_matrices.py +26 -36
  225. scipy/linalg/blas.py +35 -24
  226. scipy/linalg/cython_blas.cpython-313t-darwin.so +0 -0
  227. scipy/linalg/cython_lapack.cpython-313t-darwin.so +0 -0
  228. scipy/linalg/lapack.py +22 -2
  229. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  230. scipy/linalg/tests/test_basic.py +31 -16
  231. scipy/linalg/tests/test_batch.py +588 -0
  232. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  233. scipy/linalg/tests/test_decomp.py +40 -3
  234. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  235. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  236. scipy/linalg/tests/test_interpolative.py +17 -0
  237. scipy/linalg/tests/test_lapack.py +115 -7
  238. scipy/linalg/tests/test_matfuncs.py +157 -102
  239. scipy/linalg/tests/test_procrustes.py +0 -7
  240. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  241. scipy/linalg/tests/test_special_matrices.py +1 -5
  242. scipy/ndimage/__init__.py +1 -0
  243. scipy/ndimage/_cytest.cpython-313t-darwin.so +0 -0
  244. scipy/ndimage/_delegators.py +8 -2
  245. scipy/ndimage/_filters.py +453 -5
  246. scipy/ndimage/_interpolation.py +36 -6
  247. scipy/ndimage/_measurements.py +4 -2
  248. scipy/ndimage/_morphology.py +5 -0
  249. scipy/ndimage/_nd_image.cpython-313t-darwin.so +0 -0
  250. scipy/ndimage/_ndimage_api.py +2 -1
  251. scipy/ndimage/_ni_docstrings.py +5 -1
  252. scipy/ndimage/_ni_label.cpython-313t-darwin.so +0 -0
  253. scipy/ndimage/_ni_support.py +1 -5
  254. scipy/ndimage/_rank_filter_1d.cpython-313t-darwin.so +0 -0
  255. scipy/ndimage/_support_alternative_backends.py +18 -6
  256. scipy/ndimage/tests/test_filters.py +384 -259
  257. scipy/ndimage/tests/test_fourier.py +7 -9
  258. scipy/ndimage/tests/test_interpolation.py +68 -61
  259. scipy/ndimage/tests/test_measurements.py +18 -35
  260. scipy/ndimage/tests/test_morphology.py +143 -131
  261. scipy/ndimage/tests/test_splines.py +1 -3
  262. scipy/odr/__odrpack.cpython-313t-darwin.so +0 -0
  263. scipy/optimize/_basinhopping.py +13 -7
  264. scipy/optimize/_bglu_dense.cpython-313t-darwin.so +0 -0
  265. scipy/optimize/_bracket.py +46 -26
  266. scipy/optimize/_chandrupatla.py +9 -10
  267. scipy/optimize/_cobyla_py.py +104 -123
  268. scipy/optimize/_constraints.py +14 -10
  269. scipy/optimize/_differentiable_functions.py +371 -230
  270. scipy/optimize/_differentialevolution.py +4 -3
  271. scipy/optimize/_direct.cpython-313t-darwin.so +0 -0
  272. scipy/optimize/_dual_annealing.py +1 -1
  273. scipy/optimize/_elementwise.py +1 -4
  274. scipy/optimize/_group_columns.cpython-313t-darwin.so +0 -0
  275. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  276. scipy/optimize/_lbfgsb.cpython-313t-darwin.so +0 -0
  277. scipy/optimize/_lbfgsb_py.py +80 -24
  278. scipy/optimize/_linprog_doc.py +2 -2
  279. scipy/optimize/_linprog_highs.py +11 -11
  280. scipy/optimize/_linprog_ip.py +25 -10
  281. scipy/optimize/_linprog_util.py +18 -19
  282. scipy/optimize/_lsap.cpython-313t-darwin.so +0 -0
  283. scipy/optimize/_lsq/common.py +3 -3
  284. scipy/optimize/_lsq/dogbox.py +16 -2
  285. scipy/optimize/_lsq/givens_elimination.cpython-313t-darwin.so +0 -0
  286. scipy/optimize/_lsq/least_squares.py +198 -126
  287. scipy/optimize/_lsq/lsq_linear.py +6 -6
  288. scipy/optimize/_lsq/trf.py +35 -8
  289. scipy/optimize/_milp.py +3 -1
  290. scipy/optimize/_minimize.py +105 -36
  291. scipy/optimize/_minpack.cpython-313t-darwin.so +0 -0
  292. scipy/optimize/_minpack_py.py +21 -14
  293. scipy/optimize/_moduleTNC.cpython-313t-darwin.so +0 -0
  294. scipy/optimize/_nnls.py +20 -21
  295. scipy/optimize/_nonlin.py +34 -3
  296. scipy/optimize/_numdiff.py +288 -110
  297. scipy/optimize/_optimize.py +86 -48
  298. scipy/optimize/_pava_pybind.cpython-313t-darwin.so +0 -0
  299. scipy/optimize/_remove_redundancy.py +5 -5
  300. scipy/optimize/_root_scalar.py +1 -1
  301. scipy/optimize/_shgo.py +6 -0
  302. scipy/optimize/_shgo_lib/_complex.py +1 -1
  303. scipy/optimize/_slsqp_py.py +216 -124
  304. scipy/optimize/_slsqplib.cpython-313t-darwin.so +0 -0
  305. scipy/optimize/_spectral.py +1 -1
  306. scipy/optimize/_tnc.py +8 -1
  307. scipy/optimize/_trlib/_trlib.cpython-313t-darwin.so +0 -0
  308. scipy/optimize/_trustregion.py +20 -6
  309. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  310. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  311. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  312. scipy/optimize/_trustregion_constr/projections.py +12 -8
  313. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  314. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  315. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  316. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  317. scipy/optimize/_trustregion_exact.py +0 -1
  318. scipy/optimize/_zeros.cpython-313t-darwin.so +0 -0
  319. scipy/optimize/_zeros_py.py +97 -17
  320. scipy/optimize/cython_optimize/_zeros.cpython-313t-darwin.so +0 -0
  321. scipy/optimize/slsqp.py +0 -1
  322. scipy/optimize/tests/test__basinhopping.py +1 -1
  323. scipy/optimize/tests/test__differential_evolution.py +4 -4
  324. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  325. scipy/optimize/tests/test__numdiff.py +66 -22
  326. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  327. scipy/optimize/tests/test__shgo.py +9 -1
  328. scipy/optimize/tests/test_bracket.py +71 -46
  329. scipy/optimize/tests/test_chandrupatla.py +133 -135
  330. scipy/optimize/tests/test_cobyla.py +74 -45
  331. scipy/optimize/tests/test_constraints.py +1 -1
  332. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  333. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  334. scipy/optimize/tests/test_least_squares.py +125 -13
  335. scipy/optimize/tests/test_linear_assignment.py +3 -3
  336. scipy/optimize/tests/test_linprog.py +3 -3
  337. scipy/optimize/tests/test_lsq_linear.py +6 -6
  338. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  339. scipy/optimize/tests/test_minpack.py +4 -4
  340. scipy/optimize/tests/test_nnls.py +43 -3
  341. scipy/optimize/tests/test_nonlin.py +36 -0
  342. scipy/optimize/tests/test_optimize.py +98 -20
  343. scipy/optimize/tests/test_slsqp.py +36 -4
  344. scipy/optimize/tests/test_zeros.py +34 -1
  345. scipy/signal/__init__.py +12 -23
  346. scipy/signal/_delegators.py +568 -0
  347. scipy/signal/_filter_design.py +459 -241
  348. scipy/signal/_fir_filter_design.py +262 -90
  349. scipy/signal/_lti_conversion.py +3 -2
  350. scipy/signal/_ltisys.py +118 -91
  351. scipy/signal/_max_len_seq_inner.cpython-313t-darwin.so +0 -0
  352. scipy/signal/_peak_finding_utils.cpython-313t-darwin.so +0 -0
  353. scipy/signal/_polyutils.py +172 -0
  354. scipy/signal/_short_time_fft.py +553 -76
  355. scipy/signal/_signal_api.py +30 -0
  356. scipy/signal/_signaltools.py +719 -396
  357. scipy/signal/_sigtools.cpython-313t-darwin.so +0 -0
  358. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  359. scipy/signal/_spectral_py.py +230 -50
  360. scipy/signal/_spline.cpython-313t-darwin.so +0 -0
  361. scipy/signal/_spline_filters.py +108 -68
  362. scipy/signal/_support_alternative_backends.py +73 -0
  363. scipy/signal/_upfirdn.py +4 -1
  364. scipy/signal/_upfirdn_apply.cpython-313t-darwin.so +0 -0
  365. scipy/signal/_waveforms.py +2 -11
  366. scipy/signal/_wavelets.py +1 -1
  367. scipy/signal/fir_filter_design.py +1 -0
  368. scipy/signal/spline.py +4 -11
  369. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  370. scipy/signal/tests/test_bsplines.py +114 -79
  371. scipy/signal/tests/test_cont2discrete.py +9 -2
  372. scipy/signal/tests/test_filter_design.py +721 -481
  373. scipy/signal/tests/test_fir_filter_design.py +332 -140
  374. scipy/signal/tests/test_savitzky_golay.py +4 -3
  375. scipy/signal/tests/test_short_time_fft.py +231 -5
  376. scipy/signal/tests/test_signaltools.py +2150 -1349
  377. scipy/signal/tests/test_spectral.py +50 -6
  378. scipy/signal/tests/test_splines.py +161 -96
  379. scipy/signal/tests/test_upfirdn.py +84 -50
  380. scipy/signal/tests/test_waveforms.py +20 -0
  381. scipy/signal/tests/test_windows.py +607 -466
  382. scipy/signal/windows/_windows.py +287 -148
  383. scipy/sparse/__init__.py +23 -4
  384. scipy/sparse/_base.py +269 -120
  385. scipy/sparse/_bsr.py +7 -4
  386. scipy/sparse/_compressed.py +59 -234
  387. scipy/sparse/_construct.py +90 -38
  388. scipy/sparse/_coo.py +115 -181
  389. scipy/sparse/_csc.py +4 -4
  390. scipy/sparse/_csparsetools.cpython-313t-darwin.so +0 -0
  391. scipy/sparse/_csr.py +2 -2
  392. scipy/sparse/_data.py +48 -48
  393. scipy/sparse/_dia.py +105 -21
  394. scipy/sparse/_dok.py +0 -23
  395. scipy/sparse/_index.py +4 -4
  396. scipy/sparse/_matrix.py +23 -0
  397. scipy/sparse/_sparsetools.cpython-313t-darwin.so +0 -0
  398. scipy/sparse/_sputils.py +37 -22
  399. scipy/sparse/base.py +0 -9
  400. scipy/sparse/bsr.py +0 -14
  401. scipy/sparse/compressed.py +0 -23
  402. scipy/sparse/construct.py +0 -6
  403. scipy/sparse/coo.py +0 -14
  404. scipy/sparse/csc.py +0 -3
  405. scipy/sparse/csgraph/_flow.cpython-313t-darwin.so +0 -0
  406. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  407. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  409. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  410. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  411. scipy/sparse/csgraph/_traversal.cpython-313t-darwin.so +0 -0
  412. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  413. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  414. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  415. scipy/sparse/csr.py +0 -5
  416. scipy/sparse/data.py +1 -6
  417. scipy/sparse/dia.py +0 -7
  418. scipy/sparse/dok.py +0 -10
  419. scipy/sparse/linalg/_dsolve/_superlu.cpython-313t-darwin.so +0 -0
  420. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  421. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  422. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313t-darwin.so +0 -0
  423. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  424. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  425. scipy/sparse/linalg/_expm_multiply.py +8 -3
  426. scipy/sparse/linalg/_interface.py +29 -26
  427. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  428. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  429. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  430. scipy/sparse/linalg/_isolve/minres.py +5 -5
  431. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  432. scipy/sparse/linalg/_isolve/utils.py +2 -8
  433. scipy/sparse/linalg/_matfuncs.py +1 -1
  434. scipy/sparse/linalg/_norm.py +1 -1
  435. scipy/sparse/linalg/_propack/_cpropack.cpython-313t-darwin.so +0 -0
  436. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  437. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  438. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-darwin.so +0 -0
  439. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  440. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  441. scipy/sparse/linalg/tests/test_interface.py +35 -0
  442. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  443. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  444. scipy/sparse/tests/test_base.py +224 -40
  445. scipy/sparse/tests/test_common1d.py +17 -12
  446. scipy/sparse/tests/test_construct.py +1 -1
  447. scipy/sparse/tests/test_coo.py +272 -4
  448. scipy/sparse/tests/test_sparsetools.py +5 -0
  449. scipy/sparse/tests/test_sputils.py +36 -7
  450. scipy/spatial/_ckdtree.cpython-313t-darwin.so +0 -0
  451. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  452. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  453. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  454. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  455. scipy/spatial/_voronoi.cpython-313t-darwin.so +0 -0
  456. scipy/spatial/distance.py +49 -42
  457. scipy/spatial/tests/test_distance.py +15 -1
  458. scipy/spatial/tests/test_kdtree.py +1 -0
  459. scipy/spatial/tests/test_qhull.py +106 -2
  460. scipy/spatial/transform/__init__.py +5 -3
  461. scipy/spatial/transform/_rigid_transform.cpython-313t-darwin.so +0 -0
  462. scipy/spatial/transform/_rotation.cpython-313t-darwin.so +0 -0
  463. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  464. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  465. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  466. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  467. scipy/special/__init__.py +1 -47
  468. scipy/special/_add_newdocs.py +34 -772
  469. scipy/special/_basic.py +22 -25
  470. scipy/special/_comb.cpython-313t-darwin.so +0 -0
  471. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  472. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  473. scipy/special/_logsumexp.py +83 -69
  474. scipy/special/_orthogonal.pyi +1 -1
  475. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  476. scipy/special/_special_ufuncs.cpython-313t-darwin.so +0 -0
  477. scipy/special/_spherical_bessel.py +4 -4
  478. scipy/special/_support_alternative_backends.py +212 -119
  479. scipy/special/_test_internal.cpython-313t-darwin.so +0 -0
  480. scipy/special/_testutils.py +4 -4
  481. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  482. scipy/special/_ufuncs.pyi +1 -0
  483. scipy/special/_ufuncs.pyx +215 -1400
  484. scipy/special/_ufuncs_cxx.cpython-313t-darwin.so +0 -0
  485. scipy/special/_ufuncs_cxx.pxd +2 -15
  486. scipy/special/_ufuncs_cxx.pyx +5 -44
  487. scipy/special/_ufuncs_cxx_defs.h +2 -16
  488. scipy/special/_ufuncs_defs.h +0 -8
  489. scipy/special/cython_special.cpython-313t-darwin.so +0 -0
  490. scipy/special/cython_special.pxd +1 -1
  491. scipy/special/tests/_cython_examples/meson.build +10 -1
  492. scipy/special/tests/test_basic.py +153 -20
  493. scipy/special/tests/test_boost_ufuncs.py +3 -0
  494. scipy/special/tests/test_cdflib.py +35 -11
  495. scipy/special/tests/test_gammainc.py +16 -0
  496. scipy/special/tests/test_hyp2f1.py +23 -2
  497. scipy/special/tests/test_log1mexp.py +85 -0
  498. scipy/special/tests/test_logsumexp.py +220 -64
  499. scipy/special/tests/test_mpmath.py +1 -0
  500. scipy/special/tests/test_nan_inputs.py +1 -1
  501. scipy/special/tests/test_orthogonal.py +17 -18
  502. scipy/special/tests/test_sf_error.py +3 -2
  503. scipy/special/tests/test_sph_harm.py +6 -7
  504. scipy/special/tests/test_support_alternative_backends.py +211 -76
  505. scipy/stats/__init__.py +4 -1
  506. scipy/stats/_ansari_swilk_statistics.cpython-313t-darwin.so +0 -0
  507. scipy/stats/_axis_nan_policy.py +5 -12
  508. scipy/stats/_biasedurn.cpython-313t-darwin.so +0 -0
  509. scipy/stats/_continued_fraction.py +387 -0
  510. scipy/stats/_continuous_distns.py +296 -319
  511. scipy/stats/_correlation.py +1 -1
  512. scipy/stats/_covariance.py +6 -3
  513. scipy/stats/_discrete_distns.py +39 -32
  514. scipy/stats/_distn_infrastructure.py +39 -12
  515. scipy/stats/_distribution_infrastructure.py +920 -238
  516. scipy/stats/_entropy.py +9 -10
  517. scipy/{_lib → stats}/_finite_differences.py +1 -1
  518. scipy/stats/_hypotests.py +83 -50
  519. scipy/stats/_kde.py +53 -49
  520. scipy/stats/_ksstats.py +1 -1
  521. scipy/stats/_levy_stable/__init__.py +7 -15
  522. scipy/stats/_levy_stable/levyst.cpython-313t-darwin.so +0 -0
  523. scipy/stats/_morestats.py +118 -73
  524. scipy/stats/_mstats_basic.py +13 -17
  525. scipy/stats/_mstats_extras.py +8 -8
  526. scipy/stats/_multivariate.py +89 -113
  527. scipy/stats/_new_distributions.py +97 -20
  528. scipy/stats/_page_trend_test.py +12 -5
  529. scipy/stats/_probability_distribution.py +265 -43
  530. scipy/stats/_qmc.py +14 -9
  531. scipy/stats/_qmc_cy.cpython-313t-darwin.so +0 -0
  532. scipy/stats/_qmvnt.py +16 -95
  533. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  534. scipy/stats/_quantile.py +335 -0
  535. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  536. scipy/stats/_resampling.py +5 -30
  537. scipy/stats/_sampling.py +1 -1
  538. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  539. scipy/stats/_stats.cpython-313t-darwin.so +0 -0
  540. scipy/stats/_stats_mstats_common.py +21 -2
  541. scipy/stats/_stats_py.py +551 -477
  542. scipy/stats/_stats_pythran.cpython-313t-darwin.so +0 -0
  543. scipy/stats/_unuran/unuran_wrapper.cpython-313t-darwin.so +0 -0
  544. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  545. scipy/stats/_variation.py +6 -8
  546. scipy/stats/_wilcoxon.py +13 -7
  547. scipy/stats/tests/common_tests.py +6 -4
  548. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  549. scipy/stats/tests/test_continued_fraction.py +173 -0
  550. scipy/stats/tests/test_continuous.py +379 -60
  551. scipy/stats/tests/test_continuous_basic.py +18 -12
  552. scipy/stats/tests/test_discrete_basic.py +14 -8
  553. scipy/stats/tests/test_discrete_distns.py +16 -16
  554. scipy/stats/tests/test_distributions.py +117 -75
  555. scipy/stats/tests/test_entropy.py +40 -48
  556. scipy/stats/tests/test_fit.py +4 -3
  557. scipy/stats/tests/test_hypotests.py +153 -24
  558. scipy/stats/tests/test_kdeoth.py +109 -41
  559. scipy/stats/tests/test_marray.py +289 -0
  560. scipy/stats/tests/test_morestats.py +81 -49
  561. scipy/stats/tests/test_mstats_basic.py +3 -3
  562. scipy/stats/tests/test_multivariate.py +434 -83
  563. scipy/stats/tests/test_qmc.py +13 -10
  564. scipy/stats/tests/test_quantile.py +199 -0
  565. scipy/stats/tests/test_rank.py +119 -112
  566. scipy/stats/tests/test_resampling.py +47 -56
  567. scipy/stats/tests/test_sampling.py +9 -4
  568. scipy/stats/tests/test_stats.py +799 -939
  569. scipy/stats/tests/test_variation.py +8 -6
  570. scipy/version.py +2 -2
  571. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  572. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/METADATA +12 -12
  573. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/RECORD +574 -581
  574. scipy-1.16.0.dist-info/WHEEL +6 -0
  575. scipy/_lib/array_api_extra/_funcs.py +0 -484
  576. scipy/_lib/array_api_extra/_typing.py +0 -8
  577. scipy/interpolate/_bspl.cpython-313t-darwin.so +0 -0
  578. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  579. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  580. scipy/optimize/_slsqp.cpython-313t-darwin.so +0 -0
  581. scipy/spatial/qhull_src/COPYING.txt +0 -38
  582. scipy/special/libsf_error_state.dylib +0 -0
  583. scipy/special/tests/test_log_softmax.py +0 -109
  584. scipy/special/tests/test_xsf_cuda.py +0 -114
  585. scipy/special/xsf/binom.h +0 -89
  586. scipy/special/xsf/cdflib.h +0 -100
  587. scipy/special/xsf/cephes/airy.h +0 -307
  588. scipy/special/xsf/cephes/besselpoly.h +0 -51
  589. scipy/special/xsf/cephes/beta.h +0 -257
  590. scipy/special/xsf/cephes/cbrt.h +0 -131
  591. scipy/special/xsf/cephes/chbevl.h +0 -85
  592. scipy/special/xsf/cephes/chdtr.h +0 -193
  593. scipy/special/xsf/cephes/const.h +0 -87
  594. scipy/special/xsf/cephes/ellie.h +0 -293
  595. scipy/special/xsf/cephes/ellik.h +0 -251
  596. scipy/special/xsf/cephes/ellpe.h +0 -107
  597. scipy/special/xsf/cephes/ellpk.h +0 -117
  598. scipy/special/xsf/cephes/expn.h +0 -260
  599. scipy/special/xsf/cephes/gamma.h +0 -398
  600. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  601. scipy/special/xsf/cephes/hyperg.h +0 -361
  602. scipy/special/xsf/cephes/i0.h +0 -149
  603. scipy/special/xsf/cephes/i1.h +0 -158
  604. scipy/special/xsf/cephes/igam.h +0 -421
  605. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  606. scipy/special/xsf/cephes/igami.h +0 -313
  607. scipy/special/xsf/cephes/j0.h +0 -225
  608. scipy/special/xsf/cephes/j1.h +0 -198
  609. scipy/special/xsf/cephes/jv.h +0 -715
  610. scipy/special/xsf/cephes/k0.h +0 -164
  611. scipy/special/xsf/cephes/k1.h +0 -163
  612. scipy/special/xsf/cephes/kn.h +0 -243
  613. scipy/special/xsf/cephes/lanczos.h +0 -112
  614. scipy/special/xsf/cephes/ndtr.h +0 -275
  615. scipy/special/xsf/cephes/poch.h +0 -85
  616. scipy/special/xsf/cephes/polevl.h +0 -167
  617. scipy/special/xsf/cephes/psi.h +0 -194
  618. scipy/special/xsf/cephes/rgamma.h +0 -111
  619. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  620. scipy/special/xsf/cephes/shichi.h +0 -248
  621. scipy/special/xsf/cephes/sici.h +0 -224
  622. scipy/special/xsf/cephes/sindg.h +0 -221
  623. scipy/special/xsf/cephes/tandg.h +0 -139
  624. scipy/special/xsf/cephes/trig.h +0 -58
  625. scipy/special/xsf/cephes/unity.h +0 -186
  626. scipy/special/xsf/cephes/zeta.h +0 -172
  627. scipy/special/xsf/config.h +0 -304
  628. scipy/special/xsf/digamma.h +0 -205
  629. scipy/special/xsf/error.h +0 -57
  630. scipy/special/xsf/evalpoly.h +0 -47
  631. scipy/special/xsf/expint.h +0 -266
  632. scipy/special/xsf/hyp2f1.h +0 -694
  633. scipy/special/xsf/iv_ratio.h +0 -173
  634. scipy/special/xsf/lambertw.h +0 -150
  635. scipy/special/xsf/loggamma.h +0 -163
  636. scipy/special/xsf/sici.h +0 -200
  637. scipy/special/xsf/tools.h +0 -427
  638. scipy/special/xsf/trig.h +0 -164
  639. scipy/special/xsf/wright_bessel.h +0 -843
  640. scipy/special/xsf/zlog1.h +0 -35
  641. scipy/stats/_mvn.cpython-313t-darwin.so +0 -0
  642. scipy-1.15.2.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)