scipy 1.15.3__cp313-cp313-macosx_14_0_arm64.whl → 1.16.0rc1__cp313-cp313-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (608) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313-darwin.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-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_deprecation_call.cpython-313-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-313-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-313-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-313-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-313-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-313-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-313-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-313-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-313-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_quad_vec.py +21 -29
  128. scipy/integrate/_quadpack_py.py +11 -7
  129. scipy/integrate/_quadrature.py +3 -3
  130. scipy/integrate/_rules/_base.py +2 -2
  131. scipy/integrate/_tanhsinh.py +48 -47
  132. scipy/integrate/_test_odeint_banded.cpython-313-darwin.so +0 -0
  133. scipy/integrate/_vode.cpython-313-darwin.so +0 -0
  134. scipy/integrate/tests/test__quad_vec.py +0 -6
  135. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  136. scipy/integrate/tests/test_cubature.py +21 -35
  137. scipy/integrate/tests/test_quadrature.py +6 -8
  138. scipy/integrate/tests/test_tanhsinh.py +56 -48
  139. scipy/interpolate/__init__.py +70 -58
  140. scipy/interpolate/_bary_rational.py +22 -22
  141. scipy/interpolate/_bsplines.py +119 -66
  142. scipy/interpolate/_cubic.py +65 -50
  143. scipy/interpolate/_dfitpack.cpython-313-darwin.so +0 -0
  144. scipy/interpolate/_dierckx.cpython-313-darwin.so +0 -0
  145. scipy/interpolate/_fitpack2.py +9 -6
  146. scipy/interpolate/_fitpack_impl.py +32 -26
  147. scipy/interpolate/_fitpack_repro.py +23 -19
  148. scipy/interpolate/_interpnd.cpython-313-darwin.so +0 -0
  149. scipy/interpolate/_interpolate.py +30 -12
  150. scipy/interpolate/_ndbspline.py +13 -18
  151. scipy/interpolate/_ndgriddata.py +5 -8
  152. scipy/interpolate/_polyint.py +95 -31
  153. scipy/interpolate/_ppoly.cpython-313-darwin.so +0 -0
  154. scipy/interpolate/_rbf.py +2 -2
  155. scipy/interpolate/_rbfinterp.py +1 -1
  156. scipy/interpolate/_rgi.py +31 -26
  157. scipy/interpolate/_rgi_cython.cpython-313-darwin.so +0 -0
  158. scipy/interpolate/dfitpack.py +0 -20
  159. scipy/interpolate/interpnd.py +1 -2
  160. scipy/interpolate/tests/test_bary_rational.py +2 -2
  161. scipy/interpolate/tests/test_bsplines.py +97 -1
  162. scipy/interpolate/tests/test_fitpack2.py +39 -1
  163. scipy/interpolate/tests/test_interpnd.py +32 -20
  164. scipy/interpolate/tests/test_interpolate.py +48 -4
  165. scipy/interpolate/tests/test_rgi.py +2 -1
  166. scipy/io/_fast_matrix_market/__init__.py +2 -0
  167. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  168. scipy/io/_harwell_boeing/hb.py +7 -11
  169. scipy/io/_idl.py +5 -7
  170. scipy/io/_netcdf.py +15 -5
  171. scipy/io/_test_fortran.cpython-313-darwin.so +0 -0
  172. scipy/io/arff/tests/test_arffread.py +3 -3
  173. scipy/io/matlab/__init__.py +5 -3
  174. scipy/io/matlab/_mio.py +4 -1
  175. scipy/io/matlab/_mio5.py +19 -13
  176. scipy/io/matlab/_mio5_utils.cpython-313-darwin.so +0 -0
  177. scipy/io/matlab/_mio_utils.cpython-313-darwin.so +0 -0
  178. scipy/io/matlab/_miobase.py +4 -1
  179. scipy/io/matlab/_streams.cpython-313-darwin.so +0 -0
  180. scipy/io/matlab/tests/test_mio.py +46 -18
  181. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  182. scipy/io/tests/test_mmio.py +7 -1
  183. scipy/io/tests/test_wavfile.py +41 -0
  184. scipy/io/wavfile.py +57 -10
  185. scipy/linalg/_basic.py +113 -86
  186. scipy/linalg/_cythonized_array_utils.cpython-313-darwin.so +0 -0
  187. scipy/linalg/_decomp.py +22 -9
  188. scipy/linalg/_decomp_cholesky.py +28 -13
  189. scipy/linalg/_decomp_cossin.py +45 -30
  190. scipy/linalg/_decomp_interpolative.cpython-313-darwin.so +0 -0
  191. scipy/linalg/_decomp_ldl.py +4 -1
  192. scipy/linalg/_decomp_lu.py +18 -6
  193. scipy/linalg/_decomp_lu_cython.cpython-313-darwin.so +0 -0
  194. scipy/linalg/_decomp_polar.py +2 -0
  195. scipy/linalg/_decomp_qr.py +6 -2
  196. scipy/linalg/_decomp_qz.py +3 -0
  197. scipy/linalg/_decomp_schur.py +3 -1
  198. scipy/linalg/_decomp_svd.py +13 -2
  199. scipy/linalg/_decomp_update.cpython-313-darwin.so +0 -0
  200. scipy/linalg/_expm_frechet.py +4 -0
  201. scipy/linalg/_fblas.cpython-313-darwin.so +0 -0
  202. scipy/linalg/_flapack.cpython-313-darwin.so +0 -0
  203. scipy/linalg/_matfuncs.py +187 -4
  204. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-darwin.so +0 -0
  205. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  206. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-darwin.so +0 -0
  207. scipy/linalg/_procrustes.py +2 -0
  208. scipy/linalg/_sketches.py +17 -6
  209. scipy/linalg/_solve_toeplitz.cpython-313-darwin.so +0 -0
  210. scipy/linalg/_solvers.py +7 -2
  211. scipy/linalg/_special_matrices.py +26 -36
  212. scipy/linalg/cython_blas.cpython-313-darwin.so +0 -0
  213. scipy/linalg/cython_lapack.cpython-313-darwin.so +0 -0
  214. scipy/linalg/lapack.py +22 -2
  215. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  216. scipy/linalg/tests/test_basic.py +31 -16
  217. scipy/linalg/tests/test_batch.py +588 -0
  218. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  219. scipy/linalg/tests/test_decomp.py +40 -3
  220. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  221. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  222. scipy/linalg/tests/test_lapack.py +115 -7
  223. scipy/linalg/tests/test_matfuncs.py +157 -102
  224. scipy/linalg/tests/test_procrustes.py +0 -7
  225. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  226. scipy/linalg/tests/test_special_matrices.py +1 -5
  227. scipy/ndimage/__init__.py +1 -0
  228. scipy/ndimage/_cytest.cpython-313-darwin.so +0 -0
  229. scipy/ndimage/_delegators.py +8 -2
  230. scipy/ndimage/_filters.py +433 -5
  231. scipy/ndimage/_interpolation.py +36 -6
  232. scipy/ndimage/_measurements.py +4 -2
  233. scipy/ndimage/_morphology.py +5 -0
  234. scipy/ndimage/_nd_image.cpython-313-darwin.so +0 -0
  235. scipy/ndimage/_ni_docstrings.py +5 -1
  236. scipy/ndimage/_ni_label.cpython-313-darwin.so +0 -0
  237. scipy/ndimage/_ni_support.py +1 -5
  238. scipy/ndimage/_support_alternative_backends.py +18 -6
  239. scipy/ndimage/tests/test_filters.py +337 -259
  240. scipy/ndimage/tests/test_fourier.py +7 -9
  241. scipy/ndimage/tests/test_interpolation.py +68 -61
  242. scipy/ndimage/tests/test_measurements.py +18 -35
  243. scipy/ndimage/tests/test_morphology.py +143 -131
  244. scipy/ndimage/tests/test_splines.py +1 -3
  245. scipy/optimize/_basinhopping.py +13 -7
  246. scipy/optimize/_bglu_dense.cpython-313-darwin.so +0 -0
  247. scipy/optimize/_bracket.py +17 -24
  248. scipy/optimize/_chandrupatla.py +9 -10
  249. scipy/optimize/_cobyla_py.py +104 -123
  250. scipy/optimize/_constraints.py +14 -10
  251. scipy/optimize/_differentiable_functions.py +371 -230
  252. scipy/optimize/_differentialevolution.py +4 -3
  253. scipy/optimize/_dual_annealing.py +1 -1
  254. scipy/optimize/_elementwise.py +1 -4
  255. scipy/optimize/_lbfgsb_py.py +57 -16
  256. scipy/optimize/_linprog_doc.py +2 -2
  257. scipy/optimize/_linprog_highs.py +2 -2
  258. scipy/optimize/_linprog_ip.py +25 -10
  259. scipy/optimize/_linprog_util.py +14 -16
  260. scipy/optimize/_lsq/common.py +3 -3
  261. scipy/optimize/_lsq/dogbox.py +16 -2
  262. scipy/optimize/_lsq/givens_elimination.cpython-313-darwin.so +0 -0
  263. scipy/optimize/_lsq/least_squares.py +198 -126
  264. scipy/optimize/_lsq/lsq_linear.py +6 -6
  265. scipy/optimize/_lsq/trf.py +35 -8
  266. scipy/optimize/_milp.py +3 -1
  267. scipy/optimize/_minimize.py +105 -36
  268. scipy/optimize/_minpack_py.py +21 -14
  269. scipy/optimize/_moduleTNC.cpython-313-darwin.so +0 -0
  270. scipy/optimize/_nnls.py +20 -21
  271. scipy/optimize/_nonlin.py +34 -3
  272. scipy/optimize/_numdiff.py +288 -110
  273. scipy/optimize/_optimize.py +86 -48
  274. scipy/optimize/_remove_redundancy.py +5 -5
  275. scipy/optimize/_root_scalar.py +1 -1
  276. scipy/optimize/_shgo.py +6 -0
  277. scipy/optimize/_shgo_lib/_complex.py +1 -1
  278. scipy/optimize/_slsqp_py.py +216 -124
  279. scipy/optimize/_slsqplib.cpython-313-darwin.so +0 -0
  280. scipy/optimize/_spectral.py +1 -1
  281. scipy/optimize/_tnc.py +8 -1
  282. scipy/optimize/_trlib/_trlib.cpython-313-darwin.so +0 -0
  283. scipy/optimize/_trustregion.py +20 -6
  284. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  285. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  286. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  287. scipy/optimize/_trustregion_constr/projections.py +12 -8
  288. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  289. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  290. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  291. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  292. scipy/optimize/_trustregion_exact.py +0 -1
  293. scipy/optimize/_zeros.cpython-313-darwin.so +0 -0
  294. scipy/optimize/_zeros_py.py +97 -17
  295. scipy/optimize/cython_optimize/_zeros.cpython-313-darwin.so +0 -0
  296. scipy/optimize/slsqp.py +0 -1
  297. scipy/optimize/tests/test__basinhopping.py +1 -1
  298. scipy/optimize/tests/test__differential_evolution.py +4 -4
  299. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  300. scipy/optimize/tests/test__numdiff.py +66 -22
  301. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  302. scipy/optimize/tests/test__shgo.py +9 -1
  303. scipy/optimize/tests/test_bracket.py +36 -46
  304. scipy/optimize/tests/test_chandrupatla.py +133 -135
  305. scipy/optimize/tests/test_cobyla.py +74 -45
  306. scipy/optimize/tests/test_constraints.py +1 -1
  307. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  308. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  309. scipy/optimize/tests/test_least_squares.py +125 -13
  310. scipy/optimize/tests/test_linear_assignment.py +3 -3
  311. scipy/optimize/tests/test_linprog.py +3 -3
  312. scipy/optimize/tests/test_lsq_linear.py +5 -5
  313. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  314. scipy/optimize/tests/test_minpack.py +4 -4
  315. scipy/optimize/tests/test_nnls.py +43 -3
  316. scipy/optimize/tests/test_nonlin.py +36 -0
  317. scipy/optimize/tests/test_optimize.py +95 -17
  318. scipy/optimize/tests/test_slsqp.py +36 -4
  319. scipy/optimize/tests/test_zeros.py +34 -1
  320. scipy/signal/__init__.py +12 -23
  321. scipy/signal/_delegators.py +568 -0
  322. scipy/signal/_filter_design.py +459 -241
  323. scipy/signal/_fir_filter_design.py +262 -90
  324. scipy/signal/_lti_conversion.py +3 -2
  325. scipy/signal/_ltisys.py +118 -91
  326. scipy/signal/_peak_finding_utils.cpython-313-darwin.so +0 -0
  327. scipy/signal/_polyutils.py +172 -0
  328. scipy/signal/_short_time_fft.py +519 -70
  329. scipy/signal/_signal_api.py +30 -0
  330. scipy/signal/_signaltools.py +719 -399
  331. scipy/signal/_sigtools.cpython-313-darwin.so +0 -0
  332. scipy/signal/_sosfilt.cpython-313-darwin.so +0 -0
  333. scipy/signal/_spectral_py.py +221 -50
  334. scipy/signal/_spline_filters.py +108 -68
  335. scipy/signal/_support_alternative_backends.py +73 -0
  336. scipy/signal/_upfirdn.py +4 -1
  337. scipy/signal/_upfirdn_apply.cpython-313-darwin.so +0 -0
  338. scipy/signal/_waveforms.py +2 -11
  339. scipy/signal/_wavelets.py +1 -1
  340. scipy/signal/fir_filter_design.py +1 -0
  341. scipy/signal/spline.py +4 -11
  342. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  343. scipy/signal/tests/test_bsplines.py +114 -79
  344. scipy/signal/tests/test_cont2discrete.py +9 -2
  345. scipy/signal/tests/test_filter_design.py +721 -481
  346. scipy/signal/tests/test_fir_filter_design.py +332 -140
  347. scipy/signal/tests/test_savitzky_golay.py +4 -3
  348. scipy/signal/tests/test_short_time_fft.py +221 -3
  349. scipy/signal/tests/test_signaltools.py +2144 -1348
  350. scipy/signal/tests/test_spectral.py +19 -6
  351. scipy/signal/tests/test_splines.py +161 -96
  352. scipy/signal/tests/test_upfirdn.py +84 -50
  353. scipy/signal/tests/test_waveforms.py +20 -0
  354. scipy/signal/tests/test_windows.py +607 -466
  355. scipy/signal/windows/_windows.py +287 -148
  356. scipy/sparse/__init__.py +23 -4
  357. scipy/sparse/_base.py +270 -108
  358. scipy/sparse/_bsr.py +7 -4
  359. scipy/sparse/_compressed.py +59 -231
  360. scipy/sparse/_construct.py +90 -38
  361. scipy/sparse/_coo.py +115 -181
  362. scipy/sparse/_csc.py +4 -4
  363. scipy/sparse/_csparsetools.cpython-313-darwin.so +0 -0
  364. scipy/sparse/_csr.py +2 -2
  365. scipy/sparse/_data.py +48 -48
  366. scipy/sparse/_dia.py +105 -18
  367. scipy/sparse/_dok.py +0 -23
  368. scipy/sparse/_index.py +4 -4
  369. scipy/sparse/_matrix.py +23 -0
  370. scipy/sparse/_sparsetools.cpython-313-darwin.so +0 -0
  371. scipy/sparse/_sputils.py +37 -22
  372. scipy/sparse/base.py +0 -9
  373. scipy/sparse/bsr.py +0 -14
  374. scipy/sparse/compressed.py +0 -23
  375. scipy/sparse/construct.py +0 -6
  376. scipy/sparse/coo.py +0 -14
  377. scipy/sparse/csc.py +0 -3
  378. scipy/sparse/csgraph/_flow.cpython-313-darwin.so +0 -0
  379. scipy/sparse/csgraph/_matching.cpython-313-darwin.so +0 -0
  380. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-darwin.so +0 -0
  381. scipy/sparse/csgraph/_reordering.cpython-313-darwin.so +0 -0
  382. scipy/sparse/csgraph/_shortest_path.cpython-313-darwin.so +0 -0
  383. scipy/sparse/csgraph/_tools.cpython-313-darwin.so +0 -0
  384. scipy/sparse/csgraph/_traversal.cpython-313-darwin.so +0 -0
  385. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  386. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  387. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  388. scipy/sparse/csr.py +0 -5
  389. scipy/sparse/data.py +1 -6
  390. scipy/sparse/dia.py +0 -7
  391. scipy/sparse/dok.py +0 -10
  392. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-darwin.so +0 -0
  393. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  394. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  395. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-darwin.so +0 -0
  396. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  397. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  398. scipy/sparse/linalg/_interface.py +17 -18
  399. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  400. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  401. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  402. scipy/sparse/linalg/_isolve/minres.py +5 -5
  403. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  404. scipy/sparse/linalg/_isolve/utils.py +2 -8
  405. scipy/sparse/linalg/_matfuncs.py +1 -1
  406. scipy/sparse/linalg/_norm.py +1 -1
  407. scipy/sparse/linalg/_propack/_cpropack.cpython-313-darwin.so +0 -0
  408. scipy/sparse/linalg/_propack/_dpropack.cpython-313-darwin.so +0 -0
  409. scipy/sparse/linalg/_propack/_spropack.cpython-313-darwin.so +0 -0
  410. scipy/sparse/linalg/_propack/_zpropack.cpython-313-darwin.so +0 -0
  411. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  412. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  413. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  414. scipy/sparse/tests/test_base.py +207 -42
  415. scipy/sparse/tests/test_common1d.py +7 -7
  416. scipy/sparse/tests/test_construct.py +1 -1
  417. scipy/sparse/tests/test_coo.py +272 -4
  418. scipy/sparse/tests/test_sparsetools.py +5 -0
  419. scipy/sparse/tests/test_sputils.py +36 -7
  420. scipy/spatial/_ckdtree.cpython-313-darwin.so +0 -0
  421. scipy/spatial/_hausdorff.cpython-313-darwin.so +0 -0
  422. scipy/spatial/_qhull.cpython-313-darwin.so +0 -0
  423. scipy/spatial/_voronoi.cpython-313-darwin.so +0 -0
  424. scipy/spatial/distance.py +49 -42
  425. scipy/spatial/tests/test_distance.py +3 -1
  426. scipy/spatial/tests/test_kdtree.py +1 -0
  427. scipy/spatial/tests/test_qhull.py +7 -2
  428. scipy/spatial/transform/__init__.py +5 -3
  429. scipy/spatial/transform/_rigid_transform.cpython-313-darwin.so +0 -0
  430. scipy/spatial/transform/_rotation.cpython-313-darwin.so +0 -0
  431. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  432. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  433. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  434. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  435. scipy/special/__init__.py +1 -47
  436. scipy/special/_add_newdocs.py +34 -772
  437. scipy/special/_basic.py +22 -25
  438. scipy/special/_comb.cpython-313-darwin.so +0 -0
  439. scipy/special/_ellip_harm_2.cpython-313-darwin.so +0 -0
  440. scipy/special/_gufuncs.cpython-313-darwin.so +0 -0
  441. scipy/special/_logsumexp.py +67 -58
  442. scipy/special/_orthogonal.pyi +1 -1
  443. scipy/special/_specfun.cpython-313-darwin.so +0 -0
  444. scipy/special/_special_ufuncs.cpython-313-darwin.so +0 -0
  445. scipy/special/_spherical_bessel.py +4 -4
  446. scipy/special/_support_alternative_backends.py +212 -119
  447. scipy/special/_test_internal.cpython-313-darwin.so +0 -0
  448. scipy/special/_testutils.py +4 -4
  449. scipy/special/_ufuncs.cpython-313-darwin.so +0 -0
  450. scipy/special/_ufuncs.pyi +1 -0
  451. scipy/special/_ufuncs.pyx +215 -1400
  452. scipy/special/_ufuncs_cxx.cpython-313-darwin.so +0 -0
  453. scipy/special/_ufuncs_cxx.pxd +2 -15
  454. scipy/special/_ufuncs_cxx.pyx +5 -44
  455. scipy/special/_ufuncs_cxx_defs.h +2 -16
  456. scipy/special/_ufuncs_defs.h +0 -8
  457. scipy/special/cython_special.cpython-313-darwin.so +0 -0
  458. scipy/special/cython_special.pxd +1 -1
  459. scipy/special/tests/_cython_examples/meson.build +10 -1
  460. scipy/special/tests/test_basic.py +153 -20
  461. scipy/special/tests/test_boost_ufuncs.py +3 -0
  462. scipy/special/tests/test_cdflib.py +35 -11
  463. scipy/special/tests/test_gammainc.py +16 -0
  464. scipy/special/tests/test_hyp2f1.py +2 -2
  465. scipy/special/tests/test_log1mexp.py +85 -0
  466. scipy/special/tests/test_logsumexp.py +206 -64
  467. scipy/special/tests/test_mpmath.py +1 -0
  468. scipy/special/tests/test_nan_inputs.py +1 -1
  469. scipy/special/tests/test_orthogonal.py +17 -18
  470. scipy/special/tests/test_sf_error.py +3 -2
  471. scipy/special/tests/test_sph_harm.py +6 -7
  472. scipy/special/tests/test_support_alternative_backends.py +211 -76
  473. scipy/stats/__init__.py +4 -1
  474. scipy/stats/_ansari_swilk_statistics.cpython-313-darwin.so +0 -0
  475. scipy/stats/_axis_nan_policy.py +4 -3
  476. scipy/stats/_biasedurn.cpython-313-darwin.so +0 -0
  477. scipy/stats/_continued_fraction.py +387 -0
  478. scipy/stats/_continuous_distns.py +277 -310
  479. scipy/stats/_covariance.py +6 -3
  480. scipy/stats/_discrete_distns.py +39 -32
  481. scipy/stats/_distn_infrastructure.py +39 -12
  482. scipy/stats/_distribution_infrastructure.py +900 -238
  483. scipy/stats/_entropy.py +7 -8
  484. scipy/{_lib → stats}/_finite_differences.py +1 -1
  485. scipy/stats/_hypotests.py +82 -49
  486. scipy/stats/_kde.py +53 -49
  487. scipy/stats/_ksstats.py +1 -1
  488. scipy/stats/_levy_stable/__init__.py +7 -15
  489. scipy/stats/_levy_stable/levyst.cpython-313-darwin.so +0 -0
  490. scipy/stats/_morestats.py +112 -67
  491. scipy/stats/_mstats_basic.py +13 -17
  492. scipy/stats/_mstats_extras.py +8 -8
  493. scipy/stats/_multivariate.py +89 -113
  494. scipy/stats/_new_distributions.py +97 -20
  495. scipy/stats/_page_trend_test.py +12 -5
  496. scipy/stats/_probability_distribution.py +265 -43
  497. scipy/stats/_qmc.py +14 -9
  498. scipy/stats/_qmc_cy.cpython-313-darwin.so +0 -0
  499. scipy/stats/_qmvnt.py +16 -95
  500. scipy/stats/_qmvnt_cy.cpython-313-darwin.so +0 -0
  501. scipy/stats/_quantile.py +335 -0
  502. scipy/stats/_rcont/rcont.cpython-313-darwin.so +0 -0
  503. scipy/stats/_resampling.py +4 -29
  504. scipy/stats/_sampling.py +1 -1
  505. scipy/stats/_sobol.cpython-313-darwin.so +0 -0
  506. scipy/stats/_stats.cpython-313-darwin.so +0 -0
  507. scipy/stats/_stats_mstats_common.py +19 -2
  508. scipy/stats/_stats_py.py +534 -460
  509. scipy/stats/_unuran/unuran_wrapper.cpython-313-darwin.so +0 -0
  510. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  511. scipy/stats/_variation.py +5 -7
  512. scipy/stats/_wilcoxon.py +13 -7
  513. scipy/stats/tests/common_tests.py +6 -4
  514. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  515. scipy/stats/tests/test_continued_fraction.py +173 -0
  516. scipy/stats/tests/test_continuous.py +379 -60
  517. scipy/stats/tests/test_continuous_basic.py +18 -12
  518. scipy/stats/tests/test_discrete_basic.py +14 -8
  519. scipy/stats/tests/test_discrete_distns.py +16 -16
  520. scipy/stats/tests/test_distributions.py +95 -75
  521. scipy/stats/tests/test_entropy.py +40 -48
  522. scipy/stats/tests/test_fit.py +4 -3
  523. scipy/stats/tests/test_hypotests.py +153 -24
  524. scipy/stats/tests/test_kdeoth.py +109 -41
  525. scipy/stats/tests/test_marray.py +289 -0
  526. scipy/stats/tests/test_morestats.py +79 -47
  527. scipy/stats/tests/test_mstats_basic.py +3 -3
  528. scipy/stats/tests/test_multivariate.py +434 -83
  529. scipy/stats/tests/test_qmc.py +13 -10
  530. scipy/stats/tests/test_quantile.py +199 -0
  531. scipy/stats/tests/test_rank.py +119 -112
  532. scipy/stats/tests/test_resampling.py +47 -56
  533. scipy/stats/tests/test_sampling.py +9 -4
  534. scipy/stats/tests/test_stats.py +799 -939
  535. scipy/stats/tests/test_variation.py +8 -6
  536. scipy/version.py +2 -2
  537. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  538. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +8 -8
  539. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +540 -547
  540. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  541. scipy/_lib/array_api_extra/_funcs.py +0 -484
  542. scipy/_lib/array_api_extra/_typing.py +0 -8
  543. scipy/interpolate/_bspl.cpython-313-darwin.so +0 -0
  544. scipy/optimize/_cobyla.cpython-313-darwin.so +0 -0
  545. scipy/optimize/_cython_nnls.cpython-313-darwin.so +0 -0
  546. scipy/optimize/_slsqp.cpython-313-darwin.so +0 -0
  547. scipy/spatial/qhull_src/COPYING.txt +0 -38
  548. scipy/special/libsf_error_state.dylib +0 -0
  549. scipy/special/tests/test_log_softmax.py +0 -109
  550. scipy/special/tests/test_xsf_cuda.py +0 -114
  551. scipy/special/xsf/binom.h +0 -89
  552. scipy/special/xsf/cdflib.h +0 -100
  553. scipy/special/xsf/cephes/airy.h +0 -307
  554. scipy/special/xsf/cephes/besselpoly.h +0 -51
  555. scipy/special/xsf/cephes/beta.h +0 -257
  556. scipy/special/xsf/cephes/cbrt.h +0 -131
  557. scipy/special/xsf/cephes/chbevl.h +0 -85
  558. scipy/special/xsf/cephes/chdtr.h +0 -193
  559. scipy/special/xsf/cephes/const.h +0 -87
  560. scipy/special/xsf/cephes/ellie.h +0 -293
  561. scipy/special/xsf/cephes/ellik.h +0 -251
  562. scipy/special/xsf/cephes/ellpe.h +0 -107
  563. scipy/special/xsf/cephes/ellpk.h +0 -117
  564. scipy/special/xsf/cephes/expn.h +0 -260
  565. scipy/special/xsf/cephes/gamma.h +0 -398
  566. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  567. scipy/special/xsf/cephes/hyperg.h +0 -361
  568. scipy/special/xsf/cephes/i0.h +0 -149
  569. scipy/special/xsf/cephes/i1.h +0 -158
  570. scipy/special/xsf/cephes/igam.h +0 -421
  571. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  572. scipy/special/xsf/cephes/igami.h +0 -313
  573. scipy/special/xsf/cephes/j0.h +0 -225
  574. scipy/special/xsf/cephes/j1.h +0 -198
  575. scipy/special/xsf/cephes/jv.h +0 -715
  576. scipy/special/xsf/cephes/k0.h +0 -164
  577. scipy/special/xsf/cephes/k1.h +0 -163
  578. scipy/special/xsf/cephes/kn.h +0 -243
  579. scipy/special/xsf/cephes/lanczos.h +0 -112
  580. scipy/special/xsf/cephes/ndtr.h +0 -275
  581. scipy/special/xsf/cephes/poch.h +0 -85
  582. scipy/special/xsf/cephes/polevl.h +0 -167
  583. scipy/special/xsf/cephes/psi.h +0 -194
  584. scipy/special/xsf/cephes/rgamma.h +0 -111
  585. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  586. scipy/special/xsf/cephes/shichi.h +0 -248
  587. scipy/special/xsf/cephes/sici.h +0 -224
  588. scipy/special/xsf/cephes/sindg.h +0 -221
  589. scipy/special/xsf/cephes/tandg.h +0 -139
  590. scipy/special/xsf/cephes/trig.h +0 -58
  591. scipy/special/xsf/cephes/unity.h +0 -186
  592. scipy/special/xsf/cephes/zeta.h +0 -172
  593. scipy/special/xsf/config.h +0 -304
  594. scipy/special/xsf/digamma.h +0 -205
  595. scipy/special/xsf/error.h +0 -57
  596. scipy/special/xsf/evalpoly.h +0 -47
  597. scipy/special/xsf/expint.h +0 -266
  598. scipy/special/xsf/hyp2f1.h +0 -694
  599. scipy/special/xsf/iv_ratio.h +0 -173
  600. scipy/special/xsf/lambertw.h +0 -150
  601. scipy/special/xsf/loggamma.h +0 -163
  602. scipy/special/xsf/sici.h +0 -200
  603. scipy/special/xsf/tools.h +0 -427
  604. scipy/special/xsf/trig.h +0 -164
  605. scipy/special/xsf/wright_bessel.h +0 -843
  606. scipy/special/xsf/zlog1.h +0 -35
  607. scipy/stats/_mvn.cpython-313-darwin.so +0 -0
  608. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
