scipy 1.15.3__cp313-cp313-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp313-cp313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_ccallback.cpython-313-aarch64-linux-musl.so +0 -0
  13. scipy/_lib/_test_deprecation_call.cpython-313-aarch64-linux-musl.so +0 -0
  14. scipy/_lib/_test_deprecation_def.cpython-313-aarch64-linux-musl.so +0 -0
  15. scipy/_lib/_testutils.py +6 -2
  16. scipy/_lib/_uarray/_uarray.cpython-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-313-aarch64-linux-musl.so +0 -0
  98. scipy/cluster/_vq.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  129. scipy/integrate/_lsoda.cpython-313-aarch64-linux-musl.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-313-aarch64-linux-musl.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  139. scipy/integrate/_test_odeint_banded.cpython-313-aarch64-linux-musl.so +0 -0
  140. scipy/integrate/_vode.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  151. scipy/interpolate/_dierckx.cpython-313-aarch64-linux-musl.so +0 -0
  152. scipy/interpolate/_fitpack.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  165. scipy/interpolate/_rgi.py +31 -26
  166. scipy/interpolate/_rgi_cython.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  187. scipy/io/matlab/_mio_utils.cpython-313-aarch64-linux-musl.so +0 -0
  188. scipy/io/matlab/_miobase.py +4 -1
  189. scipy/io/matlab/_streams.cpython-313-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-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  210. scipy/linalg/_expm_frechet.py +4 -0
  211. scipy/linalg/_fblas.cpython-313-aarch64-linux-musl.so +0 -0
  212. scipy/linalg/_flapack.cpython-313-aarch64-linux-musl.so +0 -0
  213. scipy/linalg/_linalg_pythran.cpython-313-aarch64-linux-musl.so +0 -0
  214. scipy/linalg/_matfuncs.py +187 -4
  215. scipy/linalg/_matfuncs_expm.cpython-313-aarch64-linux-musl.so +0 -0
  216. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-aarch64-linux-musl.so +0 -0
  217. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  218. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  225. scipy/linalg/cython_lapack.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  241. scipy/ndimage/_cytest.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  248. scipy/ndimage/_ni_docstrings.py +5 -1
  249. scipy/ndimage/_ni_label.cpython-313-aarch64-linux-musl.so +0 -0
  250. scipy/ndimage/_ni_support.py +1 -5
  251. scipy/ndimage/_rank_filter_1d.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  260. scipy/optimize/_basinhopping.py +13 -7
  261. scipy/optimize/_bglu_dense.cpython-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  272. scipy/optimize/_highspy/_core.cpython-313-aarch64-linux-musl.so +0 -0
  273. scipy/optimize/_highspy/_highs_options.cpython-313-aarch64-linux-musl.so +0 -0
  274. scipy/optimize/_lbfgsb.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  290. scipy/optimize/_minpack_py.py +21 -14
  291. scipy/optimize/_moduleTNC.cpython-313-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-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  317. scipy/optimize/_zeros_py.py +97 -17
  318. scipy/optimize/cython_optimize/_zeros.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  350. scipy/signal/_peak_finding_utils.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  356. scipy/signal/_sosfilt.cpython-313-aarch64-linux-musl.so +0 -0
  357. scipy/signal/_spectral_py.py +230 -50
  358. scipy/signal/_spline.cpython-313-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-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  404. scipy/sparse/csgraph/_matching.cpython-313-aarch64-linux-musl.so +0 -0
  405. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-aarch64-linux-musl.so +0 -0
  406. scipy/sparse/csgraph/_reordering.cpython-313-aarch64-linux-musl.so +0 -0
  407. scipy/sparse/csgraph/_shortest_path.cpython-313-aarch64-linux-musl.so +0 -0
  408. scipy/sparse/csgraph/_tools.cpython-313-aarch64-linux-musl.so +0 -0
  409. scipy/sparse/csgraph/_traversal.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  433. scipy/sparse/linalg/_propack/_dpropack.cpython-313-aarch64-linux-musl.so +0 -0
  434. scipy/sparse/linalg/_propack/_spropack.cpython-313-aarch64-linux-musl.so +0 -0
  435. scipy/sparse/linalg/_propack/_zpropack.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  446. scipy/spatial/_distance_pybind.cpython-313-aarch64-linux-musl.so +0 -0
  447. scipy/spatial/_distance_wrap.cpython-313-aarch64-linux-musl.so +0 -0
  448. scipy/spatial/_hausdorff.cpython-313-aarch64-linux-musl.so +0 -0
  449. scipy/spatial/_qhull.cpython-313-aarch64-linux-musl.so +0 -0
  450. scipy/spatial/_voronoi.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  457. scipy/spatial/transform/_rotation.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  466. scipy/special/_ellip_harm_2.cpython-313-aarch64-linux-musl.so +0 -0
  467. scipy/special/_gufuncs.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  471. scipy/special/_special_ufuncs.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  475. scipy/special/_testutils.py +4 -4
  476. scipy/special/_ufuncs.cpython-313-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-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  502. scipy/stats/_axis_nan_policy.py +5 -12
  503. scipy/stats/_biasedurn.cpython-313-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-313-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-313-aarch64-linux-musl.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-313-aarch64-linux-musl.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  534. scipy/stats/_stats.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-313-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-313-aarch64-linux-musl.so +0 -0
  575. scipy/optimize/_cobyla.cpython-313-aarch64-linux-musl.so +0 -0
  576. scipy/optimize/_cython_nnls.cpython-313-aarch64-linux-musl.so +0 -0
  577. scipy/optimize/_slsqp.cpython-313-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-313-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
