scipy 1.15.2__cp313-cp313t-macosx_14_0_arm64.whl → 1.16.0rc1__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 (637) 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 +497 -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_ccallback.cpython-313t-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_call.cpython-313t-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-313t-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-313t-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +169 -34
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-313t-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-313t-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +263 -157
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-313t-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-313t-darwin.so +0 -0
  126. scipy/integrate/_ivp/common.py +3 -3
  127. scipy/integrate/_ivp/ivp.py +9 -2
  128. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  129. scipy/integrate/_lsoda.cpython-313t-darwin.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-313t-darwin.so +0 -0
  134. scipy/integrate/_quadpack_py.py +11 -7
  135. scipy/integrate/_quadrature.py +3 -3
  136. scipy/integrate/_rules/_base.py +2 -2
  137. scipy/integrate/_tanhsinh.py +57 -54
  138. scipy/integrate/_test_odeint_banded.cpython-313t-darwin.so +0 -0
  139. scipy/integrate/_vode.cpython-313t-darwin.so +0 -0
  140. scipy/integrate/tests/test__quad_vec.py +0 -6
  141. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  142. scipy/integrate/tests/test_cubature.py +21 -35
  143. scipy/integrate/tests/test_quadrature.py +6 -8
  144. scipy/integrate/tests/test_tanhsinh.py +61 -43
  145. scipy/interpolate/__init__.py +70 -58
  146. scipy/interpolate/_bary_rational.py +22 -22
  147. scipy/interpolate/_bsplines.py +119 -66
  148. scipy/interpolate/_cubic.py +65 -50
  149. scipy/interpolate/_dfitpack.cpython-313t-darwin.so +0 -0
  150. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  151. scipy/interpolate/_fitpack.cpython-313t-darwin.so +0 -0
  152. scipy/interpolate/_fitpack2.py +9 -6
  153. scipy/interpolate/_fitpack_impl.py +32 -26
  154. scipy/interpolate/_fitpack_repro.py +23 -19
  155. scipy/interpolate/_interpnd.cpython-313t-darwin.so +0 -0
  156. scipy/interpolate/_interpolate.py +30 -12
  157. scipy/interpolate/_ndbspline.py +13 -18
  158. scipy/interpolate/_ndgriddata.py +5 -8
  159. scipy/interpolate/_polyint.py +95 -31
  160. scipy/interpolate/_ppoly.cpython-313t-darwin.so +0 -0
  161. scipy/interpolate/_rbf.py +2 -2
  162. scipy/interpolate/_rbfinterp.py +1 -1
  163. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  164. scipy/interpolate/_rgi.py +31 -26
  165. scipy/interpolate/_rgi_cython.cpython-313t-darwin.so +0 -0
  166. scipy/interpolate/dfitpack.py +0 -20
  167. scipy/interpolate/interpnd.py +1 -2
  168. scipy/interpolate/tests/test_bary_rational.py +2 -2
  169. scipy/interpolate/tests/test_bsplines.py +97 -1
  170. scipy/interpolate/tests/test_fitpack2.py +39 -1
  171. scipy/interpolate/tests/test_interpnd.py +32 -20
  172. scipy/interpolate/tests/test_interpolate.py +48 -4
  173. scipy/interpolate/tests/test_rgi.py +2 -1
  174. scipy/io/_fast_matrix_market/__init__.py +2 -0
  175. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  176. scipy/io/_harwell_boeing/hb.py +7 -11
  177. scipy/io/_idl.py +5 -7
  178. scipy/io/_netcdf.py +15 -5
  179. scipy/io/_test_fortran.cpython-313t-darwin.so +0 -0
  180. scipy/io/arff/tests/test_arffread.py +3 -3
  181. scipy/io/matlab/__init__.py +5 -3
  182. scipy/io/matlab/_mio.py +4 -1
  183. scipy/io/matlab/_mio5.py +19 -13
  184. scipy/io/matlab/_mio5_utils.cpython-313t-darwin.so +0 -0
  185. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  186. scipy/io/matlab/_miobase.py +4 -1
  187. scipy/io/matlab/_streams.cpython-313t-darwin.so +0 -0
  188. scipy/io/matlab/tests/test_mio.py +46 -18
  189. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  190. scipy/io/tests/test_mmio.py +7 -1
  191. scipy/io/tests/test_wavfile.py +41 -0
  192. scipy/io/wavfile.py +57 -10
  193. scipy/linalg/_basic.py +113 -86
  194. scipy/linalg/_cythonized_array_utils.cpython-313t-darwin.so +0 -0
  195. scipy/linalg/_decomp.py +22 -9
  196. scipy/linalg/_decomp_cholesky.py +28 -13
  197. scipy/linalg/_decomp_cossin.py +45 -30
  198. scipy/linalg/_decomp_interpolative.cpython-313t-darwin.so +0 -0
  199. scipy/linalg/_decomp_ldl.py +4 -1
  200. scipy/linalg/_decomp_lu.py +18 -6
  201. scipy/linalg/_decomp_lu_cython.cpython-313t-darwin.so +0 -0
  202. scipy/linalg/_decomp_polar.py +2 -0
  203. scipy/linalg/_decomp_qr.py +6 -2
  204. scipy/linalg/_decomp_qz.py +3 -0
  205. scipy/linalg/_decomp_schur.py +3 -1
  206. scipy/linalg/_decomp_svd.py +13 -2
  207. scipy/linalg/_decomp_update.cpython-313t-darwin.so +0 -0
  208. scipy/linalg/_expm_frechet.py +4 -0
  209. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  210. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  211. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  212. scipy/linalg/_matfuncs.py +187 -4
  213. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  214. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  216. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  217. scipy/linalg/_procrustes.py +2 -0
  218. scipy/linalg/_sketches.py +17 -6
  219. scipy/linalg/_solve_toeplitz.cpython-313t-darwin.so +0 -0
  220. scipy/linalg/_solvers.py +7 -2
  221. scipy/linalg/_special_matrices.py +26 -36
  222. scipy/linalg/cython_blas.cpython-313t-darwin.so +0 -0
  223. scipy/linalg/cython_lapack.cpython-313t-darwin.so +0 -0
  224. scipy/linalg/lapack.py +22 -2
  225. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  226. scipy/linalg/tests/test_basic.py +31 -16
  227. scipy/linalg/tests/test_batch.py +588 -0
  228. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  229. scipy/linalg/tests/test_decomp.py +40 -3
  230. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  231. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  232. scipy/linalg/tests/test_interpolative.py +17 -0
  233. scipy/linalg/tests/test_lapack.py +115 -7
  234. scipy/linalg/tests/test_matfuncs.py +157 -102
  235. scipy/linalg/tests/test_procrustes.py +0 -7
  236. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  237. scipy/linalg/tests/test_special_matrices.py +1 -5
  238. scipy/ndimage/__init__.py +1 -0
  239. scipy/ndimage/_cytest.cpython-313t-darwin.so +0 -0
  240. scipy/ndimage/_delegators.py +8 -2
  241. scipy/ndimage/_filters.py +433 -5
  242. scipy/ndimage/_interpolation.py +36 -6
  243. scipy/ndimage/_measurements.py +4 -2
  244. scipy/ndimage/_morphology.py +5 -0
  245. scipy/ndimage/_nd_image.cpython-313t-darwin.so +0 -0
  246. scipy/ndimage/_ndimage_api.py +2 -1
  247. scipy/ndimage/_ni_docstrings.py +5 -1
  248. scipy/ndimage/_ni_label.cpython-313t-darwin.so +0 -0
  249. scipy/ndimage/_ni_support.py +1 -5
  250. scipy/ndimage/_rank_filter_1d.cpython-313t-darwin.so +0 -0
  251. scipy/ndimage/_support_alternative_backends.py +18 -6
  252. scipy/ndimage/tests/test_filters.py +351 -259
  253. scipy/ndimage/tests/test_fourier.py +7 -9
  254. scipy/ndimage/tests/test_interpolation.py +68 -61
  255. scipy/ndimage/tests/test_measurements.py +18 -35
  256. scipy/ndimage/tests/test_morphology.py +143 -131
  257. scipy/ndimage/tests/test_splines.py +1 -3
  258. scipy/odr/__odrpack.cpython-313t-darwin.so +0 -0
  259. scipy/optimize/_basinhopping.py +13 -7
  260. scipy/optimize/_bglu_dense.cpython-313t-darwin.so +0 -0
  261. scipy/optimize/_bracket.py +46 -26
  262. scipy/optimize/_chandrupatla.py +9 -10
  263. scipy/optimize/_cobyla_py.py +104 -123
  264. scipy/optimize/_constraints.py +14 -10
  265. scipy/optimize/_differentiable_functions.py +371 -230
  266. scipy/optimize/_differentialevolution.py +4 -3
  267. scipy/optimize/_direct.cpython-313t-darwin.so +0 -0
  268. scipy/optimize/_dual_annealing.py +1 -1
  269. scipy/optimize/_elementwise.py +1 -4
  270. scipy/optimize/_group_columns.cpython-313t-darwin.so +0 -0
  271. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  272. scipy/optimize/_lbfgsb.cpython-313t-darwin.so +0 -0
  273. scipy/optimize/_lbfgsb_py.py +57 -16
  274. scipy/optimize/_linprog_doc.py +2 -2
  275. scipy/optimize/_linprog_highs.py +11 -11
  276. scipy/optimize/_linprog_ip.py +25 -10
  277. scipy/optimize/_linprog_util.py +18 -19
  278. scipy/optimize/_lsap.cpython-313t-darwin.so +0 -0
  279. scipy/optimize/_lsq/common.py +3 -3
  280. scipy/optimize/_lsq/dogbox.py +16 -2
  281. scipy/optimize/_lsq/givens_elimination.cpython-313t-darwin.so +0 -0
  282. scipy/optimize/_lsq/least_squares.py +198 -126
  283. scipy/optimize/_lsq/lsq_linear.py +6 -6
  284. scipy/optimize/_lsq/trf.py +35 -8
  285. scipy/optimize/_milp.py +3 -1
  286. scipy/optimize/_minimize.py +105 -36
  287. scipy/optimize/_minpack.cpython-313t-darwin.so +0 -0
  288. scipy/optimize/_minpack_py.py +21 -14
  289. scipy/optimize/_moduleTNC.cpython-313t-darwin.so +0 -0
  290. scipy/optimize/_nnls.py +20 -21
  291. scipy/optimize/_nonlin.py +34 -3
  292. scipy/optimize/_numdiff.py +288 -110
  293. scipy/optimize/_optimize.py +86 -48
  294. scipy/optimize/_pava_pybind.cpython-313t-darwin.so +0 -0
  295. scipy/optimize/_remove_redundancy.py +5 -5
  296. scipy/optimize/_root_scalar.py +1 -1
  297. scipy/optimize/_shgo.py +6 -0
  298. scipy/optimize/_shgo_lib/_complex.py +1 -1
  299. scipy/optimize/_slsqp_py.py +216 -124
  300. scipy/optimize/_slsqplib.cpython-313t-darwin.so +0 -0
  301. scipy/optimize/_spectral.py +1 -1
  302. scipy/optimize/_tnc.py +8 -1
  303. scipy/optimize/_trlib/_trlib.cpython-313t-darwin.so +0 -0
  304. scipy/optimize/_trustregion.py +20 -6
  305. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  306. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  307. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  308. scipy/optimize/_trustregion_constr/projections.py +12 -8
  309. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  310. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  311. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  312. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  313. scipy/optimize/_trustregion_exact.py +0 -1
  314. scipy/optimize/_zeros.cpython-313t-darwin.so +0 -0
  315. scipy/optimize/_zeros_py.py +97 -17
  316. scipy/optimize/cython_optimize/_zeros.cpython-313t-darwin.so +0 -0
  317. scipy/optimize/slsqp.py +0 -1
  318. scipy/optimize/tests/test__basinhopping.py +1 -1
  319. scipy/optimize/tests/test__differential_evolution.py +4 -4
  320. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  321. scipy/optimize/tests/test__numdiff.py +66 -22
  322. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  323. scipy/optimize/tests/test__shgo.py +9 -1
  324. scipy/optimize/tests/test_bracket.py +71 -46
  325. scipy/optimize/tests/test_chandrupatla.py +133 -135
  326. scipy/optimize/tests/test_cobyla.py +74 -45
  327. scipy/optimize/tests/test_constraints.py +1 -1
  328. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  329. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  330. scipy/optimize/tests/test_least_squares.py +125 -13
  331. scipy/optimize/tests/test_linear_assignment.py +3 -3
  332. scipy/optimize/tests/test_linprog.py +3 -3
  333. scipy/optimize/tests/test_lsq_linear.py +5 -5
  334. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  335. scipy/optimize/tests/test_minpack.py +4 -4
  336. scipy/optimize/tests/test_nnls.py +43 -3
  337. scipy/optimize/tests/test_nonlin.py +36 -0
  338. scipy/optimize/tests/test_optimize.py +95 -17
  339. scipy/optimize/tests/test_slsqp.py +36 -4
  340. scipy/optimize/tests/test_zeros.py +34 -1
  341. scipy/signal/__init__.py +12 -23
  342. scipy/signal/_delegators.py +568 -0
  343. scipy/signal/_filter_design.py +459 -241
  344. scipy/signal/_fir_filter_design.py +262 -90
  345. scipy/signal/_lti_conversion.py +3 -2
  346. scipy/signal/_ltisys.py +118 -91
  347. scipy/signal/_max_len_seq_inner.cpython-313t-darwin.so +0 -0
  348. scipy/signal/_peak_finding_utils.cpython-313t-darwin.so +0 -0
  349. scipy/signal/_polyutils.py +172 -0
  350. scipy/signal/_short_time_fft.py +553 -76
  351. scipy/signal/_signal_api.py +30 -0
  352. scipy/signal/_signaltools.py +719 -396
  353. scipy/signal/_sigtools.cpython-313t-darwin.so +0 -0
  354. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  355. scipy/signal/_spectral_py.py +221 -50
  356. scipy/signal/_spline.cpython-313t-darwin.so +0 -0
  357. scipy/signal/_spline_filters.py +108 -68
  358. scipy/signal/_support_alternative_backends.py +73 -0
  359. scipy/signal/_upfirdn.py +4 -1
  360. scipy/signal/_upfirdn_apply.cpython-313t-darwin.so +0 -0
  361. scipy/signal/_waveforms.py +2 -11
  362. scipy/signal/_wavelets.py +1 -1
  363. scipy/signal/fir_filter_design.py +1 -0
  364. scipy/signal/spline.py +4 -11
  365. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  366. scipy/signal/tests/test_bsplines.py +114 -79
  367. scipy/signal/tests/test_cont2discrete.py +9 -2
  368. scipy/signal/tests/test_filter_design.py +721 -481
  369. scipy/signal/tests/test_fir_filter_design.py +332 -140
  370. scipy/signal/tests/test_savitzky_golay.py +4 -3
  371. scipy/signal/tests/test_short_time_fft.py +231 -5
  372. scipy/signal/tests/test_signaltools.py +2149 -1348
  373. scipy/signal/tests/test_spectral.py +19 -6
  374. scipy/signal/tests/test_splines.py +161 -96
  375. scipy/signal/tests/test_upfirdn.py +84 -50
  376. scipy/signal/tests/test_waveforms.py +20 -0
  377. scipy/signal/tests/test_windows.py +607 -466
  378. scipy/signal/windows/_windows.py +287 -148
  379. scipy/sparse/__init__.py +23 -4
  380. scipy/sparse/_base.py +269 -120
  381. scipy/sparse/_bsr.py +7 -4
  382. scipy/sparse/_compressed.py +59 -234
  383. scipy/sparse/_construct.py +90 -38
  384. scipy/sparse/_coo.py +115 -181
  385. scipy/sparse/_csc.py +4 -4
  386. scipy/sparse/_csparsetools.cpython-313t-darwin.so +0 -0
  387. scipy/sparse/_csr.py +2 -2
  388. scipy/sparse/_data.py +48 -48
  389. scipy/sparse/_dia.py +105 -21
  390. scipy/sparse/_dok.py +0 -23
  391. scipy/sparse/_index.py +4 -4
  392. scipy/sparse/_matrix.py +23 -0
  393. scipy/sparse/_sparsetools.cpython-313t-darwin.so +0 -0
  394. scipy/sparse/_sputils.py +37 -22
  395. scipy/sparse/base.py +0 -9
  396. scipy/sparse/bsr.py +0 -14
  397. scipy/sparse/compressed.py +0 -23
  398. scipy/sparse/construct.py +0 -6
  399. scipy/sparse/coo.py +0 -14
  400. scipy/sparse/csc.py +0 -3
  401. scipy/sparse/csgraph/_flow.cpython-313t-darwin.so +0 -0
  402. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  403. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  404. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  405. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  406. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  407. scipy/sparse/csgraph/_traversal.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  409. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  410. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  411. scipy/sparse/csr.py +0 -5
  412. scipy/sparse/data.py +1 -6
  413. scipy/sparse/dia.py +0 -7
  414. scipy/sparse/dok.py +0 -10
  415. scipy/sparse/linalg/_dsolve/_superlu.cpython-313t-darwin.so +0 -0
  416. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  417. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  418. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313t-darwin.so +0 -0
  419. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  420. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  421. scipy/sparse/linalg/_expm_multiply.py +8 -3
  422. scipy/sparse/linalg/_interface.py +29 -26
  423. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  424. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  425. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  426. scipy/sparse/linalg/_isolve/minres.py +5 -5
  427. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  428. scipy/sparse/linalg/_isolve/utils.py +2 -8
  429. scipy/sparse/linalg/_matfuncs.py +1 -1
  430. scipy/sparse/linalg/_norm.py +1 -1
  431. scipy/sparse/linalg/_propack/_cpropack.cpython-313t-darwin.so +0 -0
  432. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  433. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  434. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-darwin.so +0 -0
  435. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  436. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  437. scipy/sparse/linalg/tests/test_interface.py +35 -0
  438. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  439. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  440. scipy/sparse/tests/test_base.py +217 -40
  441. scipy/sparse/tests/test_common1d.py +17 -12
  442. scipy/sparse/tests/test_construct.py +1 -1
  443. scipy/sparse/tests/test_coo.py +272 -4
  444. scipy/sparse/tests/test_sparsetools.py +5 -0
  445. scipy/sparse/tests/test_sputils.py +36 -7
  446. scipy/spatial/_ckdtree.cpython-313t-darwin.so +0 -0
  447. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  448. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  449. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  450. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  451. scipy/spatial/_voronoi.cpython-313t-darwin.so +0 -0
  452. scipy/spatial/distance.py +49 -42
  453. scipy/spatial/tests/test_distance.py +3 -1
  454. scipy/spatial/tests/test_kdtree.py +1 -0
  455. scipy/spatial/tests/test_qhull.py +106 -2
  456. scipy/spatial/transform/__init__.py +5 -3
  457. scipy/spatial/transform/_rigid_transform.cpython-313t-darwin.so +0 -0
  458. scipy/spatial/transform/_rotation.cpython-313t-darwin.so +0 -0
  459. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  460. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  461. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  462. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  463. scipy/special/__init__.py +1 -47
  464. scipy/special/_add_newdocs.py +34 -772
  465. scipy/special/_basic.py +22 -25
  466. scipy/special/_comb.cpython-313t-darwin.so +0 -0
  467. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  468. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  469. scipy/special/_logsumexp.py +83 -69
  470. scipy/special/_orthogonal.pyi +1 -1
  471. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  472. scipy/special/_special_ufuncs.cpython-313t-darwin.so +0 -0
  473. scipy/special/_spherical_bessel.py +4 -4
  474. scipy/special/_support_alternative_backends.py +212 -119
  475. scipy/special/_test_internal.cpython-313t-darwin.so +0 -0
  476. scipy/special/_testutils.py +4 -4
  477. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  478. scipy/special/_ufuncs.pyi +1 -0
  479. scipy/special/_ufuncs.pyx +215 -1400
  480. scipy/special/_ufuncs_cxx.cpython-313t-darwin.so +0 -0
  481. scipy/special/_ufuncs_cxx.pxd +2 -15
  482. scipy/special/_ufuncs_cxx.pyx +5 -44
  483. scipy/special/_ufuncs_cxx_defs.h +2 -16
  484. scipy/special/_ufuncs_defs.h +0 -8
  485. scipy/special/cython_special.cpython-313t-darwin.so +0 -0
  486. scipy/special/cython_special.pxd +1 -1
  487. scipy/special/tests/_cython_examples/meson.build +10 -1
  488. scipy/special/tests/test_basic.py +153 -20
  489. scipy/special/tests/test_boost_ufuncs.py +3 -0
  490. scipy/special/tests/test_cdflib.py +35 -11
  491. scipy/special/tests/test_gammainc.py +16 -0
  492. scipy/special/tests/test_hyp2f1.py +23 -2
  493. scipy/special/tests/test_log1mexp.py +85 -0
  494. scipy/special/tests/test_logsumexp.py +220 -64
  495. scipy/special/tests/test_mpmath.py +1 -0
  496. scipy/special/tests/test_nan_inputs.py +1 -1
  497. scipy/special/tests/test_orthogonal.py +17 -18
  498. scipy/special/tests/test_sf_error.py +3 -2
  499. scipy/special/tests/test_sph_harm.py +6 -7
  500. scipy/special/tests/test_support_alternative_backends.py +211 -76
  501. scipy/stats/__init__.py +4 -1
  502. scipy/stats/_ansari_swilk_statistics.cpython-313t-darwin.so +0 -0
  503. scipy/stats/_axis_nan_policy.py +4 -3
  504. scipy/stats/_biasedurn.cpython-313t-darwin.so +0 -0
  505. scipy/stats/_continued_fraction.py +387 -0
  506. scipy/stats/_continuous_distns.py +296 -319
  507. scipy/stats/_covariance.py +6 -3
  508. scipy/stats/_discrete_distns.py +39 -32
  509. scipy/stats/_distn_infrastructure.py +39 -12
  510. scipy/stats/_distribution_infrastructure.py +900 -238
  511. scipy/stats/_entropy.py +7 -8
  512. scipy/{_lib → stats}/_finite_differences.py +1 -1
  513. scipy/stats/_hypotests.py +82 -49
  514. scipy/stats/_kde.py +53 -49
  515. scipy/stats/_ksstats.py +1 -1
  516. scipy/stats/_levy_stable/__init__.py +7 -15
  517. scipy/stats/_levy_stable/levyst.cpython-313t-darwin.so +0 -0
  518. scipy/stats/_morestats.py +112 -67
  519. scipy/stats/_mstats_basic.py +13 -17
  520. scipy/stats/_mstats_extras.py +8 -8
  521. scipy/stats/_multivariate.py +89 -113
  522. scipy/stats/_new_distributions.py +97 -20
  523. scipy/stats/_page_trend_test.py +12 -5
  524. scipy/stats/_probability_distribution.py +265 -43
  525. scipy/stats/_qmc.py +14 -9
  526. scipy/stats/_qmc_cy.cpython-313t-darwin.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  531. scipy/stats/_resampling.py +4 -29
  532. scipy/stats/_sampling.py +1 -1
  533. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  534. scipy/stats/_stats.cpython-313t-darwin.so +0 -0
  535. scipy/stats/_stats_mstats_common.py +19 -2
  536. scipy/stats/_stats_py.py +534 -460
  537. scipy/stats/_stats_pythran.cpython-313t-darwin.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-313t-darwin.so +0 -0
  539. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  540. scipy/stats/_variation.py +5 -7
  541. scipy/stats/_wilcoxon.py +13 -7
  542. scipy/stats/tests/common_tests.py +6 -4
  543. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  544. scipy/stats/tests/test_continued_fraction.py +173 -0
  545. scipy/stats/tests/test_continuous.py +379 -60
  546. scipy/stats/tests/test_continuous_basic.py +18 -12
  547. scipy/stats/tests/test_discrete_basic.py +14 -8
  548. scipy/stats/tests/test_discrete_distns.py +16 -16
  549. scipy/stats/tests/test_distributions.py +117 -75
  550. scipy/stats/tests/test_entropy.py +40 -48
  551. scipy/stats/tests/test_fit.py +4 -3
  552. scipy/stats/tests/test_hypotests.py +153 -24
  553. scipy/stats/tests/test_kdeoth.py +109 -41
  554. scipy/stats/tests/test_marray.py +289 -0
  555. scipy/stats/tests/test_morestats.py +79 -47
  556. scipy/stats/tests/test_mstats_basic.py +3 -3
  557. scipy/stats/tests/test_multivariate.py +434 -83
  558. scipy/stats/tests/test_qmc.py +13 -10
  559. scipy/stats/tests/test_quantile.py +199 -0
  560. scipy/stats/tests/test_rank.py +119 -112
  561. scipy/stats/tests/test_resampling.py +47 -56
  562. scipy/stats/tests/test_sampling.py +9 -4
  563. scipy/stats/tests/test_stats.py +799 -939
  564. scipy/stats/tests/test_variation.py +8 -6
  565. scipy/version.py +2 -2
  566. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  567. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +9 -9
  568. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +569 -576
  569. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  570. scipy/_lib/array_api_extra/_funcs.py +0 -484
  571. scipy/_lib/array_api_extra/_typing.py +0 -8
  572. scipy/interpolate/_bspl.cpython-313t-darwin.so +0 -0
  573. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  574. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  575. scipy/optimize/_slsqp.cpython-313t-darwin.so +0 -0
  576. scipy/spatial/qhull_src/COPYING.txt +0 -38
  577. scipy/special/libsf_error_state.dylib +0 -0
  578. scipy/special/tests/test_log_softmax.py +0 -109
  579. scipy/special/tests/test_xsf_cuda.py +0 -114
  580. scipy/special/xsf/binom.h +0 -89
  581. scipy/special/xsf/cdflib.h +0 -100
  582. scipy/special/xsf/cephes/airy.h +0 -307
  583. scipy/special/xsf/cephes/besselpoly.h +0 -51
  584. scipy/special/xsf/cephes/beta.h +0 -257
  585. scipy/special/xsf/cephes/cbrt.h +0 -131
  586. scipy/special/xsf/cephes/chbevl.h +0 -85
  587. scipy/special/xsf/cephes/chdtr.h +0 -193
  588. scipy/special/xsf/cephes/const.h +0 -87
  589. scipy/special/xsf/cephes/ellie.h +0 -293
  590. scipy/special/xsf/cephes/ellik.h +0 -251
  591. scipy/special/xsf/cephes/ellpe.h +0 -107
  592. scipy/special/xsf/cephes/ellpk.h +0 -117
  593. scipy/special/xsf/cephes/expn.h +0 -260
  594. scipy/special/xsf/cephes/gamma.h +0 -398
  595. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  596. scipy/special/xsf/cephes/hyperg.h +0 -361
  597. scipy/special/xsf/cephes/i0.h +0 -149
  598. scipy/special/xsf/cephes/i1.h +0 -158
  599. scipy/special/xsf/cephes/igam.h +0 -421
  600. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  601. scipy/special/xsf/cephes/igami.h +0 -313
  602. scipy/special/xsf/cephes/j0.h +0 -225
  603. scipy/special/xsf/cephes/j1.h +0 -198
  604. scipy/special/xsf/cephes/jv.h +0 -715
  605. scipy/special/xsf/cephes/k0.h +0 -164
  606. scipy/special/xsf/cephes/k1.h +0 -163
  607. scipy/special/xsf/cephes/kn.h +0 -243
  608. scipy/special/xsf/cephes/lanczos.h +0 -112
  609. scipy/special/xsf/cephes/ndtr.h +0 -275
  610. scipy/special/xsf/cephes/poch.h +0 -85
  611. scipy/special/xsf/cephes/polevl.h +0 -167
  612. scipy/special/xsf/cephes/psi.h +0 -194
  613. scipy/special/xsf/cephes/rgamma.h +0 -111
  614. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  615. scipy/special/xsf/cephes/shichi.h +0 -248
  616. scipy/special/xsf/cephes/sici.h +0 -224
  617. scipy/special/xsf/cephes/sindg.h +0 -221
  618. scipy/special/xsf/cephes/tandg.h +0 -139
  619. scipy/special/xsf/cephes/trig.h +0 -58
  620. scipy/special/xsf/cephes/unity.h +0 -186
  621. scipy/special/xsf/cephes/zeta.h +0 -172
  622. scipy/special/xsf/config.h +0 -304
  623. scipy/special/xsf/digamma.h +0 -205
  624. scipy/special/xsf/error.h +0 -57
  625. scipy/special/xsf/evalpoly.h +0 -47
  626. scipy/special/xsf/expint.h +0 -266
  627. scipy/special/xsf/hyp2f1.h +0 -694
  628. scipy/special/xsf/iv_ratio.h +0 -173
  629. scipy/special/xsf/lambertw.h +0 -150
  630. scipy/special/xsf/loggamma.h +0 -163
  631. scipy/special/xsf/sici.h +0 -200
  632. scipy/special/xsf/tools.h +0 -427
  633. scipy/special/xsf/trig.h +0 -164
  634. scipy/special/xsf/wright_bessel.h +0 -843
  635. scipy/special/xsf/zlog1.h +0 -35
  636. scipy/stats/_mvn.cpython-313t-darwin.so +0 -0
  637. scipy-1.15.2.dist-info/WHEEL +0 -4
