scipy 1.15.3__cp312-cp312-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp312-cp312-musllinux_1_2_aarch64.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 (641) hide show
  1. scipy/__config__.py +10 -10
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-aarch64-linux-musl.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-312-aarch64-linux-musl.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_fpumode.cpython-312-aarch64-linux-musl.so +0 -0
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_ccallback.cpython-312-aarch64-linux-musl.so +0 -0
  13. scipy/_lib/_test_deprecation_call.cpython-312-aarch64-linux-musl.so +0 -0
  14. scipy/_lib/_test_deprecation_def.cpython-312-aarch64-linux-musl.so +0 -0
  15. scipy/_lib/_testutils.py +6 -2
  16. scipy/_lib/_uarray/_uarray.cpython-312-aarch64-linux-musl.so +0 -0
  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-312-aarch64-linux-musl.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-312-aarch64-linux-musl.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-312-aarch64-linux-musl.so +0 -0
  98. scipy/cluster/_vq.cpython-312-aarch64-linux-musl.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 +263 -157
  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/pypocketfft.cpython-312-aarch64-linux-musl.so +0 -0
  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-312-aarch64-linux-musl.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-312-aarch64-linux-musl.so +0 -0
  129. scipy/integrate/_lsoda.cpython-312-aarch64-linux-musl.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-312-aarch64-linux-musl.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-312-aarch64-linux-musl.so +0 -0
  134. scipy/integrate/_quadpack_py.py +11 -7
  135. scipy/integrate/_quadrature.py +3 -3
  136. scipy/integrate/_rules/_base.py +2 -2
  137. scipy/integrate/_tanhsinh.py +48 -47
  138. scipy/integrate/_test_multivariate.cpython-312-aarch64-linux-musl.so +0 -0
  139. scipy/integrate/_test_odeint_banded.cpython-312-aarch64-linux-musl.so +0 -0
  140. scipy/integrate/_vode.cpython-312-aarch64-linux-musl.so +0 -0
  141. scipy/integrate/tests/test__quad_vec.py +0 -6
  142. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  143. scipy/integrate/tests/test_cubature.py +21 -35
  144. scipy/integrate/tests/test_quadrature.py +6 -8
  145. scipy/integrate/tests/test_tanhsinh.py +56 -48
  146. scipy/interpolate/__init__.py +70 -58
  147. scipy/interpolate/_bary_rational.py +22 -22
  148. scipy/interpolate/_bsplines.py +119 -66
  149. scipy/interpolate/_cubic.py +65 -50
  150. scipy/interpolate/_dfitpack.cpython-312-aarch64-linux-musl.so +0 -0
  151. scipy/interpolate/_dierckx.cpython-312-aarch64-linux-musl.so +0 -0
  152. scipy/interpolate/_fitpack.cpython-312-aarch64-linux-musl.so +0 -0
  153. scipy/interpolate/_fitpack2.py +9 -6
  154. scipy/interpolate/_fitpack_impl.py +32 -26
  155. scipy/interpolate/_fitpack_repro.py +23 -19
  156. scipy/interpolate/_interpnd.cpython-312-aarch64-linux-musl.so +0 -0
  157. scipy/interpolate/_interpolate.py +30 -12
  158. scipy/interpolate/_ndbspline.py +13 -18
  159. scipy/interpolate/_ndgriddata.py +5 -8
  160. scipy/interpolate/_polyint.py +95 -31
  161. scipy/interpolate/_ppoly.cpython-312-aarch64-linux-musl.so +0 -0
  162. scipy/interpolate/_rbf.py +2 -2
  163. scipy/interpolate/_rbfinterp.py +1 -1
  164. scipy/interpolate/_rbfinterp_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  165. scipy/interpolate/_rgi.py +31 -26
  166. scipy/interpolate/_rgi_cython.cpython-312-aarch64-linux-musl.so +0 -0
  167. scipy/interpolate/dfitpack.py +0 -20
  168. scipy/interpolate/interpnd.py +1 -2
  169. scipy/interpolate/tests/test_bary_rational.py +2 -2
  170. scipy/interpolate/tests/test_bsplines.py +97 -1
  171. scipy/interpolate/tests/test_fitpack2.py +39 -1
  172. scipy/interpolate/tests/test_interpnd.py +32 -20
  173. scipy/interpolate/tests/test_interpolate.py +48 -4
  174. scipy/interpolate/tests/test_rgi.py +2 -1
  175. scipy/io/_fast_matrix_market/__init__.py +2 -0
  176. scipy/io/_fast_matrix_market/_fmm_core.cpython-312-aarch64-linux-musl.so +0 -0
  177. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  178. scipy/io/_harwell_boeing/hb.py +7 -11
  179. scipy/io/_idl.py +5 -7
  180. scipy/io/_netcdf.py +15 -5
  181. scipy/io/_test_fortran.cpython-312-aarch64-linux-musl.so +0 -0
  182. scipy/io/arff/tests/test_arffread.py +3 -3
  183. scipy/io/matlab/__init__.py +5 -3
  184. scipy/io/matlab/_mio.py +4 -1
  185. scipy/io/matlab/_mio5.py +19 -13
  186. scipy/io/matlab/_mio5_utils.cpython-312-aarch64-linux-musl.so +0 -0
  187. scipy/io/matlab/_mio_utils.cpython-312-aarch64-linux-musl.so +0 -0
  188. scipy/io/matlab/_miobase.py +4 -1
  189. scipy/io/matlab/_streams.cpython-312-aarch64-linux-musl.so +0 -0
  190. scipy/io/matlab/tests/test_mio.py +46 -18
  191. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  192. scipy/io/tests/test_mmio.py +7 -1
  193. scipy/io/tests/test_wavfile.py +41 -0
  194. scipy/io/wavfile.py +57 -10
  195. scipy/linalg/_basic.py +113 -86
  196. scipy/linalg/_cythonized_array_utils.cpython-312-aarch64-linux-musl.so +0 -0
  197. scipy/linalg/_decomp.py +22 -9
  198. scipy/linalg/_decomp_cholesky.py +28 -13
  199. scipy/linalg/_decomp_cossin.py +45 -30
  200. scipy/linalg/_decomp_interpolative.cpython-312-aarch64-linux-musl.so +0 -0
  201. scipy/linalg/_decomp_ldl.py +4 -1
  202. scipy/linalg/_decomp_lu.py +18 -6
  203. scipy/linalg/_decomp_lu_cython.cpython-312-aarch64-linux-musl.so +0 -0
  204. scipy/linalg/_decomp_polar.py +2 -0
  205. scipy/linalg/_decomp_qr.py +6 -2
  206. scipy/linalg/_decomp_qz.py +3 -0
  207. scipy/linalg/_decomp_schur.py +3 -1
  208. scipy/linalg/_decomp_svd.py +13 -2
  209. scipy/linalg/_decomp_update.cpython-312-aarch64-linux-musl.so +0 -0
  210. scipy/linalg/_expm_frechet.py +4 -0
  211. scipy/linalg/_fblas.cpython-312-aarch64-linux-musl.so +0 -0
  212. scipy/linalg/_flapack.cpython-312-aarch64-linux-musl.so +0 -0
  213. scipy/linalg/_linalg_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  214. scipy/linalg/_matfuncs.py +187 -4
  215. scipy/linalg/_matfuncs_expm.cpython-312-aarch64-linux-musl.so +0 -0
  216. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-aarch64-linux-musl.so +0 -0
  217. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  218. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-aarch64-linux-musl.so +0 -0
  219. scipy/linalg/_procrustes.py +2 -0
  220. scipy/linalg/_sketches.py +17 -6
  221. scipy/linalg/_solve_toeplitz.cpython-312-aarch64-linux-musl.so +0 -0
  222. scipy/linalg/_solvers.py +7 -2
  223. scipy/linalg/_special_matrices.py +26 -36
  224. scipy/linalg/cython_blas.cpython-312-aarch64-linux-musl.so +0 -0
  225. scipy/linalg/cython_lapack.cpython-312-aarch64-linux-musl.so +0 -0
  226. scipy/linalg/lapack.py +22 -2
  227. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  228. scipy/linalg/tests/test_basic.py +31 -16
  229. scipy/linalg/tests/test_batch.py +588 -0
  230. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  231. scipy/linalg/tests/test_decomp.py +40 -3
  232. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  233. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  234. scipy/linalg/tests/test_lapack.py +115 -7
  235. scipy/linalg/tests/test_matfuncs.py +157 -102
  236. scipy/linalg/tests/test_procrustes.py +0 -7
  237. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  238. scipy/linalg/tests/test_special_matrices.py +1 -5
  239. scipy/ndimage/__init__.py +1 -0
  240. scipy/ndimage/_ctest.cpython-312-aarch64-linux-musl.so +0 -0
  241. scipy/ndimage/_cytest.cpython-312-aarch64-linux-musl.so +0 -0
  242. scipy/ndimage/_delegators.py +8 -2
  243. scipy/ndimage/_filters.py +453 -5
  244. scipy/ndimage/_interpolation.py +36 -6
  245. scipy/ndimage/_measurements.py +4 -2
  246. scipy/ndimage/_morphology.py +5 -0
  247. scipy/ndimage/_nd_image.cpython-312-aarch64-linux-musl.so +0 -0
  248. scipy/ndimage/_ni_docstrings.py +5 -1
  249. scipy/ndimage/_ni_label.cpython-312-aarch64-linux-musl.so +0 -0
  250. scipy/ndimage/_ni_support.py +1 -5
  251. scipy/ndimage/_rank_filter_1d.cpython-312-aarch64-linux-musl.so +0 -0
  252. scipy/ndimage/_support_alternative_backends.py +18 -6
  253. scipy/ndimage/tests/test_filters.py +370 -259
  254. scipy/ndimage/tests/test_fourier.py +7 -9
  255. scipy/ndimage/tests/test_interpolation.py +68 -61
  256. scipy/ndimage/tests/test_measurements.py +18 -35
  257. scipy/ndimage/tests/test_morphology.py +143 -131
  258. scipy/ndimage/tests/test_splines.py +1 -3
  259. scipy/odr/__odrpack.cpython-312-aarch64-linux-musl.so +0 -0
  260. scipy/optimize/_basinhopping.py +13 -7
  261. scipy/optimize/_bglu_dense.cpython-312-aarch64-linux-musl.so +0 -0
  262. scipy/optimize/_bracket.py +17 -24
  263. scipy/optimize/_chandrupatla.py +9 -10
  264. scipy/optimize/_cobyla_py.py +104 -123
  265. scipy/optimize/_constraints.py +14 -10
  266. scipy/optimize/_differentiable_functions.py +371 -230
  267. scipy/optimize/_differentialevolution.py +4 -3
  268. scipy/optimize/_direct.cpython-312-aarch64-linux-musl.so +0 -0
  269. scipy/optimize/_dual_annealing.py +1 -1
  270. scipy/optimize/_elementwise.py +1 -4
  271. scipy/optimize/_group_columns.cpython-312-aarch64-linux-musl.so +0 -0
  272. scipy/optimize/_highspy/_core.cpython-312-aarch64-linux-musl.so +0 -0
  273. scipy/optimize/_highspy/_highs_options.cpython-312-aarch64-linux-musl.so +0 -0
  274. scipy/optimize/_lbfgsb.cpython-312-aarch64-linux-musl.so +0 -0
  275. scipy/optimize/_lbfgsb_py.py +57 -16
  276. scipy/optimize/_linprog_doc.py +2 -2
  277. scipy/optimize/_linprog_highs.py +2 -2
  278. scipy/optimize/_linprog_ip.py +25 -10
  279. scipy/optimize/_linprog_util.py +14 -16
  280. scipy/optimize/_lsap.cpython-312-aarch64-linux-musl.so +0 -0
  281. scipy/optimize/_lsq/common.py +3 -3
  282. scipy/optimize/_lsq/dogbox.py +16 -2
  283. scipy/optimize/_lsq/givens_elimination.cpython-312-aarch64-linux-musl.so +0 -0
  284. scipy/optimize/_lsq/least_squares.py +198 -126
  285. scipy/optimize/_lsq/lsq_linear.py +6 -6
  286. scipy/optimize/_lsq/trf.py +35 -8
  287. scipy/optimize/_milp.py +3 -1
  288. scipy/optimize/_minimize.py +105 -36
  289. scipy/optimize/_minpack.cpython-312-aarch64-linux-musl.so +0 -0
  290. scipy/optimize/_minpack_py.py +21 -14
  291. scipy/optimize/_moduleTNC.cpython-312-aarch64-linux-musl.so +0 -0
  292. scipy/optimize/_nnls.py +20 -21
  293. scipy/optimize/_nonlin.py +34 -3
  294. scipy/optimize/_numdiff.py +288 -110
  295. scipy/optimize/_optimize.py +86 -48
  296. scipy/optimize/_pava_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  297. scipy/optimize/_remove_redundancy.py +5 -5
  298. scipy/optimize/_root_scalar.py +1 -1
  299. scipy/optimize/_shgo.py +6 -0
  300. scipy/optimize/_shgo_lib/_complex.py +1 -1
  301. scipy/optimize/_slsqp_py.py +216 -124
  302. scipy/optimize/_slsqplib.cpython-312-aarch64-linux-musl.so +0 -0
  303. scipy/optimize/_spectral.py +1 -1
  304. scipy/optimize/_tnc.py +8 -1
  305. scipy/optimize/_trlib/_trlib.cpython-312-aarch64-linux-musl.so +0 -0
  306. scipy/optimize/_trustregion.py +20 -6
  307. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  308. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  309. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  310. scipy/optimize/_trustregion_constr/projections.py +12 -8
  311. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  312. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  313. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  314. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  315. scipy/optimize/_trustregion_exact.py +0 -1
  316. scipy/optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  317. scipy/optimize/_zeros_py.py +97 -17
  318. scipy/optimize/cython_optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  319. scipy/optimize/slsqp.py +0 -1
  320. scipy/optimize/tests/test__basinhopping.py +1 -1
  321. scipy/optimize/tests/test__differential_evolution.py +4 -4
  322. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  323. scipy/optimize/tests/test__numdiff.py +66 -22
  324. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  325. scipy/optimize/tests/test__shgo.py +9 -1
  326. scipy/optimize/tests/test_bracket.py +36 -46
  327. scipy/optimize/tests/test_chandrupatla.py +133 -135
  328. scipy/optimize/tests/test_cobyla.py +74 -45
  329. scipy/optimize/tests/test_constraints.py +1 -1
  330. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  331. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  332. scipy/optimize/tests/test_least_squares.py +125 -13
  333. scipy/optimize/tests/test_linear_assignment.py +3 -3
  334. scipy/optimize/tests/test_linprog.py +3 -3
  335. scipy/optimize/tests/test_lsq_linear.py +6 -6
  336. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  337. scipy/optimize/tests/test_minpack.py +4 -4
  338. scipy/optimize/tests/test_nnls.py +43 -3
  339. scipy/optimize/tests/test_nonlin.py +36 -0
  340. scipy/optimize/tests/test_optimize.py +95 -17
  341. scipy/optimize/tests/test_slsqp.py +36 -4
  342. scipy/optimize/tests/test_zeros.py +34 -1
  343. scipy/signal/__init__.py +12 -23
  344. scipy/signal/_delegators.py +568 -0
  345. scipy/signal/_filter_design.py +459 -241
  346. scipy/signal/_fir_filter_design.py +262 -90
  347. scipy/signal/_lti_conversion.py +3 -2
  348. scipy/signal/_ltisys.py +118 -91
  349. scipy/signal/_max_len_seq_inner.cpython-312-aarch64-linux-musl.so +0 -0
  350. scipy/signal/_peak_finding_utils.cpython-312-aarch64-linux-musl.so +0 -0
  351. scipy/signal/_polyutils.py +172 -0
  352. scipy/signal/_short_time_fft.py +519 -70
  353. scipy/signal/_signal_api.py +30 -0
  354. scipy/signal/_signaltools.py +719 -399
  355. scipy/signal/_sigtools.cpython-312-aarch64-linux-musl.so +0 -0
  356. scipy/signal/_sosfilt.cpython-312-aarch64-linux-musl.so +0 -0
  357. scipy/signal/_spectral_py.py +230 -50
  358. scipy/signal/_spline.cpython-312-aarch64-linux-musl.so +0 -0
  359. scipy/signal/_spline_filters.py +108 -68
  360. scipy/signal/_support_alternative_backends.py +73 -0
  361. scipy/signal/_upfirdn.py +4 -1
  362. scipy/signal/_upfirdn_apply.cpython-312-aarch64-linux-musl.so +0 -0
  363. scipy/signal/_waveforms.py +2 -11
  364. scipy/signal/_wavelets.py +1 -1
  365. scipy/signal/fir_filter_design.py +1 -0
  366. scipy/signal/spline.py +4 -11
  367. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  368. scipy/signal/tests/test_bsplines.py +114 -79
  369. scipy/signal/tests/test_cont2discrete.py +9 -2
  370. scipy/signal/tests/test_filter_design.py +721 -481
  371. scipy/signal/tests/test_fir_filter_design.py +332 -140
  372. scipy/signal/tests/test_savitzky_golay.py +4 -3
  373. scipy/signal/tests/test_short_time_fft.py +221 -3
  374. scipy/signal/tests/test_signaltools.py +2144 -1348
  375. scipy/signal/tests/test_spectral.py +50 -6
  376. scipy/signal/tests/test_splines.py +161 -96
  377. scipy/signal/tests/test_upfirdn.py +84 -50
  378. scipy/signal/tests/test_waveforms.py +20 -0
  379. scipy/signal/tests/test_windows.py +607 -466
  380. scipy/signal/windows/_windows.py +287 -148
  381. scipy/sparse/__init__.py +23 -4
  382. scipy/sparse/_base.py +270 -108
  383. scipy/sparse/_bsr.py +7 -4
  384. scipy/sparse/_compressed.py +59 -231
  385. scipy/sparse/_construct.py +90 -38
  386. scipy/sparse/_coo.py +115 -181
  387. scipy/sparse/_csc.py +4 -4
  388. scipy/sparse/_csparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  389. scipy/sparse/_csr.py +2 -2
  390. scipy/sparse/_data.py +48 -48
  391. scipy/sparse/_dia.py +105 -18
  392. scipy/sparse/_dok.py +0 -23
  393. scipy/sparse/_index.py +4 -4
  394. scipy/sparse/_matrix.py +23 -0
  395. scipy/sparse/_sparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  396. scipy/sparse/_sputils.py +37 -22
  397. scipy/sparse/base.py +0 -9
  398. scipy/sparse/bsr.py +0 -14
  399. scipy/sparse/compressed.py +0 -23
  400. scipy/sparse/construct.py +0 -6
  401. scipy/sparse/coo.py +0 -14
  402. scipy/sparse/csc.py +0 -3
  403. scipy/sparse/csgraph/_flow.cpython-312-aarch64-linux-musl.so +0 -0
  404. scipy/sparse/csgraph/_matching.cpython-312-aarch64-linux-musl.so +0 -0
  405. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-aarch64-linux-musl.so +0 -0
  406. scipy/sparse/csgraph/_reordering.cpython-312-aarch64-linux-musl.so +0 -0
  407. scipy/sparse/csgraph/_shortest_path.cpython-312-aarch64-linux-musl.so +0 -0
  408. scipy/sparse/csgraph/_tools.cpython-312-aarch64-linux-musl.so +0 -0
  409. scipy/sparse/csgraph/_traversal.cpython-312-aarch64-linux-musl.so +0 -0
  410. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  411. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  412. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  413. scipy/sparse/csr.py +0 -5
  414. scipy/sparse/data.py +1 -6
  415. scipy/sparse/dia.py +0 -7
  416. scipy/sparse/dok.py +0 -10
  417. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-aarch64-linux-musl.so +0 -0
  418. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  419. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  420. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-aarch64-linux-musl.so +0 -0
  421. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  422. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  423. scipy/sparse/linalg/_interface.py +17 -18
  424. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  425. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  426. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  427. scipy/sparse/linalg/_isolve/minres.py +5 -5
  428. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  429. scipy/sparse/linalg/_isolve/utils.py +2 -8
  430. scipy/sparse/linalg/_matfuncs.py +1 -1
  431. scipy/sparse/linalg/_norm.py +1 -1
  432. scipy/sparse/linalg/_propack/_cpropack.cpython-312-aarch64-linux-musl.so +0 -0
  433. scipy/sparse/linalg/_propack/_dpropack.cpython-312-aarch64-linux-musl.so +0 -0
  434. scipy/sparse/linalg/_propack/_spropack.cpython-312-aarch64-linux-musl.so +0 -0
  435. scipy/sparse/linalg/_propack/_zpropack.cpython-312-aarch64-linux-musl.so +0 -0
  436. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  437. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  438. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  439. scipy/sparse/tests/test_base.py +214 -42
  440. scipy/sparse/tests/test_common1d.py +7 -7
  441. scipy/sparse/tests/test_construct.py +1 -1
  442. scipy/sparse/tests/test_coo.py +272 -4
  443. scipy/sparse/tests/test_sparsetools.py +5 -0
  444. scipy/sparse/tests/test_sputils.py +36 -7
  445. scipy/spatial/_ckdtree.cpython-312-aarch64-linux-musl.so +0 -0
  446. scipy/spatial/_distance_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  447. scipy/spatial/_distance_wrap.cpython-312-aarch64-linux-musl.so +0 -0
  448. scipy/spatial/_hausdorff.cpython-312-aarch64-linux-musl.so +0 -0
  449. scipy/spatial/_qhull.cpython-312-aarch64-linux-musl.so +0 -0
  450. scipy/spatial/_voronoi.cpython-312-aarch64-linux-musl.so +0 -0
  451. scipy/spatial/distance.py +49 -42
  452. scipy/spatial/tests/test_distance.py +15 -1
  453. scipy/spatial/tests/test_kdtree.py +1 -0
  454. scipy/spatial/tests/test_qhull.py +7 -2
  455. scipy/spatial/transform/__init__.py +5 -3
  456. scipy/spatial/transform/_rigid_transform.cpython-312-aarch64-linux-musl.so +0 -0
  457. scipy/spatial/transform/_rotation.cpython-312-aarch64-linux-musl.so +0 -0
  458. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  459. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  460. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  461. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  462. scipy/special/__init__.py +1 -47
  463. scipy/special/_add_newdocs.py +34 -772
  464. scipy/special/_basic.py +22 -25
  465. scipy/special/_comb.cpython-312-aarch64-linux-musl.so +0 -0
  466. scipy/special/_ellip_harm_2.cpython-312-aarch64-linux-musl.so +0 -0
  467. scipy/special/_gufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  468. scipy/special/_logsumexp.py +67 -58
  469. scipy/special/_orthogonal.pyi +1 -1
  470. scipy/special/_specfun.cpython-312-aarch64-linux-musl.so +0 -0
  471. scipy/special/_special_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  472. scipy/special/_spherical_bessel.py +4 -4
  473. scipy/special/_support_alternative_backends.py +212 -119
  474. scipy/special/_test_internal.cpython-312-aarch64-linux-musl.so +0 -0
  475. scipy/special/_testutils.py +4 -4
  476. scipy/special/_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  477. scipy/special/_ufuncs.pyi +1 -0
  478. scipy/special/_ufuncs.pyx +215 -1400
  479. scipy/special/_ufuncs_cxx.cpython-312-aarch64-linux-musl.so +0 -0
  480. scipy/special/_ufuncs_cxx.pxd +2 -15
  481. scipy/special/_ufuncs_cxx.pyx +5 -44
  482. scipy/special/_ufuncs_cxx_defs.h +2 -16
  483. scipy/special/_ufuncs_defs.h +0 -8
  484. scipy/special/cython_special.cpython-312-aarch64-linux-musl.so +0 -0
  485. scipy/special/cython_special.pxd +1 -1
  486. scipy/special/tests/_cython_examples/meson.build +10 -1
  487. scipy/special/tests/test_basic.py +153 -20
  488. scipy/special/tests/test_boost_ufuncs.py +3 -0
  489. scipy/special/tests/test_cdflib.py +35 -11
  490. scipy/special/tests/test_gammainc.py +16 -0
  491. scipy/special/tests/test_hyp2f1.py +2 -2
  492. scipy/special/tests/test_log1mexp.py +85 -0
  493. scipy/special/tests/test_logsumexp.py +206 -64
  494. scipy/special/tests/test_mpmath.py +1 -0
  495. scipy/special/tests/test_nan_inputs.py +1 -1
  496. scipy/special/tests/test_orthogonal.py +17 -18
  497. scipy/special/tests/test_sf_error.py +3 -2
  498. scipy/special/tests/test_sph_harm.py +6 -7
  499. scipy/special/tests/test_support_alternative_backends.py +211 -76
  500. scipy/stats/__init__.py +4 -1
  501. scipy/stats/_ansari_swilk_statistics.cpython-312-aarch64-linux-musl.so +0 -0
  502. scipy/stats/_axis_nan_policy.py +5 -12
  503. scipy/stats/_biasedurn.cpython-312-aarch64-linux-musl.so +0 -0
  504. scipy/stats/_continued_fraction.py +387 -0
  505. scipy/stats/_continuous_distns.py +277 -310
  506. scipy/stats/_correlation.py +1 -1
  507. scipy/stats/_covariance.py +6 -3
  508. scipy/stats/_discrete_distns.py +39 -32
  509. scipy/stats/_distn_infrastructure.py +39 -12
  510. scipy/stats/_distribution_infrastructure.py +900 -238
  511. scipy/stats/_entropy.py +9 -10
  512. scipy/{_lib → stats}/_finite_differences.py +1 -1
  513. scipy/stats/_hypotests.py +83 -50
  514. scipy/stats/_kde.py +53 -49
  515. scipy/stats/_ksstats.py +1 -1
  516. scipy/stats/_levy_stable/__init__.py +7 -15
  517. scipy/stats/_levy_stable/levyst.cpython-312-aarch64-linux-musl.so +0 -0
  518. scipy/stats/_morestats.py +118 -73
  519. scipy/stats/_mstats_basic.py +13 -17
  520. scipy/stats/_mstats_extras.py +8 -8
  521. scipy/stats/_multivariate.py +89 -113
  522. scipy/stats/_new_distributions.py +97 -20
  523. scipy/stats/_page_trend_test.py +12 -5
  524. scipy/stats/_probability_distribution.py +265 -43
  525. scipy/stats/_qmc.py +14 -9
  526. scipy/stats/_qmc_cy.cpython-312-aarch64-linux-musl.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-312-aarch64-linux-musl.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-312-aarch64-linux-musl.so +0 -0
  531. scipy/stats/_resampling.py +4 -29
  532. scipy/stats/_sampling.py +1 -1
  533. scipy/stats/_sobol.cpython-312-aarch64-linux-musl.so +0 -0
  534. scipy/stats/_stats.cpython-312-aarch64-linux-musl.so +0 -0
  535. scipy/stats/_stats_mstats_common.py +21 -2
  536. scipy/stats/_stats_py.py +550 -476
  537. scipy/stats/_stats_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-312-aarch64-linux-musl.so +0 -0
  539. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  540. scipy/stats/_variation.py +6 -8
  541. scipy/stats/_wilcoxon.py +13 -7
  542. scipy/stats/tests/common_tests.py +6 -4
  543. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  544. scipy/stats/tests/test_continued_fraction.py +173 -0
  545. scipy/stats/tests/test_continuous.py +379 -60
  546. scipy/stats/tests/test_continuous_basic.py +18 -12
  547. scipy/stats/tests/test_discrete_basic.py +14 -8
  548. scipy/stats/tests/test_discrete_distns.py +16 -16
  549. scipy/stats/tests/test_distributions.py +95 -75
  550. scipy/stats/tests/test_entropy.py +40 -48
  551. scipy/stats/tests/test_fit.py +4 -3
  552. scipy/stats/tests/test_hypotests.py +153 -24
  553. scipy/stats/tests/test_kdeoth.py +109 -41
  554. scipy/stats/tests/test_marray.py +289 -0
  555. scipy/stats/tests/test_morestats.py +79 -47
  556. scipy/stats/tests/test_mstats_basic.py +3 -3
  557. scipy/stats/tests/test_multivariate.py +434 -83
  558. scipy/stats/tests/test_qmc.py +13 -10
  559. scipy/stats/tests/test_quantile.py +199 -0
  560. scipy/stats/tests/test_rank.py +119 -112
  561. scipy/stats/tests/test_resampling.py +47 -56
  562. scipy/stats/tests/test_sampling.py +9 -4
  563. scipy/stats/tests/test_stats.py +799 -939
  564. scipy/stats/tests/test_variation.py +8 -6
  565. scipy/version.py +2 -2
  566. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  567. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  568. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +1262 -1269
  569. scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
  570. scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
  571. scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
  572. scipy/_lib/array_api_extra/_funcs.py +0 -484
  573. scipy/_lib/array_api_extra/_typing.py +0 -8
  574. scipy/interpolate/_bspl.cpython-312-aarch64-linux-musl.so +0 -0
  575. scipy/optimize/_cobyla.cpython-312-aarch64-linux-musl.so +0 -0
  576. scipy/optimize/_cython_nnls.cpython-312-aarch64-linux-musl.so +0 -0
  577. scipy/optimize/_slsqp.cpython-312-aarch64-linux-musl.so +0 -0
  578. scipy/spatial/qhull_src/COPYING.txt +0 -38
  579. scipy/special/libsf_error_state.so +0 -0
  580. scipy/special/tests/test_log_softmax.py +0 -109
  581. scipy/special/tests/test_xsf_cuda.py +0 -114
  582. scipy/special/xsf/binom.h +0 -89
  583. scipy/special/xsf/cdflib.h +0 -100
  584. scipy/special/xsf/cephes/airy.h +0 -307
  585. scipy/special/xsf/cephes/besselpoly.h +0 -51
  586. scipy/special/xsf/cephes/beta.h +0 -257
  587. scipy/special/xsf/cephes/cbrt.h +0 -131
  588. scipy/special/xsf/cephes/chbevl.h +0 -85
  589. scipy/special/xsf/cephes/chdtr.h +0 -193
  590. scipy/special/xsf/cephes/const.h +0 -87
  591. scipy/special/xsf/cephes/ellie.h +0 -293
  592. scipy/special/xsf/cephes/ellik.h +0 -251
  593. scipy/special/xsf/cephes/ellpe.h +0 -107
  594. scipy/special/xsf/cephes/ellpk.h +0 -117
  595. scipy/special/xsf/cephes/expn.h +0 -260
  596. scipy/special/xsf/cephes/gamma.h +0 -398
  597. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  598. scipy/special/xsf/cephes/hyperg.h +0 -361
  599. scipy/special/xsf/cephes/i0.h +0 -149
  600. scipy/special/xsf/cephes/i1.h +0 -158
  601. scipy/special/xsf/cephes/igam.h +0 -421
  602. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  603. scipy/special/xsf/cephes/igami.h +0 -313
  604. scipy/special/xsf/cephes/j0.h +0 -225
  605. scipy/special/xsf/cephes/j1.h +0 -198
  606. scipy/special/xsf/cephes/jv.h +0 -715
  607. scipy/special/xsf/cephes/k0.h +0 -164
  608. scipy/special/xsf/cephes/k1.h +0 -163
  609. scipy/special/xsf/cephes/kn.h +0 -243
  610. scipy/special/xsf/cephes/lanczos.h +0 -112
  611. scipy/special/xsf/cephes/ndtr.h +0 -275
  612. scipy/special/xsf/cephes/poch.h +0 -85
  613. scipy/special/xsf/cephes/polevl.h +0 -167
  614. scipy/special/xsf/cephes/psi.h +0 -194
  615. scipy/special/xsf/cephes/rgamma.h +0 -111
  616. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  617. scipy/special/xsf/cephes/shichi.h +0 -248
  618. scipy/special/xsf/cephes/sici.h +0 -224
  619. scipy/special/xsf/cephes/sindg.h +0 -221
  620. scipy/special/xsf/cephes/tandg.h +0 -139
  621. scipy/special/xsf/cephes/trig.h +0 -58
  622. scipy/special/xsf/cephes/unity.h +0 -186
  623. scipy/special/xsf/cephes/zeta.h +0 -172
  624. scipy/special/xsf/config.h +0 -304
  625. scipy/special/xsf/digamma.h +0 -205
  626. scipy/special/xsf/error.h +0 -57
  627. scipy/special/xsf/evalpoly.h +0 -47
  628. scipy/special/xsf/expint.h +0 -266
  629. scipy/special/xsf/hyp2f1.h +0 -694
  630. scipy/special/xsf/iv_ratio.h +0 -173
  631. scipy/special/xsf/lambertw.h +0 -150
  632. scipy/special/xsf/loggamma.h +0 -163
  633. scipy/special/xsf/sici.h +0 -200
  634. scipy/special/xsf/tools.h +0 -427
  635. scipy/special/xsf/trig.h +0 -164
  636. scipy/special/xsf/wright_bessel.h +0 -843
  637. scipy/special/xsf/zlog1.h +0 -35
  638. scipy/stats/_mvn.cpython-312-aarch64-linux-musl.so +0 -0
  639. scipy.libs/libgcc_s-7393e603.so.1 +0 -0
  640. scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
  641. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