scipy/stats/_qmvnt.py CHANGED
@@ -35,12 +35,10 @@
35
35
  import numpy as np
36
36
 
37
37
  from scipy.fft import fft, ifft
38
- from scipy.special import gammaincinv, ndtr, ndtri
38
+ from scipy.special import ndtr as phi, ndtri as phinv
39
39
  from scipy.stats._qmc import primes_from_2_to
40
40
 
41
-
42
- phi = ndtr
43
- phinv = ndtri
41
+ from ._qmvnt_cy import _qmvn_inner, _qmvt_inner
44
42
 
45
43
 
46
44
  def _factorize_int(n):
@@ -145,9 +143,6 @@ def _cbc_lattice(n_dim, n_qmc_samples):
145
143
  return q, n_qmc_samples
146
144
 
147
145
 
148
- # Note: this function is not currently used or tested by any SciPy code. It is
149
- # included in this file to facilitate the development of a parameter for users
150
- # to set the desired CDF accuracy, but must be reviewed and tested before use.
151
146
  def _qauto(func, covar, low, high, rng, error=1e-3, limit=10_000, **kwds):
152
147
  """Automatically rerun the integration to get the required error bound.
153
148
 
@@ -180,7 +175,7 @@ def _qauto(func, covar, low, high, rng, error=1e-3, limit=10_000, **kwds):
180
175
  n = len(covar)
181
176
  n_samples = 0
182
177
  if n == 1:
183
- prob = phi(high) - phi(low)
178
+ prob = phi(high / covar**0.5) - phi(low / covar**0.5)
184
179
  # More or less
185
180
  est_error = 1e-15
186
181
  else:
@@ -198,9 +193,6 @@ def _qauto(func, covar, low, high, rng, error=1e-3, limit=10_000, **kwds):
198
193
  return prob, est_error, n_samples
199
194
 
200
195
 
201
- # Note: this function is not currently used or tested by any SciPy code. It is
202
- # included in this file to facilitate the resolution of gh-8367, gh-16142, and
203
- # possibly gh-14286, but must be reviewed and tested before use.
204
196
  def _qmvn(m, covar, low, high, rng, lattice='cbc', n_batches=10):
205
197
  """Multivariate normal integration over box bounds.
206
198
 
@@ -229,42 +221,17 @@ def _qmvn(m, covar, low, high, rng, lattice='cbc', n_batches=10):
229
221
  3 times the standard error of the batch estimates.
