scipy 1.15.3__cp313-cp313t-macosx_14_0_arm64.whl → 1.16.0rc2__cp313-cp313t-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (627) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  12. scipy/_lib/_testutils.py +6 -2
  13. scipy/_lib/_util.py +222 -125
  14. scipy/_lib/array_api_compat/__init__.py +4 -4
  15. scipy/_lib/array_api_compat/_internal.py +19 -6
  16. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  17. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  18. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  19. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  20. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  21. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  22. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  23. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  24. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  25. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  26. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  27. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  28. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  29. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  30. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  31. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  32. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  33. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  34. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  35. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  36. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  37. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  38. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  39. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  40. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  41. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  42. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  43. scipy/_lib/array_api_extra/__init__.py +26 -3
  44. scipy/_lib/array_api_extra/_delegation.py +171 -0
  45. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  46. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  47. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  48. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  49. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  50. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  51. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  57. scipy/_lib/array_api_extra/testing.py +359 -0
  58. scipy/_lib/decorator.py +2 -2
  59. scipy/_lib/doccer.py +1 -7
  60. scipy/_lib/messagestream.cpython-313t-darwin.so +0 -0
  61. scipy/_lib/pyprima/__init__.py +212 -0
  62. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  63. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  64. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  65. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  66. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  67. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  68. scipy/_lib/pyprima/cobyla/update.py +289 -0
  69. scipy/_lib/pyprima/common/__init__.py +0 -0
  70. scipy/_lib/pyprima/common/_bounds.py +34 -0
  71. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  72. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  73. scipy/_lib/pyprima/common/_project.py +173 -0
  74. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  75. scipy/_lib/pyprima/common/consts.py +47 -0
  76. scipy/_lib/pyprima/common/evaluate.py +99 -0
  77. scipy/_lib/pyprima/common/history.py +38 -0
  78. scipy/_lib/pyprima/common/infos.py +30 -0
  79. scipy/_lib/pyprima/common/linalg.py +435 -0
  80. scipy/_lib/pyprima/common/message.py +290 -0
  81. scipy/_lib/pyprima/common/powalg.py +131 -0
  82. scipy/_lib/pyprima/common/preproc.py +277 -0
  83. scipy/_lib/pyprima/common/present.py +5 -0
  84. scipy/_lib/pyprima/common/ratio.py +54 -0
  85. scipy/_lib/pyprima/common/redrho.py +47 -0
  86. scipy/_lib/pyprima/common/selectx.py +296 -0
  87. scipy/_lib/tests/test__util.py +105 -121
  88. scipy/_lib/tests/test_array_api.py +166 -35
  89. scipy/_lib/tests/test_bunch.py +7 -0
  90. scipy/_lib/tests/test_ccallback.py +2 -10
  91. scipy/_lib/tests/test_public_api.py +13 -0
  92. scipy/cluster/_hierarchy.cpython-313t-darwin.so +0 -0
  93. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  94. scipy/cluster/_vq.cpython-313t-darwin.so +0 -0
  95. scipy/cluster/hierarchy.py +393 -223
  96. scipy/cluster/tests/test_hierarchy.py +273 -335
  97. scipy/cluster/tests/test_vq.py +45 -61
  98. scipy/cluster/vq.py +39 -35
  99. scipy/conftest.py +263 -157
  100. scipy/constants/_constants.py +4 -1
  101. scipy/constants/tests/test_codata.py +2 -2
  102. scipy/constants/tests/test_constants.py +11 -18
  103. scipy/datasets/_download_all.py +15 -1
  104. scipy/datasets/_fetchers.py +7 -1
  105. scipy/datasets/_utils.py +1 -1
  106. scipy/differentiate/_differentiate.py +25 -25
  107. scipy/differentiate/tests/test_differentiate.py +24 -25
  108. scipy/fft/_basic.py +20 -0
  109. scipy/fft/_helper.py +3 -34
  110. scipy/fft/_pocketfft/helper.py +29 -1
  111. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  112. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  113. scipy/fft/_realtransforms.py +13 -0
  114. scipy/fft/tests/test_basic.py +27 -25
  115. scipy/fft/tests/test_fftlog.py +16 -7
  116. scipy/fft/tests/test_helper.py +18 -34
  117. scipy/fft/tests/test_real_transforms.py +8 -10
  118. scipy/fftpack/convolve.cpython-313t-darwin.so +0 -0
  119. scipy/fftpack/tests/test_basic.py +2 -4
  120. scipy/fftpack/tests/test_real_transforms.py +8 -9
  121. scipy/integrate/_bvp.py +9 -3
  122. scipy/integrate/_cubature.py +3 -2
  123. scipy/integrate/_dop.cpython-313t-darwin.so +0 -0
  124. scipy/integrate/_lsoda.cpython-313t-darwin.so +0 -0
  125. scipy/integrate/_ode.py +9 -2
  126. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  127. scipy/integrate/_quad_vec.py +21 -29
  128. scipy/integrate/_quadpack.cpython-313t-darwin.so +0 -0
  129. scipy/integrate/_quadpack_py.py +11 -7
  130. scipy/integrate/_quadrature.py +3 -3
  131. scipy/integrate/_rules/_base.py +2 -2
  132. scipy/integrate/_tanhsinh.py +48 -47
  133. scipy/integrate/_test_odeint_banded.cpython-313t-darwin.so +0 -0
  134. scipy/integrate/_vode.cpython-313t-darwin.so +0 -0
  135. scipy/integrate/tests/test__quad_vec.py +0 -6
  136. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  137. scipy/integrate/tests/test_cubature.py +21 -35
  138. scipy/integrate/tests/test_quadrature.py +6 -8
  139. scipy/integrate/tests/test_tanhsinh.py +56 -48
  140. scipy/interpolate/__init__.py +70 -58
  141. scipy/interpolate/_bary_rational.py +22 -22
  142. scipy/interpolate/_bsplines.py +119 -66
  143. scipy/interpolate/_cubic.py +65 -50
  144. scipy/interpolate/_dfitpack.cpython-313t-darwin.so +0 -0
  145. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  146. scipy/interpolate/_fitpack.cpython-313t-darwin.so +0 -0
  147. scipy/interpolate/_fitpack2.py +9 -6
  148. scipy/interpolate/_fitpack_impl.py +32 -26
  149. scipy/interpolate/_fitpack_repro.py +23 -19
  150. scipy/interpolate/_interpnd.cpython-313t-darwin.so +0 -0
  151. scipy/interpolate/_interpolate.py +30 -12
  152. scipy/interpolate/_ndbspline.py +13 -18
  153. scipy/interpolate/_ndgriddata.py +5 -8
  154. scipy/interpolate/_polyint.py +95 -31
  155. scipy/interpolate/_ppoly.cpython-313t-darwin.so +0 -0
  156. scipy/interpolate/_rbf.py +2 -2
  157. scipy/interpolate/_rbfinterp.py +1 -1
  158. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  159. scipy/interpolate/_rgi.py +31 -26
  160. scipy/interpolate/_rgi_cython.cpython-313t-darwin.so +0 -0
  161. scipy/interpolate/dfitpack.py +0 -20
  162. scipy/interpolate/interpnd.py +1 -2
  163. scipy/interpolate/tests/test_bary_rational.py +2 -2
  164. scipy/interpolate/tests/test_bsplines.py +97 -1
  165. scipy/interpolate/tests/test_fitpack2.py +39 -1
  166. scipy/interpolate/tests/test_interpnd.py +32 -20
  167. scipy/interpolate/tests/test_interpolate.py +48 -4
  168. scipy/interpolate/tests/test_rgi.py +2 -1
  169. scipy/io/_fast_matrix_market/__init__.py +2 -0
  170. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  171. scipy/io/_harwell_boeing/hb.py +7 -11
  172. scipy/io/_idl.py +5 -7
  173. scipy/io/_netcdf.py +15 -5
  174. scipy/io/_test_fortran.cpython-313t-darwin.so +0 -0
  175. scipy/io/arff/tests/test_arffread.py +3 -3
  176. scipy/io/matlab/__init__.py +5 -3
  177. scipy/io/matlab/_mio.py +4 -1
  178. scipy/io/matlab/_mio5.py +19 -13
  179. scipy/io/matlab/_mio5_utils.cpython-313t-darwin.so +0 -0
  180. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  181. scipy/io/matlab/_miobase.py +4 -1
  182. scipy/io/matlab/_streams.cpython-313t-darwin.so +0 -0
  183. scipy/io/matlab/tests/test_mio.py +46 -18
  184. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  185. scipy/io/tests/test_mmio.py +7 -1
  186. scipy/io/tests/test_wavfile.py +41 -0
  187. scipy/io/wavfile.py +57 -10
  188. scipy/linalg/_basic.py +113 -86
  189. scipy/linalg/_cythonized_array_utils.cpython-313t-darwin.so +0 -0
  190. scipy/linalg/_decomp.py +22 -9
  191. scipy/linalg/_decomp_cholesky.py +28 -13
  192. scipy/linalg/_decomp_cossin.py +45 -30
  193. scipy/linalg/_decomp_interpolative.cpython-313t-darwin.so +0 -0
  194. scipy/linalg/_decomp_ldl.py +4 -1
  195. scipy/linalg/_decomp_lu.py +18 -6
  196. scipy/linalg/_decomp_lu_cython.cpython-313t-darwin.so +0 -0
  197. scipy/linalg/_decomp_polar.py +2 -0
  198. scipy/linalg/_decomp_qr.py +6 -2
  199. scipy/linalg/_decomp_qz.py +3 -0
  200. scipy/linalg/_decomp_schur.py +3 -1
  201. scipy/linalg/_decomp_svd.py +13 -2
  202. scipy/linalg/_decomp_update.cpython-313t-darwin.so +0 -0
  203. scipy/linalg/_expm_frechet.py +4 -0
  204. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  205. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  206. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  207. scipy/linalg/_matfuncs.py +187 -4
  208. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  209. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  210. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  211. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  212. scipy/linalg/_procrustes.py +2 -0
  213. scipy/linalg/_sketches.py +17 -6
  214. scipy/linalg/_solve_toeplitz.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_solvers.py +7 -2
  216. scipy/linalg/_special_matrices.py +26 -36
  217. scipy/linalg/cython_blas.cpython-313t-darwin.so +0 -0
  218. scipy/linalg/cython_lapack.cpython-313t-darwin.so +0 -0
  219. scipy/linalg/lapack.py +22 -2
  220. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  221. scipy/linalg/tests/test_basic.py +31 -16
  222. scipy/linalg/tests/test_batch.py +588 -0
  223. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  224. scipy/linalg/tests/test_decomp.py +40 -3
  225. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  226. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  227. scipy/linalg/tests/test_lapack.py +115 -7
  228. scipy/linalg/tests/test_matfuncs.py +157 -102
  229. scipy/linalg/tests/test_procrustes.py +0 -7
  230. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  231. scipy/linalg/tests/test_special_matrices.py +1 -5
  232. scipy/ndimage/__init__.py +1 -0
  233. scipy/ndimage/_cytest.cpython-313t-darwin.so +0 -0
  234. scipy/ndimage/_delegators.py +8 -2
  235. scipy/ndimage/_filters.py +453 -5
  236. scipy/ndimage/_interpolation.py +36 -6
  237. scipy/ndimage/_measurements.py +4 -2
  238. scipy/ndimage/_morphology.py +5 -0
  239. scipy/ndimage/_nd_image.cpython-313t-darwin.so +0 -0
  240. scipy/ndimage/_ni_docstrings.py +5 -1
  241. scipy/ndimage/_ni_label.cpython-313t-darwin.so +0 -0
  242. scipy/ndimage/_ni_support.py +1 -5
  243. scipy/ndimage/_rank_filter_1d.cpython-313t-darwin.so +0 -0
  244. scipy/ndimage/_support_alternative_backends.py +18 -6
  245. scipy/ndimage/tests/test_filters.py +370 -259
  246. scipy/ndimage/tests/test_fourier.py +7 -9
  247. scipy/ndimage/tests/test_interpolation.py +68 -61
  248. scipy/ndimage/tests/test_measurements.py +18 -35
  249. scipy/ndimage/tests/test_morphology.py +143 -131
  250. scipy/ndimage/tests/test_splines.py +1 -3
  251. scipy/odr/__odrpack.cpython-313t-darwin.so +0 -0
  252. scipy/optimize/_basinhopping.py +13 -7
  253. scipy/optimize/_bglu_dense.cpython-313t-darwin.so +0 -0
  254. scipy/optimize/_bracket.py +17 -24
  255. scipy/optimize/_chandrupatla.py +9 -10
  256. scipy/optimize/_cobyla_py.py +104 -123
  257. scipy/optimize/_constraints.py +14 -10
  258. scipy/optimize/_differentiable_functions.py +371 -230
  259. scipy/optimize/_differentialevolution.py +4 -3
  260. scipy/optimize/_direct.cpython-313t-darwin.so +0 -0
  261. scipy/optimize/_dual_annealing.py +1 -1
  262. scipy/optimize/_elementwise.py +1 -4
  263. scipy/optimize/_group_columns.cpython-313t-darwin.so +0 -0
  264. scipy/optimize/_lbfgsb.cpython-313t-darwin.so +0 -0
  265. scipy/optimize/_lbfgsb_py.py +57 -16
  266. scipy/optimize/_linprog_doc.py +2 -2
  267. scipy/optimize/_linprog_highs.py +2 -2
  268. scipy/optimize/_linprog_ip.py +25 -10
  269. scipy/optimize/_linprog_util.py +14 -16
  270. scipy/optimize/_lsap.cpython-313t-darwin.so +0 -0
  271. scipy/optimize/_lsq/common.py +3 -3
  272. scipy/optimize/_lsq/dogbox.py +16 -2
  273. scipy/optimize/_lsq/givens_elimination.cpython-313t-darwin.so +0 -0
  274. scipy/optimize/_lsq/least_squares.py +198 -126
  275. scipy/optimize/_lsq/lsq_linear.py +6 -6
  276. scipy/optimize/_lsq/trf.py +35 -8
  277. scipy/optimize/_milp.py +3 -1
  278. scipy/optimize/_minimize.py +105 -36
  279. scipy/optimize/_minpack.cpython-313t-darwin.so +0 -0
  280. scipy/optimize/_minpack_py.py +21 -14
  281. scipy/optimize/_moduleTNC.cpython-313t-darwin.so +0 -0
  282. scipy/optimize/_nnls.py +20 -21
  283. scipy/optimize/_nonlin.py +34 -3
  284. scipy/optimize/_numdiff.py +288 -110
  285. scipy/optimize/_optimize.py +86 -48
  286. scipy/optimize/_pava_pybind.cpython-313t-darwin.so +0 -0
  287. scipy/optimize/_remove_redundancy.py +5 -5
  288. scipy/optimize/_root_scalar.py +1 -1
  289. scipy/optimize/_shgo.py +6 -0
  290. scipy/optimize/_shgo_lib/_complex.py +1 -1
  291. scipy/optimize/_slsqp_py.py +216 -124
  292. scipy/optimize/_slsqplib.cpython-313t-darwin.so +0 -0
  293. scipy/optimize/_spectral.py +1 -1
  294. scipy/optimize/_tnc.py +8 -1
  295. scipy/optimize/_trlib/_trlib.cpython-313t-darwin.so +0 -0
  296. scipy/optimize/_trustregion.py +20 -6
  297. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  298. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  299. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  300. scipy/optimize/_trustregion_constr/projections.py +12 -8
  301. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  302. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  303. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  304. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  305. scipy/optimize/_trustregion_exact.py +0 -1
  306. scipy/optimize/_zeros.cpython-313t-darwin.so +0 -0
  307. scipy/optimize/_zeros_py.py +97 -17
  308. scipy/optimize/cython_optimize/_zeros.cpython-313t-darwin.so +0 -0
  309. scipy/optimize/slsqp.py +0 -1
  310. scipy/optimize/tests/test__basinhopping.py +1 -1
  311. scipy/optimize/tests/test__differential_evolution.py +4 -4
  312. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  313. scipy/optimize/tests/test__numdiff.py +66 -22
  314. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  315. scipy/optimize/tests/test__shgo.py +9 -1
  316. scipy/optimize/tests/test_bracket.py +36 -46
  317. scipy/optimize/tests/test_chandrupatla.py +133 -135
  318. scipy/optimize/tests/test_cobyla.py +74 -45
  319. scipy/optimize/tests/test_constraints.py +1 -1
  320. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  321. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  322. scipy/optimize/tests/test_least_squares.py +125 -13
  323. scipy/optimize/tests/test_linear_assignment.py +3 -3
  324. scipy/optimize/tests/test_linprog.py +3 -3
  325. scipy/optimize/tests/test_lsq_linear.py +6 -6
  326. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  327. scipy/optimize/tests/test_minpack.py +4 -4
  328. scipy/optimize/tests/test_nnls.py +43 -3
  329. scipy/optimize/tests/test_nonlin.py +36 -0
  330. scipy/optimize/tests/test_optimize.py +95 -17
  331. scipy/optimize/tests/test_slsqp.py +36 -4
  332. scipy/optimize/tests/test_zeros.py +34 -1
  333. scipy/signal/__init__.py +12 -23
  334. scipy/signal/_delegators.py +568 -0
  335. scipy/signal/_filter_design.py +459 -241
  336. scipy/signal/_fir_filter_design.py +262 -90
  337. scipy/signal/_lti_conversion.py +3 -2
  338. scipy/signal/_ltisys.py +118 -91
  339. scipy/signal/_max_len_seq_inner.cpython-313t-darwin.so +0 -0
  340. scipy/signal/_peak_finding_utils.cpython-313t-darwin.so +0 -0
  341. scipy/signal/_polyutils.py +172 -0
  342. scipy/signal/_short_time_fft.py +519 -70
  343. scipy/signal/_signal_api.py +30 -0
  344. scipy/signal/_signaltools.py +719 -399
  345. scipy/signal/_sigtools.cpython-313t-darwin.so +0 -0
  346. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  347. scipy/signal/_spectral_py.py +230 -50
  348. scipy/signal/_spline.cpython-313t-darwin.so +0 -0
  349. scipy/signal/_spline_filters.py +108 -68
  350. scipy/signal/_support_alternative_backends.py +73 -0
  351. scipy/signal/_upfirdn.py +4 -1
  352. scipy/signal/_upfirdn_apply.cpython-313t-darwin.so +0 -0
  353. scipy/signal/_waveforms.py +2 -11
  354. scipy/signal/_wavelets.py +1 -1
  355. scipy/signal/fir_filter_design.py +1 -0
  356. scipy/signal/spline.py +4 -11
  357. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  358. scipy/signal/tests/test_bsplines.py +114 -79
  359. scipy/signal/tests/test_cont2discrete.py +9 -2
  360. scipy/signal/tests/test_filter_design.py +721 -481
  361. scipy/signal/tests/test_fir_filter_design.py +332 -140
  362. scipy/signal/tests/test_savitzky_golay.py +4 -3
  363. scipy/signal/tests/test_short_time_fft.py +221 -3
  364. scipy/signal/tests/test_signaltools.py +2144 -1348
  365. scipy/signal/tests/test_spectral.py +50 -6
  366. scipy/signal/tests/test_splines.py +161 -96
  367. scipy/signal/tests/test_upfirdn.py +84 -50
  368. scipy/signal/tests/test_waveforms.py +20 -0
  369. scipy/signal/tests/test_windows.py +607 -466
  370. scipy/signal/windows/_windows.py +287 -148
  371. scipy/sparse/__init__.py +23 -4
  372. scipy/sparse/_base.py +270 -108
  373. scipy/sparse/_bsr.py +7 -4
  374. scipy/sparse/_compressed.py +59 -231
  375. scipy/sparse/_construct.py +90 -38
  376. scipy/sparse/_coo.py +115 -181
  377. scipy/sparse/_csc.py +4 -4
  378. scipy/sparse/_csparsetools.cpython-313t-darwin.so +0 -0
  379. scipy/sparse/_csr.py +2 -2
  380. scipy/sparse/_data.py +48 -48
  381. scipy/sparse/_dia.py +105 -18
  382. scipy/sparse/_dok.py +0 -23
  383. scipy/sparse/_index.py +4 -4
  384. scipy/sparse/_matrix.py +23 -0
  385. scipy/sparse/_sparsetools.cpython-313t-darwin.so +0 -0
  386. scipy/sparse/_sputils.py +37 -22
  387. scipy/sparse/base.py +0 -9
  388. scipy/sparse/bsr.py +0 -14
  389. scipy/sparse/compressed.py +0 -23
  390. scipy/sparse/construct.py +0 -6
  391. scipy/sparse/coo.py +0 -14
  392. scipy/sparse/csc.py +0 -3
  393. scipy/sparse/csgraph/_flow.cpython-313t-darwin.so +0 -0
  394. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  395. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  396. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  397. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  398. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  399. scipy/sparse/csgraph/_traversal.cpython-313t-darwin.so +0 -0
  400. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  401. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  402. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  403. scipy/sparse/csr.py +0 -5
  404. scipy/sparse/data.py +1 -6
  405. scipy/sparse/dia.py +0 -7
  406. scipy/sparse/dok.py +0 -10
  407. scipy/sparse/linalg/_dsolve/_superlu.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  409. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  410. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313t-darwin.so +0 -0
  411. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  412. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  413. scipy/sparse/linalg/_interface.py +17 -18
  414. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  415. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  416. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  417. scipy/sparse/linalg/_isolve/minres.py +5 -5
  418. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  419. scipy/sparse/linalg/_isolve/utils.py +2 -8
  420. scipy/sparse/linalg/_matfuncs.py +1 -1
  421. scipy/sparse/linalg/_norm.py +1 -1
  422. scipy/sparse/linalg/_propack/_cpropack.cpython-313t-darwin.so +0 -0
  423. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  424. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-darwin.so +0 -0
  426. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  427. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  428. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  429. scipy/sparse/tests/test_base.py +214 -42
  430. scipy/sparse/tests/test_common1d.py +7 -7
  431. scipy/sparse/tests/test_construct.py +1 -1
  432. scipy/sparse/tests/test_coo.py +272 -4
  433. scipy/sparse/tests/test_sparsetools.py +5 -0
  434. scipy/sparse/tests/test_sputils.py +36 -7
  435. scipy/spatial/_ckdtree.cpython-313t-darwin.so +0 -0
  436. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  437. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  438. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  439. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  440. scipy/spatial/_voronoi.cpython-313t-darwin.so +0 -0
  441. scipy/spatial/distance.py +49 -42
  442. scipy/spatial/tests/test_distance.py +15 -1
  443. scipy/spatial/tests/test_kdtree.py +1 -0
  444. scipy/spatial/tests/test_qhull.py +7 -2
  445. scipy/spatial/transform/__init__.py +5 -3
  446. scipy/spatial/transform/_rigid_transform.cpython-313t-darwin.so +0 -0
  447. scipy/spatial/transform/_rotation.cpython-313t-darwin.so +0 -0
  448. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  449. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  450. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  451. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  452. scipy/special/__init__.py +1 -47
  453. scipy/special/_add_newdocs.py +34 -772
  454. scipy/special/_basic.py +22 -25
  455. scipy/special/_comb.cpython-313t-darwin.so +0 -0
  456. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  457. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  458. scipy/special/_logsumexp.py +67 -58
  459. scipy/special/_orthogonal.pyi +1 -1
  460. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  461. scipy/special/_special_ufuncs.cpython-313t-darwin.so +0 -0
  462. scipy/special/_spherical_bessel.py +4 -4
  463. scipy/special/_support_alternative_backends.py +212 -119
  464. scipy/special/_test_internal.cpython-313t-darwin.so +0 -0
  465. scipy/special/_testutils.py +4 -4
  466. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  467. scipy/special/_ufuncs.pyi +1 -0
  468. scipy/special/_ufuncs.pyx +215 -1400
  469. scipy/special/_ufuncs_cxx.cpython-313t-darwin.so +0 -0
  470. scipy/special/_ufuncs_cxx.pxd +2 -15
  471. scipy/special/_ufuncs_cxx.pyx +5 -44
  472. scipy/special/_ufuncs_cxx_defs.h +2 -16
  473. scipy/special/_ufuncs_defs.h +0 -8
  474. scipy/special/cython_special.cpython-313t-darwin.so +0 -0
  475. scipy/special/cython_special.pxd +1 -1
  476. scipy/special/tests/_cython_examples/meson.build +10 -1
  477. scipy/special/tests/test_basic.py +153 -20
  478. scipy/special/tests/test_boost_ufuncs.py +3 -0
  479. scipy/special/tests/test_cdflib.py +35 -11
  480. scipy/special/tests/test_gammainc.py +16 -0
  481. scipy/special/tests/test_hyp2f1.py +2 -2
  482. scipy/special/tests/test_log1mexp.py +85 -0
  483. scipy/special/tests/test_logsumexp.py +206 -64
  484. scipy/special/tests/test_mpmath.py +1 -0
  485. scipy/special/tests/test_nan_inputs.py +1 -1
  486. scipy/special/tests/test_orthogonal.py +17 -18
  487. scipy/special/tests/test_sf_error.py +3 -2
  488. scipy/special/tests/test_sph_harm.py +6 -7
  489. scipy/special/tests/test_support_alternative_backends.py +211 -76
  490. scipy/stats/__init__.py +4 -1
  491. scipy/stats/_ansari_swilk_statistics.cpython-313t-darwin.so +0 -0
  492. scipy/stats/_axis_nan_policy.py +5 -12
  493. scipy/stats/_biasedurn.cpython-313t-darwin.so +0 -0
  494. scipy/stats/_continued_fraction.py +387 -0
  495. scipy/stats/_continuous_distns.py +277 -310
  496. scipy/stats/_correlation.py +1 -1
  497. scipy/stats/_covariance.py +6 -3
  498. scipy/stats/_discrete_distns.py +39 -32
  499. scipy/stats/_distn_infrastructure.py +39 -12
  500. scipy/stats/_distribution_infrastructure.py +900 -238
  501. scipy/stats/_entropy.py +9 -10
  502. scipy/{_lib → stats}/_finite_differences.py +1 -1
  503. scipy/stats/_hypotests.py +83 -50
  504. scipy/stats/_kde.py +53 -49
  505. scipy/stats/_ksstats.py +1 -1
  506. scipy/stats/_levy_stable/__init__.py +7 -15
  507. scipy/stats/_levy_stable/levyst.cpython-313t-darwin.so +0 -0
  508. scipy/stats/_morestats.py +118 -73
  509. scipy/stats/_mstats_basic.py +13 -17
  510. scipy/stats/_mstats_extras.py +8 -8
  511. scipy/stats/_multivariate.py +89 -113
  512. scipy/stats/_new_distributions.py +97 -20
  513. scipy/stats/_page_trend_test.py +12 -5
  514. scipy/stats/_probability_distribution.py +265 -43
  515. scipy/stats/_qmc.py +14 -9
  516. scipy/stats/_qmc_cy.cpython-313t-darwin.so +0 -0
  517. scipy/stats/_qmvnt.py +16 -95
  518. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  519. scipy/stats/_quantile.py +335 -0
  520. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  521. scipy/stats/_resampling.py +4 -29
  522. scipy/stats/_sampling.py +1 -1
  523. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  524. scipy/stats/_stats.cpython-313t-darwin.so +0 -0
  525. scipy/stats/_stats_mstats_common.py +21 -2
  526. scipy/stats/_stats_py.py +550 -476
  527. scipy/stats/_stats_pythran.cpython-313t-darwin.so +0 -0
  528. scipy/stats/_unuran/unuran_wrapper.cpython-313t-darwin.so +0 -0
  529. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  530. scipy/stats/_variation.py +6 -8
  531. scipy/stats/_wilcoxon.py +13 -7
  532. scipy/stats/tests/common_tests.py +6 -4
  533. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  534. scipy/stats/tests/test_continued_fraction.py +173 -0
  535. scipy/stats/tests/test_continuous.py +379 -60
  536. scipy/stats/tests/test_continuous_basic.py +18 -12
  537. scipy/stats/tests/test_discrete_basic.py +14 -8
  538. scipy/stats/tests/test_discrete_distns.py +16 -16
  539. scipy/stats/tests/test_distributions.py +95 -75
  540. scipy/stats/tests/test_entropy.py +40 -48
  541. scipy/stats/tests/test_fit.py +4 -3
  542. scipy/stats/tests/test_hypotests.py +153 -24
  543. scipy/stats/tests/test_kdeoth.py +109 -41
  544. scipy/stats/tests/test_marray.py +289 -0
  545. scipy/stats/tests/test_morestats.py +79 -47
  546. scipy/stats/tests/test_mstats_basic.py +3 -3
  547. scipy/stats/tests/test_multivariate.py +434 -83
  548. scipy/stats/tests/test_qmc.py +13 -10
  549. scipy/stats/tests/test_quantile.py +199 -0
  550. scipy/stats/tests/test_rank.py +119 -112
  551. scipy/stats/tests/test_resampling.py +47 -56
  552. scipy/stats/tests/test_sampling.py +9 -4
  553. scipy/stats/tests/test_stats.py +799 -939
  554. scipy/stats/tests/test_variation.py +8 -6
  555. scipy/version.py +2 -2
  556. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  557. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +559 -566
  559. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  560. scipy/_lib/array_api_extra/_funcs.py +0 -484
  561. scipy/_lib/array_api_extra/_typing.py +0 -8
  562. scipy/interpolate/_bspl.cpython-313t-darwin.so +0 -0
  563. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  564. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  565. scipy/optimize/_slsqp.cpython-313t-darwin.so +0 -0
  566. scipy/spatial/qhull_src/COPYING.txt +0 -38
  567. scipy/special/libsf_error_state.dylib +0 -0
  568. scipy/special/tests/test_log_softmax.py +0 -109
  569. scipy/special/tests/test_xsf_cuda.py +0 -114
  570. scipy/special/xsf/binom.h +0 -89
  571. scipy/special/xsf/cdflib.h +0 -100
  572. scipy/special/xsf/cephes/airy.h +0 -307
  573. scipy/special/xsf/cephes/besselpoly.h +0 -51
  574. scipy/special/xsf/cephes/beta.h +0 -257
  575. scipy/special/xsf/cephes/cbrt.h +0 -131
  576. scipy/special/xsf/cephes/chbevl.h +0 -85
  577. scipy/special/xsf/cephes/chdtr.h +0 -193
  578. scipy/special/xsf/cephes/const.h +0 -87
  579. scipy/special/xsf/cephes/ellie.h +0 -293
  580. scipy/special/xsf/cephes/ellik.h +0 -251
  581. scipy/special/xsf/cephes/ellpe.h +0 -107
  582. scipy/special/xsf/cephes/ellpk.h +0 -117
  583. scipy/special/xsf/cephes/expn.h +0 -260
  584. scipy/special/xsf/cephes/gamma.h +0 -398
  585. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  586. scipy/special/xsf/cephes/hyperg.h +0 -361
  587. scipy/special/xsf/cephes/i0.h +0 -149
  588. scipy/special/xsf/cephes/i1.h +0 -158
  589. scipy/special/xsf/cephes/igam.h +0 -421
  590. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  591. scipy/special/xsf/cephes/igami.h +0 -313
  592. scipy/special/xsf/cephes/j0.h +0 -225
  593. scipy/special/xsf/cephes/j1.h +0 -198
  594. scipy/special/xsf/cephes/jv.h +0 -715
  595. scipy/special/xsf/cephes/k0.h +0 -164
  596. scipy/special/xsf/cephes/k1.h +0 -163
  597. scipy/special/xsf/cephes/kn.h +0 -243
  598. scipy/special/xsf/cephes/lanczos.h +0 -112
  599. scipy/special/xsf/cephes/ndtr.h +0 -275
  600. scipy/special/xsf/cephes/poch.h +0 -85
  601. scipy/special/xsf/cephes/polevl.h +0 -167
  602. scipy/special/xsf/cephes/psi.h +0 -194
  603. scipy/special/xsf/cephes/rgamma.h +0 -111
  604. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  605. scipy/special/xsf/cephes/shichi.h +0 -248
  606. scipy/special/xsf/cephes/sici.h +0 -224
  607. scipy/special/xsf/cephes/sindg.h +0 -221
  608. scipy/special/xsf/cephes/tandg.h +0 -139
  609. scipy/special/xsf/cephes/trig.h +0 -58
  610. scipy/special/xsf/cephes/unity.h +0 -186
  611. scipy/special/xsf/cephes/zeta.h +0 -172
  612. scipy/special/xsf/config.h +0 -304
  613. scipy/special/xsf/digamma.h +0 -205
  614. scipy/special/xsf/error.h +0 -57
  615. scipy/special/xsf/evalpoly.h +0 -47
  616. scipy/special/xsf/expint.h +0 -266
  617. scipy/special/xsf/hyp2f1.h +0 -694
  618. scipy/special/xsf/iv_ratio.h +0 -173
  619. scipy/special/xsf/lambertw.h +0 -150
  620. scipy/special/xsf/loggamma.h +0 -163
  621. scipy/special/xsf/sici.h +0 -200
  622. scipy/special/xsf/tools.h +0 -427
  623. scipy/special/xsf/trig.h +0 -164
  624. scipy/special/xsf/wright_bessel.h +0 -843
  625. scipy/special/xsf/zlog1.h +0 -35
  626. scipy/stats/_mvn.cpython-313t-darwin.so +0 -0
  627. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -0,0 +1,357 @@