@@ -6,13 +6,13 @@ import numpy as np
6
6
 
7
7
  from scipy import stats
8
8
  from scipy.stats import norm, expon # type: ignore[attr-defined]
9
- from scipy.conftest import array_api_compatible
10
- from scipy._lib._array_api import array_namespace, is_array_api_strict, is_jax
11
9
  from scipy._lib._array_api_no_0d import (xp_assert_close, xp_assert_equal,
12
10
  xp_assert_less)
13
11
 
12
+ skip_xp_backends = pytest.mark.skip_xp_backends
13
+
14
+ @pytest.mark.skip_xp_backends("dask.array", reason="boolean index assignment")
14
15
  class TestEntropy:
15
- @array_api_compatible
16
16
  def test_entropy_positive(self, xp):
17
17
  # See ticket #497
18
18
  pk = xp.asarray([0.5, 0.2, 0.3])
@@ -22,33 +22,29 @@ class TestEntropy:
22
22
  xp_assert_equal(eself, xp.asarray(0.))
23
23
  xp_assert_less(-edouble, xp.asarray(0.))
24
24
 
25
- @array_api_compatible
26
25
  def test_entropy_base(self, xp):
27
26
  pk = xp.ones(16)
28
27
  S = stats.entropy(pk, base=2.)
29
28
  xp_assert_less(xp.abs(S - 4.), xp.asarray(1.e-5))