- from typing import (overload, Callable, NamedTuple, Protocol)
2
+ from typing import (overload, NamedTuple, Protocol)
3
+ from collections.abc import Callable
3
4
  import numpy.typing as npt
4
5
  from scipy._lib._util import SeedType
5
6
  import scipy.stats as stats
scipy/stats/_variation.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from scipy._lib._util import _get_nan
4
- from scipy._lib._array_api import array_namespace, xp_copysign
4
+ from scipy._lib._array_api import array_namespace
5
5
 
6
6
  from ._axis_nan_policy import _axis_nan_policy_factory
7
7
 
@@ -103,22 +103,20 @@ def variation(a, axis=0, nan_policy='propagate', ddof=0, *, keepdims=False):
103
103
  axis = 0
104
104
 
105
105
  n = a.shape[axis]
106
- NaN = _get_nan(a)
107
106
 
108
107
  if a.size == 0 or ddof > n:
109
108
  # Handle as a special case to avoid spurious warnings.
110
109
  # The return values, if any, are all nan.
111
- shp = list(a.shape)
112
- shp.pop(axis)
113
- result = xp.full(shp, fill_value=NaN)
114
- return result[()] if result.ndim == 0 else result
110
+ shape = list(a.shape)
111
+ shape.pop(axis)
112
+ return _get_nan(a, shape=tuple(shape), xp=xp)
115
113
 