230
222
  """
231
223
  cho, lo, hi = _permuted_cholesky(covar, low, high)
224
+ if not cho.flags.c_contiguous:
225
+ # qmvn_inner expects contiguous buffers
226
+ cho = cho.copy()
227
+
232
228
  n = cho.shape[0]
233
- ct = cho[0, 0]
234
- c = phi(lo[0] / ct)
235
- d = phi(hi[0] / ct)
236
- ci = c
237
- dci = d - ci
238
- prob = 0.0
239
- error_var = 0.0
240
229
  q, n_qmc_samples = _cbc_lattice(n - 1, max(m // n_batches, 1))
241
- y = np.zeros((n - 1, n_qmc_samples))
242
- i_samples = np.arange(n_qmc_samples) + 1
243
- for j in range(n_batches):
244
- c = np.full(n_qmc_samples, ci)
245
- dc = np.full(n_qmc_samples, dci)
246
- pv = dc.copy()
247
- for i in range(1, n):
248
- # Pseudorandomly-shifted lattice coordinate.
249
- z = q[i - 1] * i_samples + rng.random()
250
- # Fast remainder(z, 1.0)
251
- z -= z.astype(int)
252
- # Tent periodization transform.
253
- x = abs(2 * z - 1)
254
- y[i - 1, :] = phinv(c + x * dc)
255
- s = cho[i, :i] @ y[:i, :]
256
- ct = cho[i, i]
257
- c = phi((lo[i] - s) / ct)
258
- d = phi((hi[i] - s) / ct)
259
- dc = d - c
260
- pv = pv * dc
261
- # Accumulate the mean and error variances with online formulations.
262
- d = (pv.mean() - prob) / (j + 1)
263
- prob += d
264
- error_var = (j - 1) * error_var / (j + 1) + d * d
265
- # Error bounds are 3 times the standard error of the estimates.
266
- est_error = 3 * np.sqrt(error_var)
267
- n_samples = n_qmc_samples * n_batches
230
+ rndm = rng.random(size=(n_batches, n))
231
+
232
+ prob, est_error, n_samples = _qmvn_inner(
233
+ q, rndm, int(n_qmc_samples), int(n_batches), cho, lo, hi
234
+ )
268
235
  return prob, est_error, n_samples
269
236
 
270
237
 
@@ -371,57 +338,11 @@ def _qmvt(m, nu, covar, low, high, rng, lattice='cbc', n_batches=10):
371
338
  high = np.asarray(high, dtype=np.float64)
372
339
  cho, lo, hi = _permuted_cholesky(covar, low / sn, high / sn)
373
340
  n = cho.shape[0]
374
- prob = 0.0
375
- error_var = 0.0
376
341
  q, n_qmc_samples = _cbc_lattice(n, max(m // n_batches, 1))
377
- i_samples = np.arange(n_qmc_samples) + 1
378
- for j in range(n_batches):
379
- pv = np.ones(n_qmc_samples)
380
- s = np.zeros((n, n_qmc_samples))
381
- for i in range(n):
382
- # Pseudorandomly-shifted lattice coordinate.
383
- z = q[i] * i_samples + rng.random()
384
- # Fast remainder(z, 1.0)
385
- z -= z.astype(int)
386
- # Tent periodization transform.
387
- x = abs(2 * z - 1)
388
- # FIXME: Lift the i==0 case out of the loop to make the logic
389
- # easier to follow.
390
- if i == 0:
391
- # We'll use one of the QR variates to pull out the
392
- # t-distribution scaling.
393
- if nu > 0:
394
- r = np.sqrt(2 * gammaincinv(nu / 2, x))
395
- else:
396
- r = np.ones_like(x)
397
- else:
398
- y = phinv(c + x * dc) # noqa: F821
399
- with np.errstate(invalid='ignore'):
400
- s[i:, :] += cho[i:, i - 1][:, np.newaxis] * y
401
- si = s[i, :]
402
-
403
- c = np.ones(n_qmc_samples)
404
- d = np.ones(n_qmc_samples)
405
- with np.errstate(invalid='ignore'):
406
- lois = lo[i] * r - si
407
- hiis = hi[i] * r - si
408
- c[lois < -9] = 0.0
409
- d[hiis < -9] = 0.0
410
- lo_mask = abs(lois) < 9
411
- hi_mask = abs(hiis) < 9
412
- c[lo_mask] = phi(lois[lo_mask])
413
- d[hi_mask] = phi(hiis[hi_mask])
414
-
415
- dc = d - c
416
- pv *= dc
417
-
418
- # Accumulate the mean and error variances with online formulations.
419
- d = (pv.mean() - prob) / (j + 1)
420
- prob += d
421
- error_var = (j - 1) * error_var / (j + 1) + d * d
422
- # Error bounds are 3 times the standard error of the estimates.
423
- est_error = 3 * np.sqrt(error_var)
424
- n_samples = n_qmc_samples * n_batches
342
+ rndm = rng.random(size=(n_batches, n))
343
+ prob, est_error, n_samples = _qmvt_inner(
344
+ q, rndm, int(n_qmc_samples), int(n_batches), cho, lo, hi, float(nu)
345
+ )
425
346
  return prob, est_error, n_samples
426
347
 
427
348
 
@@ -0,0 +1,335 @@
1
+ import numpy as np
2
+ from scipy.special import betainc
3
+ from scipy._lib._array_api import xp_ravel, array_namespace, xp_promote
4
+ import scipy._lib.array_api_extra as xpx
5
+ from scipy.stats._axis_nan_policy import _broadcast_arrays, _contains_nan
6
+ from scipy.stats._stats_py import _length_nonmasked
7
+
8
+
9
+ def _quantile_iv(x, p, method, axis, nan_policy, keepdims):
10
+ xp = array_namespace(x, p)
11
+
12
+ if not xp.isdtype(xp.asarray(x).dtype, ('integral', 'real floating')):
13
+ raise ValueError("`x` must have real dtype.")
14
+
15
+ if not xp.isdtype(xp.asarray(p).dtype, 'real floating'):
16
+ raise ValueError("`p` must have real floating dtype.")
17
+
18
+ x, p = xp_promote(x, p, force_floating=True, xp=xp)
19
+ dtype = x.dtype
20
+
21
+ axis_none = axis is None
22
+ ndim = max(x.ndim, p.ndim)
23
+ if axis_none:
24
+ x = xp_ravel(x)
25
+ p = xp_ravel(p)
26
+ axis = 0
27
+ elif np.iterable(axis) or int(axis) != axis:
28
+ message = "`axis` must be an integer or None."
29
+ raise ValueError(message)
30
+ elif (axis >= ndim) or (axis < -ndim):
31
+ message = "`axis` is not compatible with the shapes of the inputs."
32
+ raise ValueError(message)
33
+ axis = int(axis)
34
+
35
+ methods = {'inverted_cdf', 'averaged_inverted_cdf', 'closest_observation',
36
+ 'hazen', 'interpolated_inverted_cdf', 'linear',
37
+ 'median_unbiased', 'normal_unbiased', 'weibull',
38
+ 'harrell-davis'}
39
+ if method not in methods:
40
+ message = f"`method` must be one of {methods}"
41
+ raise ValueError(message)
42
+
43
+ contains_nans = _contains_nan(x, nan_policy, xp_omit_okay=True, xp=xp)
44
+
45
+ if keepdims not in {None, True, False}:
46
+ message = "If specified, `keepdims` must be True or False."
47
+ raise ValueError(message)
48
+
49
+ # If data has length zero along `axis`, the result will be an array of NaNs just
50
+ # as if the data had length 1 along axis and were filled with NaNs. This is treated
51
+ # naturally below whether `nan_policy` is `'propagate'` or `'omit'`.
52
+ if x.shape[axis] == 0:
53
+ shape = list(x.shape)
54
+ shape[axis] = 1
55
+ x = xp.full(shape, xp.asarray(xp.nan, dtype=dtype))
56
+
57
+ y = xp.sort(x, axis=axis)
58
+ y, p = _broadcast_arrays((y, p), axis=axis)
59
+
60
+ if (keepdims is False) and (p.shape[axis] != 1):
61
+ message = "`keepdims` may be False only if the length of `p` along `axis` is 1."
62
+ raise ValueError(message)
63
+ keepdims = (p.shape[axis] != 1) if keepdims is None else keepdims
64
+
65
+ y = xp.moveaxis(y, axis, -1)
66
+ p = xp.moveaxis(p, axis, -1)
67
+
68
+ n = _length_nonmasked(y, -1, xp=xp, keepdims=True)
69
+ n = xp.asarray(n, dtype=dtype)
70
+ if contains_nans:
71
+ nans = xp.isnan(y)
72
+
73
+ # Note that if length along `axis` were 0 to begin with,
74
+ # it is now length 1 and filled with NaNs.
75
+ if nan_policy == 'propagate':
76
+ nan_out = xp.any(nans, axis=-1)
77
+ else: # 'omit'
78
+ non_nan = xp.astype(~nans, xp.uint64)
79
+ n_int = xp.sum(non_nan, axis=-1, keepdims=True)
80
+ n = xp.astype(n_int, dtype)
81
+ # NaNs are produced only if slice is empty after removing NaNs
82
+ nan_out = xp.any(n == 0, axis=-1)
83
+ n = xpx.at(n, nan_out).set(y.shape[-1]) # avoids pytorch/pytorch#146211
84
+
85
+ if xp.any(nan_out):
86
+ y = xp.asarray(y, copy=True) # ensure writable
87
+ y = xpx.at(y, nan_out).set(xp.nan)
88
+ elif xp.any(nans) and method == 'harrell-davis':
89
+ y = xp.asarray(y, copy=True) # ensure writable
90
+ y = xpx.at(y, nans).set(0) # any non-nan will prevent NaN from propagating
91
+
92
+ p_mask = (p > 1) | (p < 0) | xp.isnan(p)
93
+ if xp.any(p_mask):
94
+ p = xp.asarray(p, copy=True)
95
+ p = xpx.at(p, p_mask).set(0.5) # these get NaN-ed out at the end
96
+
97
+ return y, p, method, axis, nan_policy, keepdims, n, axis_none, ndim, p_mask, xp
98
+
99
+
100
+ def quantile(x, p, *, method='linear', axis=0, nan_policy='propagate', keepdims=None):
101
+ """
102
+ Compute the p-th quantile of the data along the specified axis.
103
+
104
+ Parameters
105
+ ----------
106
+ x : array_like of real numbers
107
+ Data array.
108
+ p : array_like of float
109
+ Probability or sequence of probabilities of the quantiles to compute.
110
+ Values must be between 0 and 1 (inclusive).
111
+ Must have length 1 along `axis` unless ``keepdims=True``.
112
+ method : str, default: 'linear'
113
+ The method to use for estimating the quantile.
114
+ The available options, numbered as they appear in [1]_, are:
115
+
116
+ 1. 'inverted_cdf'
117
+ 2. 'averaged_inverted_cdf'
118
+ 3. 'closest_observation'
119
+ 4. 'interpolated_inverted_cdf'
120
+ 5. 'hazen'
121
+ 6. 'weibull'
122
+ 7. 'linear' (default)
123
+ 8. 'median_unbiased'
124
+ 9. 'normal_unbiased'
125
+
126
+ 'harrell-davis' is also available to compute the quantile estimate
127
+ according to [2]_.
128
+ See Notes for details.
129
+ axis : int or None, default: 0
130
+ Axis along which the quantiles are computed.
131
+ ``None`` ravels both `x` and `p` before performing the calculation,
132
+ without checking whether the original shapes were compatible.
133
+ nan_policy : str, default: 'propagate'
134
+ Defines how to handle NaNs in the input data `x`.
135
+
136
+ - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
137
+ which the statistic is computed, the corresponding slice of the output
138
+ will contain NaN(s).
139
+ - ``omit``: NaNs will be omitted when performing the calculation.
140
+ If insufficient data remains in the axis slice along which the
141
+ statistic is computed, the corresponding slice of the output will
142
+ contain NaN(s).
143
+ - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
144
+
145
+ If NaNs are present in `p`, a ``ValueError`` will be raised.
146
+ keepdims : bool, optional
147
+ Consider the case in which `x` is 1-D and `p` is a scalar: the quantile
148
+ is a reducing statistic, and the default behavior is to return a scalar.
149
+ If `keepdims` is set to True, the axis will not be reduced away, and the
150
+ result will be a 1-D array with one element.
151
+
152
+ The general case is more subtle, since multiple quantiles may be
153
+ requested for each axis-slice of `x`. For instance, if both `x` and `p`
154
+ are 1-D and ``p.size > 1``, no axis can be reduced away; there must be an
155
+ axis to contain the number of quantiles given by ``p.size``. Therefore:
156
+
157
+ - By default, the axis will be reduced away if possible (i.e. if there is
158
+ exactly one element of `q` per axis-slice of `x`).
159
+ - If `keepdims` is set to True, the axis will not be reduced away.
160
+ - If `keepdims` is set to False, the axis will be reduced away
161
+ if possible, and an error will be raised otherwise.
162
+
163
+ Returns
164
+ -------
165
+ quantile : scalar or ndarray
166
+ The resulting quantile(s). The dtype is the result dtype of `x` and `p`.
167
+
168
+ Notes
169
+ -----
170
+ Given a sample `x` from an underlying distribution, `quantile` provides a
171
+ nonparametric estimate of the inverse cumulative distribution function.
172
+
173
+ By default, this is done by interpolating between adjacent elements in
174
+ ``y``, a sorted copy of `x`::
175
+
176
+ (1-g)*y[j] + g*y[j+1]
177
+
178
+ where the index ``j`` and coefficient ``g`` are the integral and
179
+ fractional components of ``p * (n-1)``, and ``n`` is the number of
180
+ elements in the sample.
181
+
182
+ This is a special case of Equation 1 of H&F [1]_. More generally,
183
+
184
+ - ``j = (p*n + m - 1) // 1``, and
185
+ - ``g = (p*n + m - 1) % 1``,
186
+
187
+ where ``m`` may be defined according to several different conventions.
188
+ The preferred convention may be selected using the ``method`` parameter:
189
+
190
+ =============================== =============== ===============
191
+ ``method`` number in H&F ``m``
192
+ =============================== =============== ===============
193
+ ``interpolated_inverted_cdf`` 4 ``0``
194
+ ``hazen`` 5 ``1/2``
195
+ ``weibull`` 6 ``p``
196
+ ``linear`` (default) 7 ``1 - p``
197
+ ``median_unbiased`` 8 ``p/3 + 1/3``
198
+ ``normal_unbiased`` 9 ``p/4 + 3/8``
199
+ =============================== =============== ===============
200
+
201
+ Note that indices ``j`` and ``j + 1`` are clipped to the range ``0`` to
202
+ ``n - 1`` when the results of the formula would be outside the allowed
203
+ range of non-negative indices. When ``j`` is clipped to zero, ``g`` is
204
+ set to zero as well. The ``-1`` in the formulas for ``j`` and ``g``
205
+ accounts for Python's 0-based indexing.
206
+
207
+ The table above includes only the estimators from [1]_ that are continuous
208
+ functions of probability `p` (estimators 4-9). SciPy also provides the
209
+ three discontinuous estimators from [1]_ (estimators 1-3), where ``j`` is
210
+ defined as above, ``m`` is defined as follows, and ``g`` is ``0`` when
211
+ ``index = p*n + m - 1`` is less than ``0`` and otherwise is defined below.
212
+
213
+ 1. ``inverted_cdf``: ``m = 0`` and ``g = int(index - j > 0)``
214
+ 2. ``averaged_inverted_cdf``: ``m = 0`` and
215
+ ``g = (1 + int(index - j > 0)) / 2``
216
+ 3. ``closest_observation``: ``m = -1/2`` and
217
+ ``g = 1 - int((index == j) & (j%2 == 1))``
218
+
219
+ A different strategy for computing quantiles from [2]_, ``method='harrell-davis'``,
220
+ uses a weighted combination of all elements. The weights are computed as:
221
+
222
+ .. math::
223
+
224
+ w_{n, i} = I_{i/n}(a, b) - I_{(i - 1)/n}(a, b)
225
+
226
+ where :math:`n` is the number of elements in the sample,
227
+ :math:`i` are the indices :math:`1, 2, ..., n-1, n` of the sorted elements,
228
+ :math:`a = p (n + 1)`, :math:`b = (1 - p)(n + 1)`,
229
+ :math:`p` is the probability of the quantile, and
230
+ :math:`I` is the regularized, lower incomplete beta function
231
+ (`scipy.special.betainc`).
232
+
233
+ Examples
234
+ --------
235
+ >>> import numpy as np
236
+ >>> from scipy import stats
237
+ >>> x = np.asarray([[10, 8, 7, 5, 4],
238
+ ... [0, 1, 2, 3, 5]])
239
+
240
+ Take the median along the last axis.
241
+
242
+ >>> stats.quantile(x, 0.5, axis=-1)
243
+ array([7., 2.])
244
+
245
+ Take a different quantile along each axis.
246
+
247
+ >>> stats.quantile(x, [[0.25], [0.75]], axis=-1, keepdims=True)
248
+ array([[5.],
249
+ [3.]])
250
+
251
+ Take multiple quantiles along each axis.
252
+
253
+ >>> stats.quantile(x, [0.25, 0.75], axis=-1)
254
+ array([[5., 8.],
255
+ [1., 3.]])
256
+
257
+ References
258
+ ----------
259
+ .. [1] R. J. Hyndman and Y. Fan,
260
+ "Sample quantiles in statistical packages,"
261
+ The American Statistician, 50(4), pp. 361-365, 1996
262
+ .. [2] Harrell, Frank E., and C. E. Davis.
263
+ "A new distribution-free quantile estimator."
264
+ Biometrika 69.3 (1982): 635-640.
265
+
266
+ """
267
+ # Input validation / standardization
268
+
269
+ temp = _quantile_iv(x, p, method, axis, nan_policy, keepdims)
270
+ y, p, method, axis, nan_policy, keepdims, n, axis_none, ndim, p_mask, xp = temp
271
+
272
+ if method in {'inverted_cdf', 'averaged_inverted_cdf', 'closest_observation',
273
+ 'hazen', 'interpolated_inverted_cdf', 'linear',
274
+ 'median_unbiased', 'normal_unbiased', 'weibull'}:
275
+ res = _quantile_hf(y, p, n, method, xp)
276
+ elif method in {'harrell-davis'}:
277
+ res = _quantile_hd(y, p, n, xp)
278
+
279
+ res = xpx.at(res, p_mask).set(xp.nan)
280
+
281
+ # Reshape per axis/keepdims
282
+ if axis_none and keepdims:
283
+ shape = (1,)*(ndim - 1) + res.shape
284
+ res = xp.reshape(res, shape)
285
+ axis = -1
286
+
287
+ res = xp.moveaxis(res, -1, axis)
288
+
289
+ if not keepdims:
290
+ res = xp.squeeze(res, axis=axis)
291
+
292
+ return res[()] if res.ndim == 0 else res
293
+
294
+
295
+ def _quantile_hf(y, p, n, method, xp):
296
+ ms = dict(inverted_cdf=0, averaged_inverted_cdf=0, closest_observation=-0.5,
297
+ interpolated_inverted_cdf=0, hazen=0.5, weibull=p, linear=1 - p,
298
+ median_unbiased=p/3 + 1/3, normal_unbiased=p/4 + 3/8)
299
+ m = ms[method]
300
+ jg = p*n + m - 1
301
+ j = jg // 1
302
+ g = jg % 1
303
+ if method == 'inverted_cdf':
304
+ g = xp.astype((g > 0), jg.dtype)
305
+ elif method == 'averaged_inverted_cdf':
306
+ g = (1 + xp.astype((g > 0), jg.dtype)) / 2
307
+ elif method == 'closest_observation':
308
+ g = (1 - xp.astype((g == 0) & (j % 2 == 1), jg.dtype))
309
+ if method in {'inverted_cdf', 'averaged_inverted_cdf', 'closest_observation'}:
310
+ g = xp.asarray(g)
311
+ g = xpx.at(g, jg < 0).set(0)
312
+
313
+ g[j < 0] = 0
314
+ j = xp.clip(j, 0., n - 1)
315
+ jp1 = xp.clip(j + 1, 0., n - 1)
316
+
317
+ return ((1 - g) * xp.take_along_axis(y, xp.astype(j, xp.int64), axis=-1)
318
+ + g * xp.take_along_axis(y, xp.astype(jp1, xp.int64), axis=-1))
319
+
320
+
321
+ def _quantile_hd(y, p, n, xp):
322
+ # RE axis handling: We need to perform a reducing operation over rows of `y` for
323
+ # each element in the corresponding row of `p` (a la Cartesian product). Strategy:
324
+ # move rows of `p` to an axis at the front that is orthogonal to all the rest,
325
+ # perform the reducing operating over the last axis, then move the front axis back
326
+ # to the end.
327
+ p = xp.moveaxis(p, -1, 0)[..., xp.newaxis]
328
+ a = p * (n + 1)
329
+ b = (1 - p) * (n + 1)
330
+ i = xp.arange(y.shape[-1] + 1, dtype=y.dtype)
331
+ w = betainc(a, b, i / n)
332
+ w = w[..., 1:] - w[..., :-1]
333
+ w = xpx.at(w, xp.isnan(w)).set(0)
334
+ res = xp.vecdot(w, y, axis=-1)
335
+ return xp.moveaxis(res, 0, -1)
@@ -7,7 +7,7 @@ import inspect
7
7
 
8
8
  from scipy._lib._util import (check_random_state, _rename_parameter, rng_integers,
9
9
  _transition_to_rng)
10
- from scipy._lib._array_api import array_namespace, is_numpy, xp_moveaxis_to_end
10
+ from scipy._lib._array_api import array_namespace, is_numpy, xp_result_type
11
11
  from scipy.special import ndtr, ndtri, comb, factorial
12
12
 
13
13
  from ._common import ConfidenceInterval
@@ -183,20 +183,7 @@ def _bootstrap_iv(data, statistic, vectorized, paired, axis, confidence_level,
183
183
  if n_samples == 0:
184
184
  raise ValueError("`data` must contain at least one sample.")
185
185
 
186
- message = ("Ignoring the dimension specified by `axis`, arrays in `data` do not "
187
- "have the same shape. Beginning in SciPy 1.16.0, `bootstrap` will "
188
- "explicitly broadcast elements of `data` to the same shape (ignoring "
189
- "`axis`) before performing the calculation. To avoid this warning in "
190
- "the meantime, ensure that all samples have the same shape (except "
191
- "potentially along `axis`).")
192
- data = [np.atleast_1d(sample) for sample in data]
193
- reduced_shapes = set()
194
- for sample in data:
195
- reduced_shape = list(sample.shape)
196
- reduced_shape.pop(axis)
197
- reduced_shapes.add(tuple(reduced_shape))
198
- if len(reduced_shapes) != 1:
199
- warnings.warn(message, FutureWarning, stacklevel=3)
186
+ data = _broadcast_arrays(data, axis_int)
200
187
 
201
188
  data_iv = []
202
189
  for sample in data:
@@ -331,15 +318,6 @@ def bootstrap(data, statistic, *, n_resamples=9999, batch=None,
331
318
  Each element of `data` is a sample containing scalar observations from an
332
319
  underlying distribution. Elements of `data` must be broadcastable to the
333
320
  same shape (with the possible exception of the dimension specified by `axis`).
334
-
335
- .. versionchanged:: 1.14.0
336
- `bootstrap` will now emit a ``FutureWarning`` if the shapes of the
337
- elements of `data` are not the same (with the exception of the dimension
338
- specified by `axis`).
339
- Beginning in SciPy 1.16.0, `bootstrap` will explicitly broadcast the
340
- elements to the same shape (except along `axis`) before performing
341
- the calculation.
342
-
343
321
  statistic : callable
344
322
  Statistic for which the confidence interval is to be calculated.
345
323
  `statistic` must be a callable that accepts ``len(data)`` samples
@@ -720,6 +698,7 @@ def _monte_carlo_test_iv(data, rvs, statistic, vectorized, n_resamples,
720
698
  vectorized = 'axis' in signature
721
699
 
722
700
  xp = array_namespace(*data)
701
+ dtype = xp_result_type(*data, force_floating=True, xp=xp)
723
702
 
724
703
  if not vectorized:
725
704
  if is_numpy(xp):
@@ -735,7 +714,7 @@ def _monte_carlo_test_iv(data, rvs, statistic, vectorized, n_resamples,
735
714
  data_iv = []
736
715
  for sample in data:
737
716
  sample = xp.broadcast_to(sample, (1,)) if sample.ndim == 0 else sample
738
- sample = xp_moveaxis_to_end(sample, axis_int, xp=xp)
717
+ sample = xp.moveaxis(sample, axis_int, -1)
739
718
  data_iv.append(sample)
740
719
 
741
720
  n_resamples_int = int(n_resamples)
@@ -754,10 +733,6 @@ def _monte_carlo_test_iv(data, rvs, statistic, vectorized, n_resamples,
754
733
  if alternative not in alternatives:
755
734
  raise ValueError(f"`alternative` must be in {alternatives}")
756
735
 
757
- # Infer the desired p-value dtype based on the input types
758
- min_float = getattr(xp, 'float16', xp.float32)
759
- dtype = xp.result_type(*data_iv, min_float)
760
-
761
736
  return (data_iv, rvs, statistic_vectorized, vectorized, n_resamples_int,
762
737
  batch_iv, alternative, axis_int, dtype, xp)
763
738
 
scipy/stats/_sampling.py CHANGED
@@ -1028,7 +1028,7 @@ class FastGeneratorInversion:
1028
1028
  4.507068014335139e-07 # may vary
1029
1029
 
1030
1030
  """