30
29
 
31
30
  qk = xp.ones(16)
32
- qk = xp.where(xp.arange(16) < 8, xp.asarray(2.), qk)
31
+ qk = xp.where(xp.arange(16) < 8, 2., qk)
33
32
  S = stats.entropy(pk, qk)
34
33
  S2 = stats.entropy(pk, qk, base=2.)
35
34
  xp_assert_less(xp.abs(S/S2 - math.log(2.)), xp.asarray(1.e-5))
36
35
 
37
- @array_api_compatible
38
36
  def test_entropy_zero(self, xp):
39
37
  # Test for PR-479
40
38
  x = xp.asarray([0., 1., 2.])
41
39
  xp_assert_close(stats.entropy(x),
42
40
  xp.asarray(0.63651416829481278))
43
41
 
44
- @array_api_compatible
45
42
  def test_entropy_2d(self, xp):
46
43
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
47
44
  qk = xp.asarray([[0.2, 0.1], [0.3, 0.6], [0.5, 0.3]])
48
45
  xp_assert_close(stats.entropy(pk, qk),
49
46
  xp.asarray([0.1933259, 0.18609809]))
50
47
 
51
- @array_api_compatible
52
48
  def test_entropy_2d_zero(self, xp):
53
49
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
54
50
  qk = xp.asarray([[0.0, 0.1], [0.3, 0.6], [0.5, 0.3]])