116
114
  mean_a = xp.mean(a, axis=axis)
117
115
 
118
116
  if ddof == n:
119
117
  # Another special case. Result is either inf or nan.
120
118
  std_a = xp.std(a, axis=axis, correction=0)
121
- result = xp.where(std_a > 0, xp_copysign(xp.asarray(xp.inf), mean_a), NaN)
119
+ result = xp.where(std_a > 0, xp.copysign(xp.inf, mean_a), xp.nan)
122
120
  return result[()] if result.ndim == 0 else result
123
121
 
124
122
  with np.errstate(divide='ignore', invalid='ignore'):
scipy/stats/_wilcoxon.py CHANGED
@@ -5,7 +5,8 @@ from ._stats_py import _get_pvalue, _rankdata, _SimpleNormal
5
5
  from . import _morestats
6
6
  from ._axis_nan_policy import _broadcast_arrays
7
7
  from ._hypotests import _get_wilcoxon_distr
8
- from scipy._lib._util import _lazywhere, _get_nan
8
+ from scipy._lib._util import _get_nan
9
+ import scipy._lib.array_api_extra as xpx
9
10
 
10
11
 
11
12
  class WilcoxonDistribution:
@@ -40,13 +41,17 @@ class WilcoxonDistribution:
40
41
 
41
42
  def cdf(self, k):