1031
- if not isinstance(size, (numbers.Integral, np.integer)):
1031
+ if not isinstance(size, numbers.Integral | np.integer):
1032
1032
  raise ValueError("size must be an integer.")
1033
1033
  # urng will be used to draw the samples for testing the error
1034
1034
  # it must not interfere with self.random_state. therefore, do not
@@ -2,6 +2,7 @@ import warnings
2
2
  import numpy as np
3
3
  from . import distributions
4
4
  from .._lib._bunch import _make_tuple_bunch
5
+ from ._axis_nan_policy import _axis_nan_policy_factory
5
6
  from ._stats_pythran import siegelslopes as siegelslopes_pythran
6
7
 
7
8
  __all__ = ['_find_repeats', 'theilslopes', 'siegelslopes']
@@ -14,6 +15,14 @@ SiegelslopesResult = _make_tuple_bunch('SiegelslopesResult',
14
15
  ['slope', 'intercept'])
15
16
 
16
17
 
18
+ def _n_samples_optional_x(kwargs):
19
+ return 2 if kwargs.get('x', None) is not None else 1
20
+
21
+
22
+ @_axis_nan_policy_factory(TheilslopesResult, default_axis=None, n_outputs=4,
23
+ n_samples=_n_samples_optional_x,
24
+ result_to_tuple=lambda x, _: tuple(x), paired=True,
25
+ too_small=1)
17
26
  def theilslopes(y, x=None, alpha=0.95, method='separate'):