@@ -59,20 +55,17 @@ class TestEntropy:
59
55
  xp_assert_close(stats.entropy(pk, qk),
60
56
  xp.asarray([0.17403988, 0.18609809]))
61
57
 
62
- @array_api_compatible
63
58
  def test_entropy_base_2d_nondefault_axis(self, xp):
64
59
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
65
60
  xp_assert_close(stats.entropy(pk, axis=1),
66
61
  xp.asarray([0.63651417, 0.63651417, 0.66156324]))
67
62
 
68
- @array_api_compatible
69
63
  def test_entropy_2d_nondefault_axis(self, xp):
70
64
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
71
65
  qk = xp.asarray([[0.2, 0.1], [0.3, 0.6], [0.5, 0.3]])
72
66
  xp_assert_close(stats.entropy(pk, qk, axis=1),
73
67
  xp.asarray([0.23104906, 0.23104906, 0.12770641]))
74
68
 
75
- @array_api_compatible
76
69
  def test_entropy_raises_value_error(self, xp):
77
70
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
78
71
  qk = xp.asarray([[0.1, 0.2], [0.6, 0.3]])
@@ -80,33 +73,28 @@ class TestEntropy:
80
73
  with pytest.raises(ValueError, match=message):
81
74
  stats.entropy(pk, qk)