42
43
  k, mn, out = self._prep(k)
43
- return _lazywhere(k <= mn, (k, self.n), self._cdf,
44
- f2=lambda k, n: 1 - self._sf(k+1, n))[()]
44
+ return xpx.apply_where(
45
+ k <= mn, (k, self.n),
46
+ self._cdf,
47
+ lambda k, n: 1 - self._sf(k+1, n))[()]
45
48
 
46
49
  def sf(self, k):
47
50
  k, mn, out = self._prep(k)
48
- return _lazywhere(k <= mn, (k, self.n), self._sf,
49
- f2=lambda k, n: 1 - self._cdf(k-1, n))[()]
51
+ return xpx.apply_where(
52
+ k <= mn, (k, self.n),
53
+ self._sf,
54
+ lambda k, n: 1 - self._cdf(k-1, n))[()]
50
55
 
51
56
 
52
57
  def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
@@ -57,6 +62,7 @@ def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
57
62
  raise ValueError(message)
58
63
 
59
64
  message = '`axis` must be compatible with the shape(s) of `x` (and `y`)'
65
+ AxisError = getattr(np, 'AxisError', None) or np.exceptions.AxisError
60
66
  try:
61
67
  if y is None:
62
68
  x = np.asarray(x)
@@ -65,8 +71,8 @@ def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
65
71
  x, y = _broadcast_arrays((x, y), axis=axis)