@@ -0,0 +1,463 @@
1
+ """Update operations for read-only arrays."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import operator
6
+ from collections.abc import Callable
7
+ from enum import Enum
8
+ from types import ModuleType
9
+ from typing import TYPE_CHECKING, ClassVar, cast
10
+
11
+ from ._utils import _compat
12
+ from ._utils._compat import (
13
+ array_namespace,
14
+ is_dask_array,
15
+ is_jax_array,
16
+ is_torch_array,
17
+ is_writeable_array,
18
+ )
19
+ from ._utils._helpers import meta_namespace
20
+ from ._utils._typing import Array, SetIndex
21
+
22
+ if TYPE_CHECKING: # pragma: no cover
23
+ # TODO import from typing (requires Python >=3.11)
24
+ from typing_extensions import Self
25
+
26
+
27
+ class _AtOp(Enum):
28
+ """Operations for use in `xpx.at`."""
29
+
30
+ SET = "set"
31
+ ADD = "add"
32
+ SUBTRACT = "subtract"
33
+ MULTIPLY = "multiply"
34
+ DIVIDE = "divide"
35
+ POWER = "power"
36
+ MIN = "min"
37
+ MAX = "max"
38
+
39
+ # @override from Python 3.12
40
+ def __str__(self) -> str: # type: ignore[explicit-override] # pyright: ignore[reportImplicitOverride]
41
+ """
42
+ Return string representation (useful for pytest logs).
43
+
44
+ Returns
45
+ -------
46
+ str
47
+ The operation's name.
48
+ """
49
+ return self.value
50
+
51
+
52
+ class Undef(Enum):
53
+ """Sentinel for undefined values."""
54
+
55
+ UNDEF = 0
56
+
57
+
58
+ _undef = Undef.UNDEF
59
+
60
+
61
+ class at: # pylint: disable=invalid-name # numpydoc ignore=PR02
62
+ """
63
+ Update operations for read-only arrays.
64
+
65
+ This implements ``jax.numpy.ndarray.at`` for all writeable
66
+ backends (those that support ``__setitem__``) and routes
67
+ to the ``.at[]`` method for JAX arrays.
68
+
69
+ Parameters
70
+ ----------
71
+ x : array
72
+ Input array.
73
+ idx : index, optional
74
+ Only `array API standard compliant indices
75
+ <https://data-apis.org/array-api/latest/API_specification/indexing.html>`_
76
+ are supported.
77
+
78
+ You may use two alternate syntaxes::
79
+
80
+ >>> import array_api_extra as xpx
81
+ >>> xpx.at(x, idx).set(value) # or add(value), etc.
82
+ >>> xpx.at(x)[idx].set(value)
83
+
84
+ copy : bool, optional
85
+ None (default)
86
+ The array parameter *may* be modified in place if it is
87
+ possible and beneficial for performance.
88
+ You should not reuse it after calling this function.
89
+ True
90
+ Ensure that the inputs are not modified.
91
+ False
92
+ Ensure that the update operation writes back to the input.
93
+ Raise ``ValueError`` if a copy cannot be avoided.
94
+
95
+ xp : array_namespace, optional
96
+ The standard-compatible namespace for `x`. Default: infer.
97
+
98
+ Returns
99
+ -------
100
+ Updated input array.
101
+
102
+ Warnings
103
+ --------
104
+ (a) When you omit the ``copy`` parameter, you should never reuse the parameter
105
+ array later on; ideally, you should reassign it immediately::
106
+
107
+ >>> import array_api_extra as xpx
108
+ >>> x = xpx.at(x, 0).set(2)
109
+
110
+ The above best practice pattern ensures that the behaviour won't change depending
111
+ on whether ``x`` is writeable or not, as the original ``x`` object is dereferenced
112
+ as soon as ``xpx.at`` returns; this way there is no risk to accidentally update it
113
+ twice.
114
+
115
+ On the reverse, the anti-pattern below must be avoided, as it will result in
116
+ different behaviour on read-only versus writeable arrays::
117
+
118
+ >>> x = xp.asarray([0, 0, 0])
119
+ >>> y = xpx.at(x, 0).set(2)
120
+ >>> z = xpx.at(x, 1).set(3)
121
+
122
+ In the above example, both calls to ``xpx.at`` update ``x`` in place *if possible*.
123
+ This causes the behaviour to diverge depending on whether ``x`` is writeable or not:
124
+
125
+ - If ``x`` is writeable, then after the snippet above you'll have
126
+ ``x == y == z == [2, 3, 0]``
127
+ - If ``x`` is read-only, then you'll end up with
128
+ ``x == [0, 0, 0]``, ``y == [2, 0, 0]`` and ``z == [0, 3, 0]``.
129
+
130
+ The correct pattern to use if you want diverging outputs from the same input is
131
+ to enforce copies::
132
+
133
+ >>> x = xp.asarray([0, 0, 0])
134
+ >>> y = xpx.at(x, 0).set(2, copy=True) # Never updates x
135
+ >>> z = xpx.at(x, 1).set(3) # May or may not update x in place
136
+ >>> del x # avoid accidental reuse of x as we don't know its state anymore
137
+
138
+ (b) The array API standard does not support integer array indices.
139
+ The behaviour of update methods when the index is an array of integers is
140
+ undefined and will vary between backends; this is particularly true when the
141
+ index contains multiple occurrences of the same index, e.g.::
142
+
143
+ >>> import numpy as np
144
+ >>> import jax.numpy as jnp
145
+ >>> import array_api_extra as xpx
146
+ >>> xpx.at(np.asarray([123]), np.asarray([0, 0])).add(1)
147
+ array([124])
148
+ >>> xpx.at(jnp.asarray([123]), jnp.asarray([0, 0])).add(1)
149
+ Array([125], dtype=int32)
150
+
151
+ See Also
152
+ --------
153
+ jax.numpy.ndarray.at : Equivalent array method in JAX.
154
+
155
+ Notes
156
+ -----
157
+ `sparse <https://sparse.pydata.org/>`_, as well as read-only arrays from libraries
158
+ not explicitly covered by ``array-api-compat``, are not supported by update
159
+ methods.
160
+
161
+ Boolean masks are supported on Dask and jitted JAX arrays exclusively
162
+ when `idx` has the same shape as `x` and `y` is 0-dimensional.
163
+ Note that this support is not available in JAX's native
164
+ ``x.at[mask].set(y)``.
165
+
166
+ This pattern::
167
+
168
+ >>> mask = m(x)
169
+ >>> x[mask] = f(x[mask])
170
+
171
+ Can't be replaced by `at`, as it won't work on Dask and JAX inside jax.jit::
172
+
173
+ >>> mask = m(x)
174
+ >>> x = xpx.at(x, mask).set(f(x[mask]) # Crash on Dask and jax.jit
175
+
176
+ You should instead use::
177
+
178
+ >>> x = xp.where(m(x), f(x), x)
179
+
180
+ Examples
181
+ --------
182
+ Given either of these equivalent expressions::
183
+
184
+ >>> import array_api_extra as xpx
185
+ >>> x = xpx.at(x)[1].add(2)
186
+ >>> x = xpx.at(x, 1).add(2)
187
+
188
+ If x is a JAX array, they are the same as::
189
+
190
+ >>> x = x.at[1].add(2)
191
+
192
+ If x is a read-only NumPy array, they are the same as::
193
+
194
+ >>> x = x.copy()
195
+ >>> x[1] += 2
196
+
197
+ For other known backends, they are the same as::
198
+
199
+ >>> x[1] += 2
200
+ """
201
+
202
+ _x: Array
203
+ _idx: SetIndex | Undef
204
+ __slots__: ClassVar[tuple[str, ...]] = ("_idx", "_x")
205
+
206
+ def __init__(
207
+ self, x: Array, idx: SetIndex | Undef = _undef, /
208
+ ) -> None: # numpydoc ignore=GL08
209
+ self._x = x
210
+ self._idx = idx
211
+
212
+ def __getitem__(self, idx: SetIndex, /) -> Self: # numpydoc ignore=PR01,RT01
213
+ """
214
+ Allow for the alternate syntax ``at(x)[start:stop:step]``.
215
+
216
+ It looks prettier than ``at(x, slice(start, stop, step))``
217
+ and feels more intuitive coming from the JAX documentation.
218
+ """
219
+ if self._idx is not _undef:
220
+ msg = "Index has already been set"
221
+ raise ValueError(msg)
222
+ return type(self)(self._x, idx)
223
+
224
+ def _op(
225
+ self,
226
+ at_op: _AtOp,
227
+ in_place_op: Callable[[Array, Array | complex], Array] | None,
228
+ out_of_place_op: Callable[[Array, Array], Array] | None,
229
+ y: Array | complex,
230
+ /,
231
+ copy: bool | None,
232
+ xp: ModuleType | None,
233
+ ) -> Array:
234
+ """
235
+ Implement all update operations.
236
+
237
+ Parameters
238
+ ----------
239
+ at_op : _AtOp
240
+ Method of JAX's Array.at[].
241
+ in_place_op : Callable[[Array, Array | complex], Array] | None
242
+ In-place operation to apply on mutable backends::
243
+
244
+ x[idx] = in_place_op(x[idx], y)
245
+
246
+ If None::
247
+
248
+ x[idx] = y
249
+
250
+ out_of_place_op : Callable[[Array, Array], Array] | None
251
+ Out-of-place operation to apply when idx is a boolean mask and the backend
252
+ doesn't support in-place updates::
253
+
254
+ x = xp.where(idx, out_of_place_op(x, y), x)
255
+
256
+ If None::
257
+
258
+ x = xp.where(idx, y, x)
259
+
260
+ y : array or complex
261
+ Right-hand side of the operation.
262
+ copy : bool or None
263
+ Whether to copy the input array. See the class docstring for details.
264
+ xp : array_namespace, optional
265
+ The array namespace for the input array. Default: infer.
266
+
267
+ Returns
268
+ -------
269
+ Array
270
+ Updated `x`.
271
+ """
272
+ from ._funcs import apply_where # pylint: disable=cyclic-import
273
+
274
+ x, idx = self._x, self._idx
275
+ xp = array_namespace(x, y) if xp is None else xp
276
+
277
+ if isinstance(idx, Undef):
278
+ msg = (
279
+ "Index has not been set.\n"
280
+ "Usage: either\n"
281
+ " at(x, idx).set(value)\n"
282
+ "or\n"
283
+ " at(x)[idx].set(value)\n"
284
+ "(same for all other methods)."
285
+ )
286
+ raise ValueError(msg)
287
+
288
+ if copy not in (True, False, None):
289
+ msg = f"copy must be True, False, or None; got {copy!r}"
290
+ raise ValueError(msg)
291
+
292
+ writeable = None if copy else is_writeable_array(x)
293
+
294
+ # JAX inside jax.jit doesn't support in-place updates with boolean
295
+ # masks; Dask exclusively supports __setitem__ but not iops.
296
+ # We can handle the common special case of 0-dimensional y
297
+ # with where(idx, y, x) instead.
298
+ if (
299
+ (is_dask_array(idx) or is_jax_array(idx))
300
+ and idx.dtype == xp.bool
301
+ and idx.shape == x.shape
302
+ ):
303
+ y_xp = xp.asarray(y, dtype=x.dtype, device=_compat.device(x))
304
+ if y_xp.ndim == 0:
305
+ if out_of_place_op: # add(), subtract(), ...
306
+ # suppress inf warnings on Dask
307
+ out = apply_where(
308
+ idx, (x, y_xp), out_of_place_op, fill_value=x, xp=xp
309
+ )
310
+ # Undo int->float promotion on JAX after _AtOp.DIVIDE
311
+ out = xp.astype(out, x.dtype, copy=False)
312
+ else: # set()
313
+ out = xp.where(idx, y_xp, x)
314
+
315
+ if copy is False:
316
+ x[()] = out
317
+ return x
318
+ return out
319
+
320
+ # else: this will work on eager JAX and crash on jax.jit and Dask
321
+
322
+ if copy or (copy is None and not writeable):
323
+ if is_jax_array(x):
324
+ # Use JAX's at[]
325
+ func = cast(
326
+ Callable[[Array | complex], Array],
327
+ getattr(x.at[idx], at_op.value), # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue,reportUnknownArgumentType]
328
+ )
329
+ out = func(y)
330
+ # Undo int->float promotion on JAX after _AtOp.DIVIDE
331
+ return xp.astype(out, x.dtype, copy=False)
332
+
333
+ # Emulate at[] behaviour for non-JAX arrays
334
+ # with a copy followed by an update
335
+
336
+ x = xp.asarray(x, copy=True)
337
+ # A copy of a read-only numpy array is writeable
338
+ # Note: this assumes that a copy of a writeable array is writeable
339
+ assert not writeable
340
+ writeable = None
341
+
342
+ if writeable is None:
343
+ writeable = is_writeable_array(x)
344
+ if not writeable:
345
+ # sparse crashes here
346
+ msg = f"Can't update read-only array {x}"
347
+ raise ValueError(msg)
348
+
349
+ # Work around bug in PyTorch where __setitem__ doesn't
350
+ # always support mismatched dtypes
351
+ # https://github.com/pytorch/pytorch/issues/150017
352
+ if is_torch_array(y):
353
+ y = xp.astype(y, x.dtype, copy=False)
354
+
355
+ # Backends without boolean indexing (other than JAX) crash here
356
+ if in_place_op: # add(), subtract(), ...
357
+ x[idx] = in_place_op(x[idx], y)
358
+ else: # set()
359
+ x[idx] = y
360
+ return x
361
+
362
+ def set(
363
+ self,
364
+ y: Array | complex,
365
+ /,
366
+ copy: bool | None = None,
367
+ xp: ModuleType | None = None,
368
+ ) -> Array: # numpydoc ignore=PR01,RT01
369
+ """Apply ``x[idx] = y`` and return the update array."""
370
+ return self._op(_AtOp.SET, None, None, y, copy=copy, xp=xp)
371
+
372
+ def add(
373
+ self,
374
+ y: Array | complex,
375
+ /,
376
+ copy: bool | None = None,
377
+ xp: ModuleType | None = None,
378
+ ) -> Array: # numpydoc ignore=PR01,RT01
379
+ """Apply ``x[idx] += y`` and return the updated array."""
380
+
381
+ # Note for this and all other methods based on _iop:
382
+ # operator.iadd and operator.add subtly differ in behaviour, as
383
+ # only iadd will trigger exceptions when y has an incompatible dtype.
384
+ return self._op(_AtOp.ADD, operator.iadd, operator.add, y, copy=copy, xp=xp)
385
+
386
+ def subtract(
387
+ self,
388
+ y: Array | complex,
389
+ /,
390
+ copy: bool | None = None,
391
+ xp: ModuleType | None = None,
392
+ ) -> Array: # numpydoc ignore=PR01,RT01
393
+ """Apply ``x[idx] -= y`` and return the updated array."""
394
+ return self._op(
395
+ _AtOp.SUBTRACT, operator.isub, operator.sub, y, copy=copy, xp=xp
396
+ )
397
+
398
+ def multiply(
399
+ self,
400
+ y: Array | complex,
401
+ /,
402
+ copy: bool | None = None,
403
+ xp: ModuleType | None = None,
404
+ ) -> Array: # numpydoc ignore=PR01,RT01
405
+ """Apply ``x[idx] *= y`` and return the updated array."""
406
+ return self._op(
407
+ _AtOp.MULTIPLY, operator.imul, operator.mul, y, copy=copy, xp=xp
408
+ )
409
+
410
+ def divide(
411
+ self,
412
+ y: Array | complex,
413
+ /,
414
+ copy: bool | None = None,
415
+ xp: ModuleType | None = None,
416
+ ) -> Array: # numpydoc ignore=PR01,RT01
417
+ """Apply ``x[idx] /= y`` and return the updated array."""
418
+ return self._op(
419
+ _AtOp.DIVIDE, operator.itruediv, operator.truediv, y, copy=copy, xp=xp
420
+ )
421
+
422
+ def power(
423
+ self,
424
+ y: Array | complex,
425
+ /,
426
+ copy: bool | None = None,
427
+ xp: ModuleType | None = None,
428
+ ) -> Array: # numpydoc ignore=PR01,RT01
429
+ """Apply ``x[idx] **= y`` and return the updated array."""
430
+ return self._op(_AtOp.POWER, operator.ipow, operator.pow, y, copy=copy, xp=xp)
431
+
432
+ def min(
433
+ self,
434
+ y: Array | complex,
435
+ /,
436
+ copy: bool | None = None,
437
+ xp: ModuleType | None = None,
438
+ ) -> Array: # numpydoc ignore=PR01,RT01
439
+ """Apply ``x[idx] = minimum(x[idx], y)`` and return the updated array."""
440
+ # On Dask, this function runs on the chunks, so we need to determine the
441
+ # namespace that Dask is wrapping.
442
+ # Note that da.minimum _incidentally_ works on NumPy, CuPy, and sparse
443
+ # thanks to all these meta-namespaces implementing the __array_ufunc__
444
+ # interface, but there's no guarantee that it will work for other
445
+ # wrapped libraries in the future.
446
+ xp = array_namespace(self._x) if xp is None else xp
447
+ mxp = meta_namespace(self._x, xp=xp)
448
+ y = xp.asarray(y)
449
+ return self._op(_AtOp.MIN, mxp.minimum, mxp.minimum, y, copy=copy, xp=xp)
450
+
451
+ def max(
452
+ self,
453
+ y: Array | complex,
454
+ /,
455
+ copy: bool | None = None,
456
+ xp: ModuleType | None = None,
457
+ ) -> Array: # numpydoc ignore=PR01,RT01
458
+ """Apply ``x[idx] = maximum(x[idx], y)`` and return the updated array."""
459
+ # See note on min()
460
+ xp = array_namespace(self._x) if xp is None else xp
461
+ mxp = meta_namespace(self._x, xp=xp)
462
+ y = xp.asarray(y)
463
+ return self._op(_AtOp.MAX, mxp.maximum, mxp.maximum, y, copy=copy, xp=xp)
@@ -0,0 +1,46 @@
1
+ """Backends against which array-api-extra runs its tests."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+
7
+ __all__ = ["Backend"]
8
+
9
+
10
+ class Backend(Enum): # numpydoc ignore=PR02
11
+ """
12
+ All array library backends explicitly tested by array-api-extra.
13
+
14
+ Parameters
15
+ ----------
16
+ value : str
17
+ Tag of the backend's module, in the format ``<namespace>[:<extra tag>]``.
18
+ """
19
+
20
+ # Use :<tag> to prevent Enum from deduplicating items with the same value
21
+ ARRAY_API_STRICT = "array_api_strict"
22
+ ARRAY_API_STRICTEST = "array_api_strict:strictest"
23
+ NUMPY = "numpy"
24
+ NUMPY_READONLY = "numpy:readonly"
25
+ CUPY = "cupy"
26
+ TORCH = "torch"
27
+ TORCH_GPU = "torch:gpu"
28
+ DASK = "dask.array"
29
+ SPARSE = "sparse"
30
+ JAX = "jax.numpy"
31
+ JAX_GPU = "jax.numpy:gpu"
32
+
33
+ def __str__(self) -> str: # type: ignore[explicit-override] # pyright: ignore[reportImplicitOverride] # numpydoc ignore=RT01
34
+ """Pretty-print parameterized test names."""
35
+ return (
36
+ self.name.lower().replace("_gpu", ":gpu").replace("_readonly", ":readonly")
37
+ )
38
+
39
+ @property
40
+ def modname(self) -> str: # numpydoc ignore=RT01
41
+ """Module name to be imported."""
42
+ return self.value.split(":")[0]
43
+
44
+ def like(self, *others: Backend) -> bool: # numpydoc ignore=PR01,RT01
45
+ """Check if this backend uses the same module as others."""
46
+ return any(self.modname == other.modname for other in others)