1
+ """Public API Functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from collections.abc import Callable, Sequence
7
+ from functools import partial, wraps
8
+ from types import ModuleType
9
+ from typing import TYPE_CHECKING, Any, ParamSpec, TypeAlias, cast, overload
10
+
11
+ from ._funcs import broadcast_shapes
12
+ from ._utils import _compat
13
+ from ._utils._compat import (
14
+ array_namespace,
15
+ is_dask_namespace,
16
+ is_jax_namespace,
17
+ )
18
+ from ._utils._helpers import is_python_scalar
19
+ from ._utils._typing import Array, DType
20
+
21
+ if TYPE_CHECKING: # pragma: no cover
22
+ import numpy as np
23
+ from numpy.typing import ArrayLike
24
+
25
+ NumPyObject: TypeAlias = np.ndarray[Any, Any] | np.generic # type: ignore[explicit-any]
26
+ else:
27
+ # Sphinx hack
28
+ NumPyObject = Any
29
+
30
+ P = ParamSpec("P")
31
+
32
+
33
+ @overload
34
+ def lazy_apply( # type: ignore[decorated-any, valid-type]
35
+ func: Callable[P, Array | ArrayLike],
36
+ *args: Array | complex | None,
37
+ shape: tuple[int | None, ...] | None = None,
38
+ dtype: DType | None = None,
39
+ as_numpy: bool = False,
40
+ xp: ModuleType | None = None,
41
+ **kwargs: P.kwargs, # pyright: ignore[reportGeneralTypeIssues]
42
+ ) -> Array: ... # numpydoc ignore=GL08
43
+
44
+
45
+ @overload
46
+ def lazy_apply( # type: ignore[decorated-any, valid-type]
47
+ func: Callable[P, Sequence[Array | ArrayLike]],
48
+ *args: Array | complex | None,
49
+ shape: Sequence[tuple[int | None, ...]],
50
+ dtype: Sequence[DType] | None = None,
51
+ as_numpy: bool = False,
52
+ xp: ModuleType | None = None,
53
+ **kwargs: P.kwargs, # pyright: ignore[reportGeneralTypeIssues]
54
+ ) -> tuple[Array, ...]: ... # numpydoc ignore=GL08
55
+
56
+
57
+ def lazy_apply( # type: ignore[valid-type] # numpydoc ignore=GL07,SA04
58
+ func: Callable[P, Array | ArrayLike | Sequence[Array | ArrayLike]],
59
+ *args: Array | complex | None,
60
+ shape: tuple[int | None, ...] | Sequence[tuple[int | None, ...]] | None = None,
61
+ dtype: DType | Sequence[DType] | None = None,
62
+ as_numpy: bool = False,
63
+ xp: ModuleType | None = None,
64
+ **kwargs: P.kwargs, # pyright: ignore[reportGeneralTypeIssues]
65
+ ) -> Array | tuple[Array, ...]:
66
+ """
67
+ Lazily apply an eager function.
68
+
69
+ If the backend of the input arrays is lazy, e.g. Dask or jitted JAX, the execution
70
+ of the function is delayed until the graph is materialized; if it's eager, the
71
+ function is executed immediately.
72
+
73
+ Parameters
74
+ ----------
75
+ func : callable
76
+ The function to apply.
77
+
78
+ It must accept one or more array API compliant arrays as positional arguments.
79
+ If `as_numpy=True`, inputs are converted to NumPy before they are passed to
80
+ `func`.
81
+ It must return either a single array-like or a sequence of array-likes.
82
+
83
+ `func` must be a pure function, i.e. without side effects, as depending on the
84
+ backend it may be executed more than once or never.
85
+ *args : Array | int | float | complex | bool | None
86
+ One or more Array API compliant arrays, Python scalars, or None's.
87
+
88
+ If `as_numpy=True`, you need to be able to apply :func:`numpy.asarray` to
89
+ non-None args to convert them to NumPy; read notes below about specific
90
+ backends.
91
+ shape : tuple[int | None, ...] | Sequence[tuple[int | None, ...]], optional
92
+ Output shape or sequence of output shapes, one for each output of `func`.
93
+ Default: assume single output and broadcast shapes of the input arrays.
94
+ dtype : DType | Sequence[DType], optional
95
+ Output dtype or sequence of output dtypes, one for each output of `func`.
96
+ dtype(s) must belong to the same array namespace as the input arrays.
97
+ Default: infer the result type(s) from the input arrays.
98
+ as_numpy : bool, optional
99
+ If True, convert the input arrays to NumPy before passing them to `func`.
100
+ This is particularly useful to make NumPy-only functions, e.g. written in Cython
101
+ or Numba, work transparently with array API-compliant arrays.
102
+ Default: False.
103
+ xp : array_namespace, optional
104
+ The standard-compatible namespace for `args`. Default: infer.
105
+ **kwargs : Any, optional
106
+ Additional keyword arguments to pass verbatim to `func`.
107
+ They cannot contain Array objects.
108
+
109
+ Returns
110
+ -------
111
+ Array | tuple[Array, ...]
112
+ The result(s) of `func` applied to the input arrays, wrapped in the same
113
+ array namespace as the inputs.
114
+ If shape is omitted or a single `tuple[int | None, ...]`, return a single array.
115
+ Otherwise, return a tuple of arrays.
116
+
117
+ Notes
118
+ -----
119
+ JAX
120
+ This allows applying eager functions to jitted JAX arrays, which are lazy.
121
+ The function won't be applied until the JAX array is materialized.
122
+ When running inside ``jax.jit``, `shape` must be fully known, i.e. it cannot
123
+ contain any `None` elements.
124
+
125
+ .. warning::
126
+
127
+ `func` must never raise inside ``jax.jit``, as the resulting behavior is
128
+ undefined.
129
+
130
+ Using this with `as_numpy=False` is particularly useful to apply non-jittable
131
+ JAX functions to arrays on GPU devices.
132
+ If ``as_numpy=True``, the :doc:`jax:transfer_guard` may prevent arrays on a GPU
133
+ device from being transferred back to CPU. This is treated as an implicit
134
+ transfer.
135
+
136
+ PyTorch, CuPy
137
+ If ``as_numpy=True``, these backends raise by default if you attempt to convert
138
+ arrays on a GPU device to NumPy.
139
+
140
+ Sparse
141
+ If ``as_numpy=True``, by default sparse prevents implicit densification through
142
+ :func:`numpy.asarray`. `This safety mechanism can be disabled
143
+ <https://sparse.pydata.org/en/stable/operations.html#package-configuration>`_.
144
+
145
+ Dask
146
+ This allows applying eager functions to Dask arrays.
147
+ The Dask graph won't be computed until the user calls ``compute()`` or
148
+ ``persist()`` down the line.
149
+
150
+ The function name will be prominently visible on the user-facing Dask
151
+ dashboard and on Prometheus metrics, so it is recommended for it to be
152
+ meaningful.
153
+
154
+ `lazy_apply` doesn't know if `func` reduces along any axes; also, shape
155
+ changes are non-trivial in chunked Dask arrays. For these reasons, all inputs
156
+ will be rechunked into a single chunk.
157
+
158
+ .. warning::
159
+
160
+ The whole operation needs to fit in memory all at once on a single worker.
161
+
162
+ The outputs will also be returned as a single chunk and you should consider
163
+ rechunking them into smaller chunks afterwards.
164
+
165
+ If you want to distribute the calculation across multiple workers, you
166
+ should use :func:`dask.array.map_blocks`, :func:`dask.array.map_overlap`,
167
+ :func:`dask.array.blockwise`, or a native Dask wrapper instead of
168
+ `lazy_apply`.
169
+
170
+ Dask wrapping around other backends
171
+ If ``as_numpy=False``, `func` will receive in input eager arrays of the meta
172
+ namespace, as defined by the ``._meta`` attribute of the input Dask arrays.
173
+ The outputs of `func` will be wrapped by the meta namespace, and then wrapped
174
+ again by Dask.
175
+
176
+ Raises
177
+ ------
178
+ ValueError
179
+ When ``xp=jax.numpy``, the output `shape` is unknown (it contains ``None`` on
180
+ one or more axes) and this function was called inside ``jax.jit``.
181
+ RuntimeError
182
+ When ``xp=sparse`` and auto-densification is disabled.
183
+ Exception (backend-specific)
184
+ When the backend disallows implicit device to host transfers and the input
185
+ arrays are on a non-CPU device, e.g. on GPU.
186
+
187
+ See Also
188
+ --------
189
+ jax.transfer_guard
190
+ jax.pure_callback
191
+ dask.array.map_blocks
192
+ dask.array.map_overlap
193
+ dask.array.blockwise
194
+ """
195
+ args_not_none = [arg for arg in args if arg is not None]
196
+ array_args = [arg for arg in args_not_none if not is_python_scalar(arg)]
197
+ if not array_args:
198
+ msg = "Must have at least one argument array"
199
+ raise ValueError(msg)
200
+ if xp is None:
201
+ xp = array_namespace(*args)
202
+
203
+ # Normalize and validate shape and dtype
204
+ shapes: list[tuple[int | None, ...]]
205
+ dtypes: list[DType]
206
+ multi_output = False
207
+
208
+ if shape is None:
209
+ shapes = [broadcast_shapes(*(arg.shape for arg in array_args))]
210
+ elif all(isinstance(s, int | None) for s in shape):
211
+ # Do not test for shape to be a tuple
212
+ # https://github.com/data-apis/array-api/issues/891#issuecomment-2637430522
213
+ shapes = [cast(tuple[int | None, ...], shape)]
214
+ else:
215
+ shapes = list(shape) # type: ignore[arg-type] # pyright: ignore[reportAssignmentType]
216
+ multi_output = True
217
+
218
+ if dtype is None:
219
+ dtypes = [xp.result_type(*args_not_none)] * len(shapes)
220
+ elif multi_output:
221
+ if not isinstance(dtype, Sequence):
222
+ msg = "Got multiple shapes but only one dtype"
223
+ raise ValueError(msg)
224
+ dtypes = list(dtype) # pyright: ignore[reportUnknownArgumentType]
225
+ else:
226
+ if isinstance(dtype, Sequence):
227
+ msg = "Got single shape but multiple dtypes"
228
+ raise ValueError(msg)
229
+
230
+ dtypes = [dtype]
231
+
232
+ if len(shapes) != len(dtypes):
233
+ msg = f"Got {len(shapes)} shapes and {len(dtypes)} dtypes"
234
+ raise ValueError(msg)
235
+ del shape
236
+ del dtype
237
+ # End of shape and dtype parsing
238
+
239
+ # Backend-specific branches
240
+ if is_dask_namespace(xp):
241
+ import dask
242
+
243
+ metas: list[Array] = [arg._meta for arg in array_args] # pylint: disable=protected-access # pyright: ignore[reportAttributeAccessIssue]
244
+ meta_xp = array_namespace(*metas)
245
+
246
+ wrapped = dask.delayed( # type: ignore[attr-defined] # pyright: ignore[reportPrivateImportUsage]
247
+ _lazy_apply_wrapper(func, as_numpy, multi_output, meta_xp),
248
+ pure=True,
249
+ )
250
+ # This finalizes each arg, which is the same as arg.rechunk(-1).
251
+ # Please read docstring above for why we're not using
252
+ # dask.array.map_blocks or dask.array.blockwise!
253
+ delayed_out = wrapped(*args, **kwargs)
254
+
255
+ out = tuple(
256
+ xp.from_delayed(
257
+ delayed_out[i], # pyright: ignore[reportIndexIssue]
258
+ # Dask's unknown shapes diverge from the Array API specification
259
+ shape=tuple(math.nan if s is None else s for s in shape),
260
+ dtype=dtype,
261
+ meta=metas[0],
262
+ )
263
+ for i, (shape, dtype) in enumerate(zip(shapes, dtypes, strict=True))
264
+ )
265
+
266
+ elif is_jax_namespace(xp) and _is_jax_jit_enabled(xp):
267
+ # Delay calling func with jax.pure_callback, which will forward to func eager
268
+ # JAX arrays. Do not use jax.pure_callback when running outside of the JIT,
269
+ # as it does not support raising exceptions:
270
+ # https://github.com/jax-ml/jax/issues/26102
271
+ import jax
272
+
273
+ if any(None in shape for shape in shapes):
274
+ msg = "Output shape must be fully known when running inside jax.jit"
275
+ raise ValueError(msg)
276
+
277
+ # Shield kwargs from being coerced into JAX arrays.
278
+ # jax.pure_callback calls jax.jit under the hood, but without the chance of
279
+ # passing static_argnames / static_argnums.
280
+ wrapped = _lazy_apply_wrapper(
281
+ partial(func, **kwargs), as_numpy, multi_output, xp
282
+ )
283
+
284
+ # suppress unused-ignore to run mypy in -e lint as well as -e dev
285
+ out = cast( # type: ignore[bad-cast,unused-ignore]
286
+ tuple[Array, ...],
287
+ jax.pure_callback(
288
+ wrapped,
289
+ tuple(
290
+ jax.ShapeDtypeStruct(shape, dtype) # pyright: ignore[reportUnknownArgumentType]
291
+ for shape, dtype in zip(shapes, dtypes, strict=True)
292
+ ),
293
+ *args,
294
+ ),
295
+ )
296
+
297
+ else:
298
+ # Eager backends, including non-jitted JAX
299
+ wrapped = _lazy_apply_wrapper(func, as_numpy, multi_output, xp)
300
+ out = wrapped(*args, **kwargs)
301
+
302
+ return out if multi_output else out[0]
303
+
304
+
305
+ def _is_jax_jit_enabled(xp: ModuleType) -> bool: # numpydoc ignore=PR01,RT01
306
+ """Return True if this function is being called inside ``jax.jit``."""
307
+ import jax # pylint: disable=import-outside-toplevel
308
+
309
+ x = xp.asarray(False)
310
+ try:
311
+ return bool(x)
312
+ except jax.errors.TracerBoolConversionError:
313
+ return True
314
+
315
+
316
+ def _lazy_apply_wrapper( # type: ignore[explicit-any] # numpydoc ignore=PR01,RT01
317
+ func: Callable[..., Array | ArrayLike | Sequence[Array | ArrayLike]],
318
+ as_numpy: bool,
319
+ multi_output: bool,
320
+ xp: ModuleType,
321
+ ) -> Callable[..., tuple[Array, ...]]:
322
+ """
323
+ Helper of `lazy_apply`.
324
+
325
+ Given a function that accepts one or more arrays as positional arguments and returns
326
+ a single array-like or a sequence of array-likes, return a function that accepts the
327
+ same number of Array API arrays and always returns a tuple of Array API array.
328
+
329
+ Any keyword arguments are passed through verbatim to the wrapped function.
330
+ """
331
+
332
+ # On Dask, @wraps causes the graph key to contain the wrapped function's name
333
+ @wraps(func)
334
+ def wrapper( # type: ignore[decorated-any,explicit-any]
335
+ *args: Array | complex | None, **kwargs: Any
336
+ ) -> tuple[Array, ...]: # numpydoc ignore=GL08
337
+ args_list = []
338
+ device = None
339
+ for arg in args:
340
+ if arg is not None and not is_python_scalar(arg):
341
+ if device is None:
342
+ device = _compat.device(arg)
343
+ if as_numpy:
344
+ import numpy as np
345
+
346
+ arg = cast(Array, np.asarray(arg)) # type: ignore[bad-cast] # noqa: PLW2901
347
+ args_list.append(arg)
348
+ assert device is not None
349
+
350
+ out = func(*args_list, **kwargs)
351
+
352
+ if multi_output:
353
+ assert isinstance(out, Sequence)
354
+ return tuple(xp.asarray(o, device=device) for o in out)
355
+ return (xp.asarray(out, device=device),)
356
+
357
+ return wrapper
@@ -0,0 +1,278 @@
1
+ """
2
+ Testing utilities.
3
+
4
+ Note that this is private API; don't expect it to be stable.
5
+ See also ..testing for public testing utilities.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import math
11
+ from types import ModuleType
12
+ from typing import Any, cast
13
+
14
+ import numpy as np
15
+ import pytest
16
+
17
+ from ._utils._compat import (
18
+ array_namespace,
19
+ is_array_api_strict_namespace,
20
+ is_cupy_namespace,
21
+ is_dask_namespace,
22
+ is_jax_namespace,
23
+ is_numpy_namespace,
24
+ is_pydata_sparse_namespace,
25
+ is_torch_namespace,
26
+ to_device,
27
+ )
28
+ from ._utils._typing import Array, Device
29
+
30
+ __all__ = ["as_numpy_array", "xp_assert_close", "xp_assert_equal", "xp_assert_less"]
31
+
32
+
33
+ def _check_ns_shape_dtype(
34
+ actual: Array,
35
+ desired: Array,
36
+ check_dtype: bool,
37
+ check_shape: bool,
38
+ check_scalar: bool,
39
+ ) -> ModuleType: # numpydoc ignore=RT03
40
+ """
41
+ Assert that namespace, shape and dtype of the two arrays match.
42
+
43
+ Parameters
44
+ ----------
45
+ actual : Array
46
+ The array produced by the tested function.
47
+ desired : Array
48
+ The expected array (typically hardcoded).
49
+ check_dtype, check_shape : bool, default: True
50
+ Whether to check agreement between actual and desired dtypes and shapes
51
+ check_scalar : bool, default: False
52
+ NumPy only: whether to check agreement between actual and desired types -
53
+ 0d array vs scalar.
54
+
55
+ Returns
56
+ -------
57
+ Arrays namespace.
58
+ """
59
+ actual_xp = array_namespace(actual) # Raises on scalars and lists
60
+ desired_xp = array_namespace(desired)
61
+
62
+ msg = f"namespaces do not match: {actual_xp} != f{desired_xp}"
63
+ assert actual_xp == desired_xp, msg
64
+
65
+ if check_shape:
66
+ actual_shape = actual.shape
67
+ desired_shape = desired.shape
68
+ if is_dask_namespace(desired_xp):
69
+ # Dask uses nan instead of None for unknown shapes
70
+ if any(math.isnan(i) for i in cast(tuple[float, ...], actual_shape)):
71
+ actual_shape = actual.compute().shape # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue]
72
+ if any(math.isnan(i) for i in cast(tuple[float, ...], desired_shape)):
73
+ desired_shape = desired.compute().shape # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue]
74
+
75
+ msg = f"shapes do not match: {actual_shape} != f{desired_shape}"
76
+ assert actual_shape == desired_shape, msg
77
+
78
+ if check_dtype:
79
+ msg = f"dtypes do not match: {actual.dtype} != {desired.dtype}"
80
+ assert actual.dtype == desired.dtype, msg
81
+
82
+ if is_numpy_namespace(actual_xp) and check_scalar:
83
+ # only NumPy distinguishes between scalars and arrays; we do if check_scalar.
84
+ _msg = (
85
+ "array-ness does not match:\n Actual: "
86
+ f"{type(actual)}\n Desired: {type(desired)}"
87
+ )
88
+ assert np.isscalar(actual) == np.isscalar(desired), _msg
89
+
90
+ return desired_xp
91
+
92
+
93
+ def as_numpy_array(array: Array, *, xp: ModuleType) -> np.typing.NDArray[Any]: # type: ignore[explicit-any]
94
+ """
95
+ Convert array to NumPy, bypassing GPU-CPU transfer guards and densification guards.
96
+ """
97
+ if is_cupy_namespace(xp):
98
+ return xp.asnumpy(array)
99
+ if is_pydata_sparse_namespace(xp):
100
+ return array.todense() # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue]
101
+
102
+ if is_torch_namespace(xp):
103
+ array = to_device(array, "cpu")
104
+ if is_array_api_strict_namespace(xp):
105
+ cpu: Device = xp.Device("CPU_DEVICE")
106
+ array = to_device(array, cpu)
107
+ if is_jax_namespace(xp):
108
+ import jax
109
+
110
+ # Note: only needed if the transfer guard is enabled
111
+ cpu = cast(Device, jax.devices("cpu")[0])
112
+ array = to_device(array, cpu)
113
+
114
+ return np.asarray(array)
115
+
116
+
117
+ def xp_assert_equal(
118
+ actual: Array,
119
+ desired: Array,
120
+ *,
121
+ err_msg: str = "",
122
+ check_dtype: bool = True,
123
+ check_shape: bool = True,
124
+ check_scalar: bool = False,
125
+ ) -> None:
126
+ """
127
+ Array-API compatible version of `np.testing.assert_array_equal`.
128
+
129
+ Parameters
130
+ ----------
131
+ actual : Array
132
+ The array produced by the tested function.
133
+ desired : Array
134
+ The expected array (typically hardcoded).
135
+ err_msg : str, optional
136
+ Error message to display on failure.
137
+ check_dtype, check_shape : bool, default: True
138
+ Whether to check agreement between actual and desired dtypes and shapes
139
+ check_scalar : bool, default: False
140
+ NumPy only: whether to check agreement between actual and desired types -
141
+ 0d array vs scalar.
142
+
143
+ See Also
144
+ --------
145
+ xp_assert_close : Similar function for inexact equality checks.
146
+ numpy.testing.assert_array_equal : Similar function for NumPy arrays.
147
+ """
148
+ xp = _check_ns_shape_dtype(actual, desired, check_dtype, check_shape, check_scalar)
149
+ actual_np = as_numpy_array(actual, xp=xp)
150
+ desired_np = as_numpy_array(desired, xp=xp)
151
+ np.testing.assert_array_equal(actual_np, desired_np, err_msg=err_msg)
152
+
153
+
154
+ def xp_assert_less(
155
+ x: Array,
156
+ y: Array,
157
+ *,
158
+ err_msg: str = "",
159
+ check_dtype: bool = True,
160
+ check_shape: bool = True,
161
+ check_scalar: bool = False,
162
+ ) -> None:
163
+ """
164
+ Array-API compatible version of `np.testing.assert_array_less`.
165
+
166
+ Parameters
167
+ ----------
168
+ x, y : Array
169
+ The arrays to compare according to ``x < y`` (elementwise).
170
+ err_msg : str, optional
171
+ Error message to display on failure.
172
+ check_dtype, check_shape : bool, default: True
173
+ Whether to check agreement between actual and desired dtypes and shapes
174
+ check_scalar : bool, default: False
175
+ NumPy only: whether to check agreement between actual and desired types -
176
+ 0d array vs scalar.
177
+
178
+ See Also
179
+ --------
180
+ xp_assert_close : Similar function for inexact equality checks.
181
+ numpy.testing.assert_array_equal : Similar function for NumPy arrays.
182
+ """
183
+ xp = _check_ns_shape_dtype(x, y, check_dtype, check_shape, check_scalar)
184
+ x_np = as_numpy_array(x, xp=xp)
185
+ y_np = as_numpy_array(y, xp=xp)
186
+ np.testing.assert_array_less(x_np, y_np, err_msg=err_msg)
187
+
188
+
189
+ def xp_assert_close(
190
+ actual: Array,
191
+ desired: Array,
192
+ *,
193
+ rtol: float | None = None,
194
+ atol: float = 0,
195
+ err_msg: str = "",
196
+ check_dtype: bool = True,
197
+ check_shape: bool = True,
198
+ check_scalar: bool = False,
199
+ ) -> None:
200
+ """
201
+ Array-API compatible version of `np.testing.assert_allclose`.
202
+
203
+ Parameters
204
+ ----------
205
+ actual : Array
206
+ The array produced by the tested function.
207
+ desired : Array
208
+ The expected array (typically hardcoded).
209
+ rtol : float, optional
210
+ Relative tolerance. Default: dtype-dependent.
211
+ atol : float, optional
212
+ Absolute tolerance. Default: 0.
213
+ err_msg : str, optional
214
+ Error message to display on failure.
215
+ check_dtype, check_shape : bool, default: True
216
+ Whether to check agreement between actual and desired dtypes and shapes
217
+ check_scalar : bool, default: False
218
+ NumPy only: whether to check agreement between actual and desired types -
219
+ 0d array vs scalar.
220
+
221
+ See Also
222
+ --------
223
+ xp_assert_equal : Similar function for exact equality checks.
224
+ isclose : Public function for checking closeness.
225
+ numpy.testing.assert_allclose : Similar function for NumPy arrays.
226
+
227
+ Notes
228
+ -----
229
+ The default `atol` and `rtol` differ from `xp.all(xpx.isclose(a, b))`.
230
+ """
231
+ xp = _check_ns_shape_dtype(actual, desired, check_dtype, check_shape, check_scalar)
232
+
233
+ if rtol is None:
234
+ if xp.isdtype(actual.dtype, ("real floating", "complex floating")):
235
+ # multiplier of 4 is used as for `np.float64` this puts the default `rtol`
236
+ # roughly half way between sqrt(eps) and the default for
237
+ # `numpy.testing.assert_allclose`, 1e-7
238
+ rtol = xp.finfo(actual.dtype).eps ** 0.5 * 4
239
+ else:
240
+ rtol = 1e-7
241
+
242
+ actual_np = as_numpy_array(actual, xp=xp)
243
+ desired_np = as_numpy_array(desired, xp=xp)
244
+ np.testing.assert_allclose( # pyright: ignore[reportCallIssue]
245
+ actual_np,
246
+ desired_np,
247
+ rtol=rtol, # pyright: ignore[reportArgumentType]
248
+ atol=atol,
249
+ err_msg=err_msg,
250
+ )
251
+
252
+
253
+ def xfail(
254
+ request: pytest.FixtureRequest, *, reason: str, strict: bool | None = None
255
+ ) -> None:
256
+ """
257
+ XFAIL the currently running test.
258
+
259
+ Unlike ``pytest.xfail``, allow rest of test to execute instead of immediately
260
+ halting it, so that it may result in a XPASS.
261
+ xref https://github.com/pandas-dev/pandas/issues/38902
262
+
263
+ Parameters
264
+ ----------
265
+ request : pytest.FixtureRequest
266
+ ``request`` argument of the test function.
267
+ reason : str
268
+ Reason for the expected failure.
269
+ strict: bool, optional
270
+ If True, the test will be marked as failed if it passes.
271
+ If False, the test will be marked as passed if it fails.
272
+ Default: ``xfail_strict`` value in ``pyproject.toml``, or False if absent.
273
+ """
274
+ if strict is not None:
275
+ marker = pytest.mark.xfail(reason=reason, strict=strict)
276
+ else:
277
+ marker = pytest.mark.xfail(reason=reason)
278
+ request.node.add_marker(marker)
@@ -0,0 +1 @@
1
+ """Modules housing private utility functions."""