66
72
  d = x - y
67
73
  d = np.moveaxis(d, axis, -1)
68
- except np.AxisError as e:
69
- raise ValueError(message) from e
74
+ except AxisError as e:
75
+ raise AxisError(message) from e
70
76
 
71
77
  message = "`x` and `y` must have the same length along `axis`."
72
78
  if y is not None and x.shape[axis] != y.shape[axis]:
@@ -344,11 +344,13 @@ def check_freezing(distfn, args):
344
344
 
345
345
 
346
346
  def check_rvs_broadcast(distfunc, distname, allargs, shape, shape_only, otype):
347
- np.random.seed(123)
348
- sample = distfunc.rvs(*allargs)
347
+ rng = np.random.RandomState(123)
348
+ sample = distfunc.rvs(*allargs, random_state=rng)
349
349
  assert_equal(sample.shape, shape, f"{distname}: rvs failed to broadcast")
350
350
  if not shape_only:
351
- rvs = np.vectorize(lambda *allargs: distfunc.rvs(*allargs), otypes=otype)
352
- np.random.seed(123)
351
+ rvs = np.vectorize(
352
+ lambda *allargs: distfunc.rvs(*allargs, random_state=rng),
353
+ otypes=otype)
354
+ rng = np.random.RandomState(123)
353
355
  expected = rvs(*allargs)
354
356
  assert_allclose(sample, expected, rtol=1e-13)
@@ -56,11 +56,23 @@ def xp_var(*args, **kwargs):
56
56
  return stats._stats_py._xp_var(*args, **kwargs)