18
27
  r"""
19
28
  Computes the Theil-Sen estimator for a set of points (x, y).
@@ -131,7 +140,9 @@ def theilslopes(y, x=None, alpha=0.95, method='separate'):
131
140
  else:
132
141
  x = np.array(x, dtype=float, copy=True).ravel()
133
142
  if len(x) != len(y):
134
- raise ValueError(f"Incompatible lengths ! ({len(y)}<>{len(x)})")
143
+ raise ValueError("Array shapes are incompatible for broadcasting.")
144
+ if len(x) < 2:
145
+ raise ValueError("`x` and `y` must have length at least 2.")
135
146
 
136
147
  # Compute sorted slopes only when deltax > 0
137
148
  deltax = x[:, np.newaxis] - x
@@ -192,6 +203,10 @@ def _find_repeats(arr):
192
203
  return unique[atleast2], freq[atleast2]
193
204
 
194
205
 
206
+ @_axis_nan_policy_factory(SiegelslopesResult, default_axis=None, n_outputs=2,
207
+ n_samples=_n_samples_optional_x,
208
+ result_to_tuple=lambda x, _: tuple(x), paired=True,
209
+ too_small=1)
195
210
  def siegelslopes(y, x=None, method="hierarchical"):
196
211
  r"""
197
212
  Computes the Siegel estimator for a set of points (x, y).
@@ -296,8 +311,12 @@ def siegelslopes(y, x=None, method="hierarchical"):
296
311
  else:
297
312
  x = np.asarray(x, dtype=float).ravel()
298
313
  if len(x) != len(y):
299
- raise ValueError(f"Incompatible lengths ! ({len(y)}<>{len(x)})")
314
+ raise ValueError("Array shapes are incompatible for broadcasting.")
315
+ if len(x) < 2:
316
+ raise ValueError("`x` and `y` must have length at least 2.")
317
+
300
318
  dtype = np.result_type(x, y, np.float32) # use at least float32
301
319
  y, x = y.astype(dtype), x.astype(dtype)
302
320
  medslope, medinter = siegelslopes_pythran(y, x, method)
321
+ medslope, medinter = np.asarray(medslope)[()], np.asarray(medinter)[()]
303
322
  return SiegelslopesResult(slope=medslope, intercept=medinter)