82
75
 
83
- @array_api_compatible
84
76
  def test_base_entropy_with_axis_0_is_equal_to_default(self, xp):
85
77
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
86
78
  xp_assert_close(stats.entropy(pk, axis=0),
87
79
  stats.entropy(pk))
88
80
 
89
- @array_api_compatible
90
81
  def test_entropy_with_axis_0_is_equal_to_default(self, xp):
91
82
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
92
83
  qk = xp.asarray([[0.2, 0.1], [0.3, 0.6], [0.5, 0.3]])
93
84
  xp_assert_close(stats.entropy(pk, qk, axis=0),
94
85
  stats.entropy(pk, qk))
95
86
 
96
- @array_api_compatible
97
87
  def test_base_entropy_transposed(self, xp):
98
88
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
99
89
  xp_assert_close(stats.entropy(pk.T),
100
90
  stats.entropy(pk, axis=1))
101
91
 
102
- @array_api_compatible
103
92
  def test_entropy_transposed(self, xp):
104
93
  pk = xp.asarray([[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]])
105
94
  qk = xp.asarray([[0.2, 0.1], [0.3, 0.6], [0.5, 0.3]])
106
95
  xp_assert_close(stats.entropy(pk.T, qk.T),
107
96
  stats.entropy(pk, qk, axis=1))