57
57
 
58
58
 
59
+ def gstd(*args, **kwargs):
60
+ kwargs.pop('_no_deco', None)
61
+ return stats.gstd(*args, **kwargs)
62
+
63
+
59
64
  def combine_pvalues_weighted(*args, **kwargs):
60
65
  return stats.combine_pvalues(args[0], *args[2:], weights=args[1],
61
66
  method='stouffer', **kwargs)
62
67
 
63
68
 
69
+ def weightedtau_weighted(x, y, rank, **kwargs):
70
+ axis = kwargs.get('axis', 0)
71
+ nan_policy = kwargs.get('nan_policy', 'propagate')
72
+ rank = stats.rankdata(rank, axis=axis, nan_policy=nan_policy)
73
+ return stats.weightedtau(x, y, rank, **kwargs)
74
+
75
+
64
76
  axis_nan_policy_cases = [
65
77
  # function, args, kwds, number of samples, number of outputs,
66
78
  # ... paired, unpacker function
@@ -133,6 +145,7 @@ axis_nan_policy_cases = [
133
145
  (stats.circvar, tuple(), dict(), 1, 1, False, lambda x: (x,)),
134
146
  (stats.circstd, tuple(), dict(), 1, 1, False, lambda x: (x,)),
135
147
  (stats.f_oneway, tuple(), {}, 2, 2, False, None),
148
+ (stats.f_oneway, tuple(), {'equal_var': False}, 2, 2, False, None),
136
149
  (stats.alexandergovern, tuple(), {}, 2, 2, False,
137
150
  lambda res: (res.statistic, res.pvalue)),
138
151
  (stats.combine_pvalues, tuple(), {}, 1, 2, False, None),
@@ -143,6 +156,24 @@ axis_nan_policy_cases = [
143
156
  (xp_var, tuple(), dict(), 1, 1, False, lambda x: (x,)),
144
157
  (stats.chatterjeexi, tuple(), dict(), 2, 2, True,
145
158
  lambda res: (res.statistic, res.pvalue)),
159
+ (stats.pointbiserialr, tuple(), dict(), 2, 3, True,
160
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
161
+ (stats.kendalltau, tuple(), dict(), 2, 3, True,
162
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
163
+ (stats.weightedtau, tuple(), dict(), 2, 3, True,
164
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
165
+ (weightedtau_weighted, tuple(), dict(), 3, 3, True,
166
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
167
+ (stats.linregress, tuple(), dict(), 2, 6, True,
168
+ lambda res: tuple(res) + (res.intercept_stderr,)),
169
+ (stats.theilslopes, tuple(), dict(), 2, 4, True, tuple),
170
+ (stats.theilslopes, tuple(), dict(), 1, 4, True, tuple),
171
+ (stats.siegelslopes, tuple(), dict(), 2, 2, True, tuple),
172
+ (stats.siegelslopes, tuple(), dict(), 1, 2, True, tuple),
173
+ (gstd, tuple(), dict(), 1, 1, False, lambda x: (x,)),
174
+ (stats.power_divergence, tuple(), dict(), 1, 2, False, None),
175
+ (stats.chisquare, tuple(), dict(), 1, 2, False, None),
176
+ (stats._morestats._boxcox_llf, tuple(), dict(lmb=1.5), 1, 1, False, lambda x: (x,)),
146
177
  ]
147
178
 
148
179
  # If the message is one of those expected, put nans in
@@ -175,6 +206,9 @@ too_small_messages = {"Degrees of freedom <= 0 for slice",
175
206
  "One or more sample arguments is too small",
176
207
  "invalid value encountered",
177
208
  "divide by zero encountered",
209
+ "`x` and `y` must have length at least 2.",
210
+ "Inputs must not be empty.",
211
+ "All `x` coordinates are identical.",
178
212
  }
179
213
 
180
214
  # If the message is one of these, results of the function may be inaccurate,
@@ -183,13 +217,13 @@ inaccuracy_messages = {"Precision loss occurred in moment calculation",
183
217
  "Sample size too small for normal approximation."}
184
218
 
185
219
  # For some functions, nan_policy='propagate' should not just return NaNs
186
- override_propagate_funcs = {stats.mode}
220
+ override_propagate_funcs = {stats.mode, weightedtau_weighted, stats.weightedtau}
187
221
 
188
222
  # For some functions, empty arrays produce non-NaN results
189
- empty_special_case_funcs = {stats.entropy}
223
+ empty_special_case_funcs = {stats.entropy, stats.chisquare, stats.power_divergence}
190
224
 
191
225
  # Some functions don't follow the usual "too small" warning rules
192
- too_small_special_case_funcs = {stats.entropy}
226
+ too_small_special_case_funcs = {stats.entropy, stats.chisquare, stats.power_divergence}
193
227
 
194
228
  def _mixed_data_generator(n_samples, n_repetitions, axis, rng,
195
229
  paired=False):
@@ -301,6 +335,7 @@ def nan_policy_1d(hypotest, data1d, unpacker, *args, n_outputs=2,
301
335
  @pytest.mark.parametrize(("nan_policy"), ("propagate", "omit", "raise"))
302
336
  @pytest.mark.parametrize(("axis"), (1,))
303
337
  @pytest.mark.parametrize(("data_generator"), ("mixed",))
338
+ @pytest.mark.parallel_threads(1)
304
339
  def test_axis_nan_policy_fast(hypotest, args, kwds, n_samples, n_outputs,
305
340
  paired, unpacker, nan_policy, axis,
306
341
  data_generator):
@@ -413,7 +448,7 @@ def _axis_nan_policy_test(hypotest, args, kwds, n_samples, n_outputs, paired,
413
448
  n_outputs=n_outputs,
414
449
  nan_policy=nan_policy,
415
450
  paired=paired, _no_deco=True, **kwds)
416
- except (ValueError, RuntimeWarning, ZeroDivisionError) as ea:
451
+ except (ValueError, RuntimeWarning, ZeroDivisionError, UserWarning) as ea:
417
452
  ea_str = str(ea)
418
453
  if any([str(ea_str).startswith(msg) for msg in too_small_messages]):
419
454
  res_1da = np.full(n_outputs, np.nan)
@@ -472,6 +507,7 @@ def _axis_nan_policy_test(hypotest, args, kwds, n_samples, n_outputs, paired,
472
507
  @pytest.mark.parametrize(("nan_policy"), ("propagate", "omit", "raise"))
473
508
  @pytest.mark.parametrize(("data_generator"),
474
509
  ("all_nans", "all_finite", "mixed", "empty"))
510
+ @pytest.mark.parallel_threads(1)
475
511
  def test_axis_nan_policy_axis_is_None(hypotest, args, kwds, n_samples,
476
512
  n_outputs, paired, unpacker, nan_policy,
477
513
  data_generator):
@@ -524,7 +560,7 @@ def test_axis_nan_policy_axis_is_None(hypotest, args, kwds, n_samples,
524
560
  res1da = nan_policy_1d(hypotest, data_raveled, unpacker, *args,
525
561
  n_outputs=n_outputs, nan_policy=nan_policy,
526
562
  paired=paired, _no_deco=True, **kwds)
527
- except (RuntimeWarning, ValueError, ZeroDivisionError) as ea:
563
+ except (RuntimeWarning, ValueError, ZeroDivisionError, UserWarning) as ea:
528
564
  res1da = None
529
565
  ea_str = str(ea)
530
566
 
@@ -594,6 +630,8 @@ def test_keepdims(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker,
594
630
  stats.differential_entropy}
595
631
  if sample_shape == (2, 3, 3, 4) and hypotest in small_sample_raises:
596
632
  pytest.skip("Sample too small; test raises error.")
633
+ if hypotest in {weightedtau_weighted}:
634
+ pytest.skip("`rankdata` used in testing doesn't support axis tuple.")
597
635
  # test if keepdims parameter works correctly
598
636
  if not unpacker:
599
637
  def unpacker(res):
@@ -787,6 +825,7 @@ def _check_arrays_broadcastable(arrays, axis):
787
825
  @pytest.mark.slow
788
826
  @pytest.mark.parametrize(("hypotest", "args", "kwds", "n_samples", "n_outputs",
789
827
  "paired", "unpacker"), axis_nan_policy_cases)
828
+ @pytest.mark.parallel_threads(1)
790
829
  def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
791
830
  # test for correct output shape when at least one input is empty
792
831
  if hypotest in {stats.kruskal, stats.friedmanchisquare} and not SCIPY_XSLOW:
@@ -834,15 +873,16 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
834
873
  sup.filter(RuntimeWarning, "Mean of empty slice.")
835
874
  sup.filter(RuntimeWarning, "invalid value encountered")
836
875
  expected = np.mean(concat, axis=axis) * np.nan
876
+ mask = np.isnan(expected)
877
+ expected = [np.asarray(expected.copy()) for i in range(n_outputs)]
837
878
 
838
879
  if hypotest in empty_special_case_funcs:
839
880
  empty_val = hypotest(*([[]]*len(samples)), *args, **kwds)
840
- expected = np.asarray(expected)
841
- mask = np.isnan(expected)
842
- expected[mask] = empty_val
843
- expected = expected[()]
881
+ empty_val = list(unpacker(empty_val))
882
+ for i in range(n_outputs):
883
+ expected[i][mask] = empty_val[i]
844
884
 
845
- if expected.size and hypotest not in too_small_special_case_funcs:
885
+ if expected[0].size and hypotest not in too_small_special_case_funcs:
846
886
  message = (too_small_1d_not_omit if max_axis == 1
847
887
  else too_small_nd_not_omit)
848
888
  with pytest.warns(SmallSampleWarning, match=message):
@@ -855,7 +895,7 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
855
895
  res = unpacker(res)
856
896
 
857
897
  for i in range(n_outputs):
858
- assert_equal(res[i], expected)
898
+ assert_equal(res[i], expected[i])
859
899
 
860
900
  except ValueError:
861
901
  # confirm that the arrays truly are not broadcastable
@@ -872,22 +912,21 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
872
912
 
873
913
 
874
914
  def paired_non_broadcastable_cases():
875
- rng = np.random.default_rng(91359824598245)
876
915
  for case in axis_nan_policy_cases:
877
916
  hypotest, args, kwds, n_samples, n_outputs, paired, unpacker = case
878
917
  if n_samples == 1: # broadcasting only needed with >1 sample
879
918
  continue
880
- yield case + (rng,)
919
+ yield case
881
920
 
882
921
 
883
922
  @pytest.mark.parametrize("axis", [0, 1])
884
923
  @pytest.mark.parametrize(("hypotest", "args", "kwds", "n_samples", "n_outputs",
885
- "paired", "unpacker", "rng"),
924
+ "paired", "unpacker"),
886
925
  paired_non_broadcastable_cases())
887
926
  def test_non_broadcastable(hypotest, args, kwds, n_samples, n_outputs, paired,
888
- unpacker, rng, axis):
927
+ unpacker, axis):
889
928
  # test for correct error message when shapes are not broadcastable
890
-
929
+ rng = np.random.default_rng(91359824598245)
891
930
  get_samples = True
892
931
  while get_samples:
893
932
  samples = [rng.random(size=rng.integers(2, 100, size=2))
@@ -913,7 +952,6 @@ def test_non_broadcastable(hypotest, args, kwds, n_samples, n_outputs, paired,
913
952
  with pytest.raises(ValueError, match=message):
914
953
  hypotest(other_sample, *most_samples, *args, **kwds)
915
954
 
916
-
917
955
  def test_masked_array_2_sentinel_array():
918
956
  # prepare arrays
919
957
  np.random.seed(0)
@@ -1078,13 +1116,13 @@ def test_mixed_mask_nan_1():
1078
1116
  m, n = 3, 20
1079
1117
  axis = -1
1080
1118
 
1081
- np.random.seed(0)
1082
- a = np.random.rand(m, n)
1083
- b = np.random.rand(m, n)
1084
- mask_a1 = np.random.rand(m, n) < 0.2
1085
- mask_a2 = np.random.rand(m, n) < 0.1
1086
- mask_b1 = np.random.rand(m, n) < 0.15
1087
- mask_b2 = np.random.rand(m, n) < 0.15
1119
+ rng = np.random.RandomState(0)
1120
+ a = rng.rand(m, n)
1121
+ b = rng.rand(m, n)
1122
+ mask_a1 = rng.rand(m, n) < 0.2
1123
+ mask_a2 = rng.rand(m, n) < 0.1
1124
+ mask_b1 = rng.rand(m, n) < 0.15
1125
+ mask_b2 = rng.rand(m, n) < 0.15
1088
1126
  mask_a1[2, :] = True
1089
1127
 
1090
1128
  a_nans = a.copy()
@@ -0,0 +1,173 @@
1
+ import math
2
+
3
+ import pytest
4
+ import numpy as np
5
+
6
+ from scipy._lib._array_api import array_namespace
7
+ from scipy._lib._array_api_no_0d import xp_assert_close, xp_assert_less, xp_assert_equal
8
+ from scipy.stats._continued_fraction import _continued_fraction
9
+
10
+
11
+ @pytest.mark.skip_xp_backends('array_api_strict', reason='No fancy indexing assignment')
12
+ @pytest.mark.skip_xp_backends('jax.numpy', reason="Don't support mutation")
13
+ # dask doesn't like lines like this
14
+ # n = int(xp.real(xp_ravel(n))[0])
15
+ # (at some point in here the shape becomes nan)
16
+ @pytest.mark.skip_xp_backends('dask.array', reason="dask has issues with the shapes")
17
+ class TestContinuedFraction:
18
+ rng = np.random.default_rng(5895448232066142650)
19
+ p = rng.uniform(1, 10, size=10)
20
+
21
+ def a1(self, n, x=1.5):
22
+ if n == 0:
23
+ y = 0*x
24
+ elif n == 1:
25
+ y = x
26
+ else:
27
+ y = -x**2
28
+ if np.isscalar(y) and np.__version__ < "2.0":
29
+ y = np.full_like(x, y) # preserve dtype pre NEP 50
30
+ return y
31
+
32
+ def b1(self, n, x=1.5):
33
+ if n == 0:
34
+ y = 0*x
35
+ else:
36
+ one = x/x # gets array of correct type, dtype, and shape
37
+ y = one * (2*n - 1)
38
+ if np.isscalar(y) and np.__version__ < "2.0":
39
+ y = np.full_like(x, y) # preserve dtype pre NEP 50
40
+ return y
41
+
42
+ def log_a1(self, n, x):
43
+ xp = array_namespace(x)
44
+ if n == 0:
45
+ y = xp.full_like(x, -xp.asarray(math.inf, dtype=x.dtype))
46
+ elif n == 1:
47
+ y = xp.log(x)
48
+ else:
49
+ y = 2 * xp.log(x) + math.pi * 1j
50
+ return y
51
+
52
+ def log_b1(self, n, x):
53
+ xp = array_namespace(x)
54
+ if n == 0:
55
+ y = xp.full_like(x, -xp.asarray(math.inf, dtype=x.dtype))
56
+ else:
57
+ one = x - x # gets array of correct type, dtype, and shape
58
+ y = one + math.log(2 * n - 1)
59
+ return y
60
+
61
+ def test_input_validation(self, xp):
62
+ a1 = self.a1
63
+ b1 = self.b1
64
+
65
+ message = '`a` and `b` must be callable.'
66
+ with pytest.raises(ValueError, match=message):
67
+ _continued_fraction(1, b1)
68
+ with pytest.raises(ValueError, match=message):
69
+ _continued_fraction(a1, 1)
70
+
71
+ message = r'`eps` and `tiny` must be \(or represent the logarithm of\)...'
72
+ with pytest.raises(ValueError, match=message):
73
+ _continued_fraction(a1, b1, tolerances={'eps': -10})
74
+ with pytest.raises(ValueError, match=message):
75
+ _continued_fraction(a1, b1, tolerances={'eps': np.nan})
76
+ with pytest.raises(ValueError, match=message):
77
+ _continued_fraction(a1, b1, tolerances={'eps': 1+1j}, log=True)
78
+ with pytest.raises(ValueError, match=message):
79
+ _continued_fraction(a1, b1, tolerances={'tiny': 0})
80
+ with pytest.raises(ValueError, match=message):
81
+ _continued_fraction(a1, b1, tolerances={'tiny': np.inf})
82
+ with pytest.raises(ValueError, match=message):
83
+ _continued_fraction(a1, b1, tolerances={'tiny': np.inf}, log=True)
84
+ # this should not raise
85
+ kwargs = dict(args=xp.asarray(1.5+0j), log=True, maxiter=0)
86
+ _continued_fraction(a1, b1, tolerances={'eps': -10}, **kwargs)
87
+ _continued_fraction(a1, b1, tolerances={'tiny': -10}, **kwargs)
88
+
89
+ message = '`maxiter` must be a non-negative integer.'
90
+ with pytest.raises(ValueError, match=message):
91
+ _continued_fraction(a1, b1, maxiter=-1)
92
+
93
+ message = '`log` must be boolean.'
94
+ with pytest.raises(ValueError, match=message):
95
+ _continued_fraction(a1, b1, log=2)
96
+
97
+ @pytest.mark.parametrize('dtype', ['float32', 'float64', 'complex64', 'complex128'])
98
+ @pytest.mark.parametrize('shape', [(), (1,), (3,), (3, 2)])
99
+ def test_basic(self, shape, dtype, xp):
100
+ np_dtype = getattr(np, dtype)
101
+ xp_dtype = getattr(xp, dtype)
102
+ rng = np.random.default_rng(2435908729190400)
103
+
104
+ x = rng.random(shape).astype(np_dtype)
105
+ x = x + rng.random(shape).astype(np_dtype)*1j if dtype.startswith('c') else x
106
+ x = xp.asarray(x, dtype=xp_dtype)
107
+
108
+ res = _continued_fraction(self.a1, self.b1, args=(x,))
109
+ ref = xp.tan(x)
110
+ xp_assert_close(res.f, ref)
111
+
112
+ @pytest.mark.skip_xp_backends('torch', reason='pytorch/pytorch#136063')
113
+ @pytest.mark.parametrize('dtype', ['float32', 'float64'])
114
+ @pytest.mark.parametrize('shape', [(), (1,), (3,), (3, 2)])
115
+ def test_log(self, shape, dtype, xp):
116
+ if (np.__version__ < "2") and (dtype == 'float32'):
117
+ pytest.skip("Scalar dtypes only respected after NEP 50.")
118
+ np_dtype = getattr(np, dtype)
119
+ rng = np.random.default_rng(2435908729190400)
120
+ x = rng.random(shape).astype(np_dtype)
121
+ x = xp.asarray(x)
122
+
123
+ res = _continued_fraction(self.log_a1, self.log_b1, args=(x + 0j,), log=True)
124
+ ref = xp.tan(x)
125
+ xp_assert_close(xp.exp(xp.real(res.f)), ref)
126
+
127
+ def test_maxiter(self, xp):
128
+ rng = np.random.default_rng(2435908729190400)
129
+ x = xp.asarray(rng.random(), dtype=xp.float64)
130
+ ref = xp.tan(x)
131
+
132
+ res1 = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=3)
133
+ assert res1.nit == 3
134
+
135
+ res2 = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=6)
136
+ assert res2.nit == 6
137
+
138
+ xp_assert_less(xp.abs(res2.f - ref), xp.abs(res1.f - ref))
139
+
140
+ def test_eps(self, xp):
141
+ x = xp.asarray(1.5, dtype=xp.float64) # x = 1.5 is the default defined above
142
+ ref = xp.tan(x)
143
+ res1 = _continued_fraction(self.a1, self.b1, args=(x,),
144
+ tolerances={'eps': 1e-6})
145
+ res2 = _continued_fraction(self.a1, self.b1, args=(x,))
146
+ xp_assert_less(res1.nit, res2.nit)
147
+ xp_assert_less(xp.abs(res2.f - ref), xp.abs(res1.f - ref))
148
+
149
+ def test_feval(self, xp):
150
+ def a(n, x):
151
+ a.nfev += 1
152
+ return n * x
153
+
154
+ def b(n, x):
155
+ b.nfev += 1
156
+ return n * x
157
+
158
+ a.nfev, b.nfev = 0, 0
159
+
160
+ res = _continued_fraction(a, b, args=(xp.asarray(1.),))
161
+ assert res.nfev == a.nfev == b.nfev == res.nit + 1
162
+
163
+ def test_status(self, xp):
164
+ x = xp.asarray([1, 10, np.nan], dtype=xp.float64)
165
+ res = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=15)
166
+ xp_assert_equal(res.success, xp.asarray([True, False, False]))
167
+ xp_assert_equal(res.status, xp.asarray([0, -2, -3], dtype=xp.int32))
168
+
169
+ def test_special_cases(self, xp):
170
+ one = xp.asarray(1)
171
+ res = _continued_fraction(lambda x: one, lambda x: one, maxiter=0)
172
+ xp_assert_close(res.f, xp.asarray(1.))
173
+ assert res.nit == res.nfev - 1 == 0