108
97
 
109
- @array_api_compatible
110
98
  def test_entropy_broadcasting(self, xp):
111
99
  rng = np.random.default_rng(74187315492831452)
112
100
  x = xp.asarray(rng.random(3))
@@ -115,7 +103,6 @@ class TestEntropy:
115
103
  xp_assert_equal(res[0], stats.entropy(x, y[0, ...]))
116
104
  xp_assert_equal(res[1], stats.entropy(x, y[1, ...]))
117
105
 
118
- @array_api_compatible
119
106
  def test_entropy_shape_mismatch(self, xp):
120
107
  x = xp.ones((10, 1, 12))
121
108
  y = xp.ones((11, 2))
@@ -123,7 +110,6 @@ class TestEntropy:
123
110
  with pytest.raises(ValueError, match=message):
124
111
  stats.entropy(x, y)
125
112
 
126
- @array_api_compatible
127
113
  def test_input_validation(self, xp):
128
114
  x = xp.ones(10)
129
115
  message = "`base` must be a positive number."
@@ -131,8 +117,7 @@ class TestEntropy:
131
117
  stats.entropy(x, base=-2)
132
118
 
133
119
 
134
- @array_api_compatible
135
- @pytest.mark.usefixtures("skip_xp_backends")
120
+ @pytest.mark.skip_xp_backends("dask.array", reason="boolean index assignment")
136
121
  class TestDifferentialEntropy:
137
122
  """
138
123
  Vasicek results are compared with the R package vsgoftest.
@@ -207,8 +192,6 @@ class TestDifferentialEntropy:
207
192
  axis=1,
208
193
  )
209
194
 
210
- @pytest.mark.skip_xp_backends('jax.numpy',
211
- reason="JAX doesn't support item assignment")
212
195
  def test_base_differential_entropy_with_axis_0_is_equal_to_default(self, xp):
213
196
  random_state = np.random.RandomState(0)
214
197
  values = random_state.standard_normal((100, 3))
@@ -218,8 +201,6 @@ class TestDifferentialEntropy:
218
201
  default_entropy = stats.differential_entropy(values)
219
202
  xp_assert_close(entropy, default_entropy)
220
203
 
221
- @pytest.mark.skip_xp_backends('jax.numpy',
222
- reason="JAX doesn't support item assignment")
223
204
  def test_base_differential_entropy_transposed(self, xp):
224
205
  random_state = np.random.RandomState(0)
225
206
  values = random_state.standard_normal((3, 100))
@@ -242,13 +223,17 @@ class TestDifferentialEntropy:
242
223
  with pytest.raises(ValueError, match=message):
243
224
  stats.differential_entropy(x, method='ekki-ekki')
244
225
 
245
- @pytest.mark.parametrize('method', ['vasicek', 'van es',
246
- 'ebrahimi', 'correa'])
226
+ @pytest.mark.parametrize('method', [
227
+ 'vasicek',
228
+ 'van es',
229
+ 'ebrahimi',
230
+ pytest.param(
231
+ 'correa',
232
+ marks=skip_xp_backends("array_api_strict",
233
+ reason="Needs fancy indexing.")
234
+ )
235
+ ])
247
236
  def test_consistency(self, method, xp):
248
- if is_jax(xp) and method == 'ebrahimi':
249
- pytest.xfail("Needs array assignment.")
250
- elif is_array_api_strict(xp) and method == 'correa':
251
- pytest.xfail("Needs fancy indexing.")
252
237
  # test that method is a consistent estimator
253
238
  n = 10000 if method == 'correa' else 1000000
254
239
  rvs = stats.norm.rvs(size=n, random_state=0)
@@ -276,17 +261,21 @@ class TestDifferentialEntropy:
276
261
  rmse_std_cases = {norm: norm_rmse_std_cases,
277
262
  expon: expon_rmse_std_cases}
278
263
 
279
- @pytest.mark.parametrize('method', ['vasicek', 'van es', 'ebrahimi', 'correa'])
264
+ @pytest.mark.parametrize('method', [
265
+ 'vasicek',
266
+ 'van es',
267
+ 'ebrahimi',
268
+ pytest.param(
269
+ 'correa',
270
+ marks=skip_xp_backends("array_api_strict",
271
+ reason="Needs fancy indexing.")
272
+ )
273
+ ])
280
274
  @pytest.mark.parametrize('dist', [norm, expon])
281
275
  def test_rmse_std(self, method, dist, xp):
282
276
  # test that RMSE and standard deviation of estimators matches values
283
277
  # given in differential_entropy reference [6]. Incidentally, also
284
278
  # tests vectorization.
285
- if is_jax(xp) and method == 'ebrahimi':
286
- pytest.xfail("Needs array assignment.")
287
- elif is_array_api_strict(xp) and method == 'correa':
288
- pytest.xfail("Needs fancy indexing.")
289
-
290
279
  reps, n, m = 10000, 50, 7
291
280
  expected = self.rmse_std_cases[dist][method]
292
281
  rmse_expected, std_expected = xp.asarray(expected[0]), xp.asarray(expected[1])
@@ -297,31 +286,34 @@ class TestDifferentialEntropy:
297
286
  method=method, axis=-1)
298
287
  xp_assert_close(xp.sqrt(xp.mean((res - true_entropy)**2)),
299
288
  rmse_expected, atol=0.005)
300
- xp_test = array_namespace(res)
301
- xp_assert_close(xp_test.std(res, correction=0), std_expected, atol=0.002)
289
+ xp_assert_close(xp.std(res, correction=0), std_expected, atol=0.002)
302
290
 
303
- @pytest.mark.parametrize('n, method', [(8, 'van es'),
304
- (12, 'ebrahimi'),
305
- (1001, 'vasicek')])
291
+ @pytest.mark.parametrize('n, method', [
292
+ (8, 'van es'),
293
+ (12, 'ebrahimi'),
294
+ (1001, 'vasicek')
295
+ ])
306
296
  def test_method_auto(self, n, method, xp):
307
- if is_jax(xp) and method == 'ebrahimi':
308
- pytest.xfail("Needs array assignment.")
309
297
  rvs = stats.norm.rvs(size=(n,), random_state=0)
310
298
  rvs = xp.asarray(rvs.tolist())
311
299
  res1 = stats.differential_entropy(rvs)
312
300
  res2 = stats.differential_entropy(rvs, method=method)
313
301
  xp_assert_equal(res1, res2)
314
302
 
315
- @pytest.mark.skip_xp_backends('jax.numpy',
316
- reason="JAX doesn't support item assignment")
317
- @pytest.mark.parametrize('method', ["vasicek", "van es", "correa", "ebrahimi"])
303
+ @pytest.mark.parametrize('method', [
304
+ "vasicek",
305
+ "van es",
306
+ pytest.param(
307
+ "correa",
308
+ marks=skip_xp_backends("array_api_strict", reason="Needs fancy indexing.")
309
+ ),
310
+ "ebrahimi"
311
+ ])
318
312
  @pytest.mark.parametrize('dtype', [None, 'float32', 'float64'])
319
313
  def test_dtypes_gh21192(self, xp, method, dtype):
320
314
  # gh-21192 noted a change in the output of method='ebrahimi'
321
315
  # with integer input. Check that the output is consistent regardless
322
316
  # of input dtype.
323
- if is_array_api_strict(xp) and method == 'correa':
324
- pytest.xfail("Needs fancy indexing.")
325
317
  x = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11]
326
318
  dtype_in = getattr(xp, str(dtype), None)
327
319
  dtype_out = getattr(xp, str(dtype), xp.asarray(1.).dtype)
@@ -42,7 +42,8 @@ mle_failing_fits = [
42
42
 
43
43
  # these pass but are XSLOW (>1s)
44
44
  mle_Xslow_fits = ['betaprime', 'crystalball', 'exponweib', 'f', 'geninvgauss',
45
- 'jf_skew_t', 'recipinvgauss', 'rel_breitwigner', 'vonmises_line']
45
+ 'jf_skew_t', 'nct', 'recipinvgauss', 'rel_breitwigner',
46
+ 'vonmises_line']
46
47
 
47
48
  # The MLE fit method of these distributions doesn't perform well when all
48
49
  # parameters are fit, so test them with the location fixed at 0.
@@ -129,10 +130,10 @@ def test_cont_fit(distname, arg, method):
129
130
 
130
131
  for fit_size in fit_sizes:
131
132
  # Note that if a fit succeeds, the other fit_sizes are skipped
132
- np.random.seed(1234)
133
+ rng = np.random.default_rng(1234)
133
134
 
134
135
  with np.errstate(all='ignore'):
135
- rvs = distfn.rvs(size=fit_size, *arg)
136
+ rvs = distfn.rvs(size=fit_size, *arg, random_state=rng)
136
137
  if method == 'MLE' and distfn.name in mle_use_floc0:
137
138
  kwds = {'floc': 0}
138
139
  else:
@@ -202,12 +202,12 @@ class TestMannWhitneyU:
202
202
  def test_auto(self):
203
203
  # Test that default method ('auto') chooses intended method
204
204
 
205
- np.random.seed(1)
205
+ rng = np.random.RandomState(1)
206
206
  n = 8 # threshold to switch from exact to asymptotic
207
207
 
208
208
  # both inputs are smaller than threshold; should use exact
209
- x = np.random.rand(n-1)
210
- y = np.random.rand(n-1)
209
+ x = rng.rand(n-1)
210
+ y = rng.rand(n-1)
211
211
  auto = mannwhitneyu(x, y)
212
212
  asymptotic = mannwhitneyu(x, y, method='asymptotic')
213
213
  exact = mannwhitneyu(x, y, method='exact')
@@ -215,8 +215,8 @@ class TestMannWhitneyU:
215
215
  assert auto.pvalue != asymptotic.pvalue
216
216
 
217
217
  # one input is smaller than threshold; should use exact
218
- x = np.random.rand(n-1)
219
- y = np.random.rand(n+1)
218
+ x = rng.rand(n-1)
219
+ y = rng.rand(n+1)
220
220
  auto = mannwhitneyu(x, y)
221
221
  asymptotic = mannwhitneyu(x, y, method='asymptotic')
222
222
  exact = mannwhitneyu(x, y, method='exact')
@@ -231,8 +231,8 @@ class TestMannWhitneyU:
231
231
  assert auto.pvalue != asymptotic.pvalue
232
232
 
233
233
  # both inputs are larger than threshold; should use asymptotic
234
- x = np.random.rand(n+1)
235
- y = np.random.rand(n+1)
234
+ x = rng.rand(n+1)
235
+ y = rng.rand(n+1)
236
236
  auto = mannwhitneyu(x, y)
237
237
  asymptotic = mannwhitneyu(x, y, method='asymptotic')
238
238
  exact = mannwhitneyu(x, y, method='exact')
@@ -241,8 +241,8 @@ class TestMannWhitneyU:
241
241
 
242
242
  # both inputs are smaller than threshold, but there is a tie
243
243
  # should use asymptotic
244
- x = np.random.rand(n-1)
245
- y = np.random.rand(n-1)
244
+ x = rng.rand(n-1)
245
+ y = rng.rand(n-1)
246
246
  y[3] = x[3]
247
247
  auto = mannwhitneyu(x, y)
248
248
  asymptotic = mannwhitneyu(x, y, method='asymptotic')
@@ -394,19 +394,19 @@ class TestMannWhitneyU:
394
394
  assert_allclose(pmf, pmf2)
395
395
 
396
396
  def test_asymptotic_behavior(self):
397
- np.random.seed(0)
397
+ rng = np.random.default_rng(12543)
398
398
 
399
399
  # for small samples, the asymptotic test is not very accurate
400
- x = np.random.rand(5)
401
- y = np.random.rand(5)
400
+ x = rng.random(5)
401
+ y = rng.random(5)
402
402
  res1 = mannwhitneyu(x, y, method="exact")
403
403
  res2 = mannwhitneyu(x, y, method="asymptotic")
404
404
  assert res1.statistic == res2.statistic
405
405
  assert np.abs(res1.pvalue - res2.pvalue) > 1e-2
406
406
 
407
407
  # for large samples, they agree reasonably well
408
- x = np.random.rand(40)
409
- y = np.random.rand(40)
408
+ x = rng.random(40)
409
+ y = rng.random(40)
410
410
  res1 = mannwhitneyu(x, y, method="exact")
411
411
  res2 = mannwhitneyu(x, y, method="asymptotic")
412
412
  assert res1.statistic == res2.statistic
@@ -860,8 +860,9 @@ class TestSomersD(_TestPythranFunc):
860
860
  shape = 4, 6
861
861
  size = np.prod(shape)
862
862
 
863
- np.random.seed(0)
864
- s = stats.multinomial.rvs(N, p=np.ones(size)/size).reshape(shape)
863
+ rng = np.random.RandomState(0)
864
+ s = stats.multinomial.rvs(N, p=np.ones(size)/size,
865
+ random_state=rng).reshape(shape)
865
866
  res = stats.somersd(s)
866
867
 
867
868
  s2 = np.insert(s, 2, np.zeros(shape[1]), axis=0)
@@ -889,9 +890,10 @@ class TestSomersD(_TestPythranFunc):
889
890
  shape = 4, 6
890
891
  size = np.prod(shape)
891
892
 
892
- np.random.seed(0)
893
+ rng = np.random.default_rng(0)
893
894
  # start with a valid contingency table
894
- s = stats.multinomial.rvs(N, p=np.ones(size)/size).reshape(shape)
895
+ s = stats.multinomial.rvs(N, p=np.ones(size)/size,
896
+ random_state=rng).reshape(shape)
895
897
 
896
898
  s5 = s - 2
897
899
  message = "All elements of the contingency table must be non-negative"
@@ -1003,6 +1005,7 @@ class TestSomersD(_TestPythranFunc):
1003
1005
  assert res.statistic == expected_statistic
1004
1006
  assert res.pvalue == (0 if positive_correlation else 1)
1005
1007
 
1008
+ @pytest.mark.thread_unsafe
1006
1009
  def test_somersd_large_inputs_gh18132(self):
1007
1010
  # Test that large inputs where potential overflows could occur give
1008
1011
  # the expected output. This is tested in the case of binary inputs.
@@ -1375,18 +1378,18 @@ class TestCvm_2samp:
1375
1378
  def test_large_sample(self):
1376
1379
  # for large samples, the statistic U gets very large
1377
1380
  # do a sanity check that p-value is not 0, 1 or nan
1378
- np.random.seed(4367)
1379
- x = distributions.norm.rvs(size=1000000)
1380
- y = distributions.norm.rvs(size=900000)
1381
+ rng = np.random.default_rng(4367)
1382
+ x = distributions.norm.rvs(size=1000000, random_state=rng)
1383
+ y = distributions.norm.rvs(size=900000, random_state=rng)
1381
1384
  r = cramervonmises_2samp(x, y)
1382
1385
  assert_(0 < r.pvalue < 1)
1383
1386
  r = cramervonmises_2samp(x, y+0.1)
1384
1387
  assert_(0 < r.pvalue < 1)
1385
1388
 
1386
1389
  def test_exact_vs_asymptotic(self):
1387
- np.random.seed(0)
1388
- x = np.random.rand(7)
1389
- y = np.random.rand(8)
1390
+ rng = np.random.RandomState(0)
1391
+ x = rng.rand(7)
1392
+ y = rng.rand(8)
1390
1393
  r1 = cramervonmises_2samp(x, y, method='exact')
1391
1394
  r2 = cramervonmises_2samp(x, y, method='asymptotic')
1392
1395
  assert_equal(r1.statistic, r2.statistic)
@@ -1640,6 +1643,11 @@ class TestTukeyHSD:
1640
1643
  with assert_raises(ValueError, match="...must be greater than one"):
1641
1644
  stats.tukey_hsd([], [2, 5], [4, 5, 6])
1642
1645
 
1646
+ def test_equal_var_input_validation(self):
1647
+ msg = "Expected a boolean value for 'equal_var'"
1648
+ with assert_raises(TypeError, match=msg):
1649
+ stats.tukey_hsd([1, 2, 3], [2, 5], [6, 7], equal_var="False")
1650
+
1643
1651
  @pytest.mark.parametrize("nargs", (0, 1))
1644
1652
  def test_not_enough_treatments(self, nargs):
1645
1653
  with assert_raises(ValueError, match="...more than 1 treatment."):
@@ -1659,6 +1667,127 @@ class TestTukeyHSD:
1659
1667
  assert_allclose(res_ttest.pvalue, res_tukey.pvalue[1, 0])
1660
1668
 
1661
1669
 
1670
+ class TestGamesHowell:
1671
+ # data with unequal variances
1672
+ data_same_size = ([24., 23., 31., 51.],
1673
+ [34., 18., 18., 26.],
1674
+ [17., 68., 59., 7.])
1675
+
1676
+ data_diff_size = ([30., 23., 51.],
1677
+ [-81., 71., -27., 63.],
1678
+ [42., 11., 29., 19., 50.],
1679
+ [23., 22., 20., 18., 9.])
1680
+
1681
+ spss_same_size = """
1682
+ Mean Diff Lower Bound Upper Bound Sig
1683
+ 0 - 1 8.25000000 -16.5492749527311 33.0492749527311 0.558733632413559
1684
+ 0 - 2 -5.50000000 -63.6702454316458 52.6702454316458 0.941147750599221
1685
+ 1 - 2 -13.7500000 -74.3174374251372 46.8174374251372 0.682983914946841
1686
+ """
1687
+
1688
+ spss_diff_size = """
1689
+ Mean Diff Lower Bound Upper Bound Sig
1690
+ 0 - 1 28.16666667 -141.985416377670 198.318749711003 0.8727542747886180
1691
+ 0 - 2 4.466666667 -37.2830676783904 46.2164010117237 0.9752628408671710
1692
+ 0 - 3 16.26666667 -35.0933112382470 67.6266445715803 0.4262506151302880
1693
+ 1 - 2 -23.70000000 -195.315617201249 147.915617201249 0.9148950609000590
1694
+ 1 - 3 -11.90000000 -188.105478728519 164.305478728519 0.9861432250093960
1695
+ 2 - 3 11.80000000 -16.2894857524254 39.8894857524254 0.4755344436335670
1696
+ """
1697
+
1698
+ @pytest.mark.xslow
1699
+ @pytest.mark.parametrize("data, res_expect_str",
1700
+ ((data_same_size, spss_same_size),
1701
+ (data_diff_size, spss_diff_size)),
1702
+ ids=["equal size sample",
1703
+ "unequal sample size"])
1704
+ def test_compare_spss(self, data, res_expect_str):
1705
+ """
1706
+ DATA LIST LIST /Group (F1.0) Value (F8.2).
1707
+ BEGIN DATA
1708
+ 0 24
1709
+ 0 23
1710
+ 0 31
1711
+ 0 51
1712
+ 1 34
1713
+ 1 18
1714
+ 1 18
1715
+ 1 26
1716
+ 2 17
1717
+ 2 68
1718
+ 2 59
1719
+ 2 7
1720
+ END DATA.
1721
+
1722
+ ONEWAY Value BY Group
1723
+ /MISSING ANALYSIS
1724
+ /POSTHOC=GH ALPHA(0.05).
1725
+ """
1726
+ res_expect = np.asarray(
1727
+ res_expect_str.replace(" - ", " ").split()[7:],
1728
+ dtype=float).reshape(-1, 6)
1729
+ res_games = stats.tukey_hsd(*data, equal_var=False)
1730
+ conf = res_games.confidence_interval()
1731
+ # loop over the comparisons
1732
+ for i, j, s, l, h, p in res_expect:
1733
+ i, j = int(i), int(j)
1734
+ assert_allclose(res_games.statistic[i, j], s, atol=1e-8)
1735
+ assert_allclose(res_games.pvalue[i, j], p, atol=1e-8)
1736
+ assert_allclose(conf.low[i, j], l, atol=1e-6)
1737
+ assert_allclose(conf.high[i, j], h, atol=1e-5)
1738
+
1739
+ r_same_size = """
1740
+ q value Pr(>|q|)
1741
+ 1 - 0 == 0 -1.5467805948856344 0.55873362851759
1742
+ 2 - 0 == 0 0.4726721776628535 0.94114775035993
1743
+ 2 - 1 == 0 1.246837541297872 0.68298393799782
1744
+ """
1745
+
1746
+ r_diff_size = """
1747
+ q value Pr(>|q|)
1748
+ 1 - 0 == 0 -1.0589317485313876 0.87275427357438
1749
+ 2 - 0 == 0 -0.5716222106144833 0.97526284087419
1750
+ 3 - 0 == 0 -2.6209678382077000 0.42625067714691
1751
+ 2 - 1 == 0 0.8971899898179028 0.91489506061850
1752
+ 3 - 1 == 0 0.4579447210555352 0.98614322544695
1753
+ 3 - 2 == 0 -2.198800177874794 0.47553444364614
1754
+ """
1755
+
1756
+ @pytest.mark.parametrize("data, res_expect_str",
1757
+ ((data_same_size, r_same_size),
1758
+ (data_diff_size, r_diff_size)),
1759
+ ids=["equal size sample",
1760
+ "unequal sample size"])
1761
+ def test_compare_r(self, data, res_expect_str):
1762
+ """
1763
+ games-howell is provided by PMCMRplus package
1764
+ https://search.r-project.org/CRAN/refmans/PMCMRplus/html/gamesHowellTest.html
1765
+ > library("PMCMRplus")
1766
+ > options(digits=16)
1767
+ > table = data.frame(
1768
+ values = c(24., 23., 31., 51., 34., 18., 18., 26., 17., 68., 59., 7.),
1769
+ groups = c("0", "0", "0", "0", "1", "1", "1", "1", "2", "2", "2", "2")
1770
+ )
1771
+ > table$groups = as.factor(table$groups)
1772
+ > fit <-aov(values ~ groups, table)
1773
+ > res = gamesHowellTest(fit)
1774
+ > summary(res)
1775
+ """
1776
+ res_expect = np.asarray(
1777
+ res_expect_str.replace(" - ", " ")
1778
+ .replace(" == ", " ").split()[3:],
1779
+ dtype=float).reshape(-1, 5)
1780
+ res_games = stats.tukey_hsd(*data, equal_var=False)
1781
+ # loop over the comparisons
1782
+ # note confidence intervals are not provided by PMCMRplus
1783
+ for j, i, _, _, p in res_expect:
1784
+ i, j = int(i), int(j)
1785
+ assert_allclose(res_games.pvalue[i, j], p, atol=1e-7)
1786
+
1787
+ # Data validation test has been covered by TestTukeyHSD
1788
+ # like empty, 1d, inf, and lack of tretments
1789
+ # because games_howell leverage _tukey_hsd_iv()
1790
+
1662
1791
  class TestPoissonMeansTest:
1663
1792
  @pytest.mark.parametrize("c1, n1, c2, n2, p_expect", (
1664
1793
  # example from [1], 6. Illustrative examples: Example 1