scipy 1.15.3__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0rc2__cp312-cp312-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 (628) hide show
  1. scipy/__config__.py +4 -4
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-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-312-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-312-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  128. scipy/integrate/_quad_vec.py +21 -29
  129. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  130. scipy/integrate/_quadpack_py.py +11 -7
  131. scipy/integrate/_quadrature.py +3 -3
  132. scipy/integrate/_rules/_base.py +2 -2
  133. scipy/integrate/_tanhsinh.py +48 -47
  134. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  136. scipy/integrate/tests/test__quad_vec.py +0 -6
  137. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  138. scipy/integrate/tests/test_cubature.py +21 -35
  139. scipy/integrate/tests/test_quadrature.py +6 -8
  140. scipy/integrate/tests/test_tanhsinh.py +56 -48
  141. scipy/interpolate/__init__.py +70 -58
  142. scipy/interpolate/_bary_rational.py +22 -22
  143. scipy/interpolate/_bsplines.py +119 -66
  144. scipy/interpolate/_cubic.py +65 -50
  145. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  146. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  148. scipy/interpolate/_fitpack2.py +9 -6
  149. scipy/interpolate/_fitpack_impl.py +32 -26
  150. scipy/interpolate/_fitpack_repro.py +23 -19
  151. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  152. scipy/interpolate/_interpolate.py +30 -12
  153. scipy/interpolate/_ndbspline.py +13 -18
  154. scipy/interpolate/_ndgriddata.py +5 -8
  155. scipy/interpolate/_polyint.py +95 -31
  156. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  157. scipy/interpolate/_rbf.py +2 -2
  158. scipy/interpolate/_rbfinterp.py +1 -1
  159. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  160. scipy/interpolate/_rgi.py +31 -26
  161. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  162. scipy/interpolate/dfitpack.py +0 -20
  163. scipy/interpolate/interpnd.py +1 -2
  164. scipy/interpolate/tests/test_bary_rational.py +2 -2
  165. scipy/interpolate/tests/test_bsplines.py +97 -1
  166. scipy/interpolate/tests/test_fitpack2.py +39 -1
  167. scipy/interpolate/tests/test_interpnd.py +32 -20
  168. scipy/interpolate/tests/test_interpolate.py +48 -4
  169. scipy/interpolate/tests/test_rgi.py +2 -1
  170. scipy/io/_fast_matrix_market/__init__.py +2 -0
  171. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  172. scipy/io/_harwell_boeing/hb.py +7 -11
  173. scipy/io/_idl.py +5 -7
  174. scipy/io/_netcdf.py +15 -5
  175. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  176. scipy/io/arff/tests/test_arffread.py +3 -3
  177. scipy/io/matlab/__init__.py +5 -3
  178. scipy/io/matlab/_mio.py +4 -1
  179. scipy/io/matlab/_mio5.py +19 -13
  180. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  181. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/_miobase.py +4 -1
  183. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  184. scipy/io/matlab/tests/test_mio.py +46 -18
  185. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  186. scipy/io/tests/test_mmio.py +7 -1
  187. scipy/io/tests/test_wavfile.py +41 -0
  188. scipy/io/wavfile.py +57 -10
  189. scipy/linalg/_basic.py +113 -86
  190. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  191. scipy/linalg/_decomp.py +22 -9
  192. scipy/linalg/_decomp_cholesky.py +28 -13
  193. scipy/linalg/_decomp_cossin.py +45 -30
  194. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  195. scipy/linalg/_decomp_ldl.py +4 -1
  196. scipy/linalg/_decomp_lu.py +18 -6
  197. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp_polar.py +2 -0
  199. scipy/linalg/_decomp_qr.py +6 -2
  200. scipy/linalg/_decomp_qz.py +3 -0
  201. scipy/linalg/_decomp_schur.py +3 -1
  202. scipy/linalg/_decomp_svd.py +13 -2
  203. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  204. scipy/linalg/_expm_frechet.py +4 -0
  205. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  206. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_matfuncs.py +187 -4
  209. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  210. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  212. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_procrustes.py +2 -0
  214. scipy/linalg/_sketches.py +17 -6
  215. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  216. scipy/linalg/_solvers.py +7 -2
  217. scipy/linalg/_special_matrices.py +26 -36
  218. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  219. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  220. scipy/linalg/lapack.py +22 -2
  221. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  222. scipy/linalg/tests/test_basic.py +31 -16
  223. scipy/linalg/tests/test_batch.py +588 -0
  224. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  225. scipy/linalg/tests/test_decomp.py +40 -3
  226. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  227. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  228. scipy/linalg/tests/test_lapack.py +115 -7
  229. scipy/linalg/tests/test_matfuncs.py +157 -102
  230. scipy/linalg/tests/test_procrustes.py +0 -7
  231. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  232. scipy/linalg/tests/test_special_matrices.py +1 -5
  233. scipy/ndimage/__init__.py +1 -0
  234. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  235. scipy/ndimage/_delegators.py +8 -2
  236. scipy/ndimage/_filters.py +453 -5
  237. scipy/ndimage/_interpolation.py +36 -6
  238. scipy/ndimage/_measurements.py +4 -2
  239. scipy/ndimage/_morphology.py +5 -0
  240. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  241. scipy/ndimage/_ni_docstrings.py +5 -1
  242. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  243. scipy/ndimage/_ni_support.py +1 -5
  244. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  245. scipy/ndimage/_support_alternative_backends.py +18 -6
  246. scipy/ndimage/tests/test_filters.py +370 -259
  247. scipy/ndimage/tests/test_fourier.py +7 -9
  248. scipy/ndimage/tests/test_interpolation.py +68 -61
  249. scipy/ndimage/tests/test_measurements.py +18 -35
  250. scipy/ndimage/tests/test_morphology.py +143 -131
  251. scipy/ndimage/tests/test_splines.py +1 -3
  252. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  253. scipy/optimize/_basinhopping.py +13 -7
  254. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  255. scipy/optimize/_bracket.py +17 -24
  256. scipy/optimize/_chandrupatla.py +9 -10
  257. scipy/optimize/_cobyla_py.py +104 -123
  258. scipy/optimize/_constraints.py +14 -10
  259. scipy/optimize/_differentiable_functions.py +371 -230
  260. scipy/optimize/_differentialevolution.py +4 -3
  261. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  262. scipy/optimize/_dual_annealing.py +1 -1
  263. scipy/optimize/_elementwise.py +1 -4
  264. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb_py.py +57 -16
  267. scipy/optimize/_linprog_doc.py +2 -2
  268. scipy/optimize/_linprog_highs.py +2 -2
  269. scipy/optimize/_linprog_ip.py +25 -10
  270. scipy/optimize/_linprog_util.py +14 -16
  271. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_lsq/common.py +3 -3
  273. scipy/optimize/_lsq/dogbox.py +16 -2
  274. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_lsq/least_squares.py +198 -126
  276. scipy/optimize/_lsq/lsq_linear.py +6 -6
  277. scipy/optimize/_lsq/trf.py +35 -8
  278. scipy/optimize/_milp.py +3 -1
  279. scipy/optimize/_minimize.py +105 -36
  280. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  281. scipy/optimize/_minpack_py.py +21 -14
  282. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_nnls.py +20 -21
  284. scipy/optimize/_nonlin.py +34 -3
  285. scipy/optimize/_numdiff.py +288 -110
  286. scipy/optimize/_optimize.py +86 -48
  287. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  288. scipy/optimize/_remove_redundancy.py +5 -5
  289. scipy/optimize/_root_scalar.py +1 -1
  290. scipy/optimize/_shgo.py +6 -0
  291. scipy/optimize/_shgo_lib/_complex.py +1 -1
  292. scipy/optimize/_slsqp_py.py +216 -124
  293. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_spectral.py +1 -1
  295. scipy/optimize/_tnc.py +8 -1
  296. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  297. scipy/optimize/_trustregion.py +20 -6
  298. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  299. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  300. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  301. scipy/optimize/_trustregion_constr/projections.py +12 -8
  302. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  303. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  304. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  305. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  306. scipy/optimize/_trustregion_exact.py +0 -1
  307. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_zeros_py.py +97 -17
  309. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  310. scipy/optimize/slsqp.py +0 -1
  311. scipy/optimize/tests/test__basinhopping.py +1 -1
  312. scipy/optimize/tests/test__differential_evolution.py +4 -4
  313. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  314. scipy/optimize/tests/test__numdiff.py +66 -22
  315. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  316. scipy/optimize/tests/test__shgo.py +9 -1
  317. scipy/optimize/tests/test_bracket.py +36 -46
  318. scipy/optimize/tests/test_chandrupatla.py +133 -135
  319. scipy/optimize/tests/test_cobyla.py +74 -45
  320. scipy/optimize/tests/test_constraints.py +1 -1
  321. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  322. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  323. scipy/optimize/tests/test_least_squares.py +125 -13
  324. scipy/optimize/tests/test_linear_assignment.py +3 -3
  325. scipy/optimize/tests/test_linprog.py +3 -3
  326. scipy/optimize/tests/test_lsq_linear.py +6 -6
  327. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  328. scipy/optimize/tests/test_minpack.py +4 -4
  329. scipy/optimize/tests/test_nnls.py +43 -3
  330. scipy/optimize/tests/test_nonlin.py +36 -0
  331. scipy/optimize/tests/test_optimize.py +95 -17
  332. scipy/optimize/tests/test_slsqp.py +36 -4
  333. scipy/optimize/tests/test_zeros.py +34 -1
  334. scipy/signal/__init__.py +12 -23
  335. scipy/signal/_delegators.py +568 -0
  336. scipy/signal/_filter_design.py +459 -241
  337. scipy/signal/_fir_filter_design.py +262 -90
  338. scipy/signal/_lti_conversion.py +3 -2
  339. scipy/signal/_ltisys.py +118 -91
  340. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  341. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  342. scipy/signal/_polyutils.py +172 -0
  343. scipy/signal/_short_time_fft.py +519 -70
  344. scipy/signal/_signal_api.py +30 -0
  345. scipy/signal/_signaltools.py +719 -399
  346. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  347. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  348. scipy/signal/_spectral_py.py +230 -50
  349. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  350. scipy/signal/_spline_filters.py +108 -68
  351. scipy/signal/_support_alternative_backends.py +73 -0
  352. scipy/signal/_upfirdn.py +4 -1
  353. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  354. scipy/signal/_waveforms.py +2 -11
  355. scipy/signal/_wavelets.py +1 -1
  356. scipy/signal/fir_filter_design.py +1 -0
  357. scipy/signal/spline.py +4 -11
  358. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  359. scipy/signal/tests/test_bsplines.py +114 -79
  360. scipy/signal/tests/test_cont2discrete.py +9 -2
  361. scipy/signal/tests/test_filter_design.py +721 -481
  362. scipy/signal/tests/test_fir_filter_design.py +332 -140
  363. scipy/signal/tests/test_savitzky_golay.py +4 -3
  364. scipy/signal/tests/test_short_time_fft.py +221 -3
  365. scipy/signal/tests/test_signaltools.py +2144 -1348
  366. scipy/signal/tests/test_spectral.py +50 -6
  367. scipy/signal/tests/test_splines.py +161 -96
  368. scipy/signal/tests/test_upfirdn.py +84 -50
  369. scipy/signal/tests/test_waveforms.py +20 -0
  370. scipy/signal/tests/test_windows.py +607 -466
  371. scipy/signal/windows/_windows.py +287 -148
  372. scipy/sparse/__init__.py +23 -4
  373. scipy/sparse/_base.py +270 -108
  374. scipy/sparse/_bsr.py +7 -4
  375. scipy/sparse/_compressed.py +59 -231
  376. scipy/sparse/_construct.py +90 -38
  377. scipy/sparse/_coo.py +115 -181
  378. scipy/sparse/_csc.py +4 -4
  379. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  380. scipy/sparse/_csr.py +2 -2
  381. scipy/sparse/_data.py +48 -48
  382. scipy/sparse/_dia.py +105 -18
  383. scipy/sparse/_dok.py +0 -23
  384. scipy/sparse/_index.py +4 -4
  385. scipy/sparse/_matrix.py +23 -0
  386. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  387. scipy/sparse/_sputils.py +37 -22
  388. scipy/sparse/base.py +0 -9
  389. scipy/sparse/bsr.py +0 -14
  390. scipy/sparse/compressed.py +0 -23
  391. scipy/sparse/construct.py +0 -6
  392. scipy/sparse/coo.py +0 -14
  393. scipy/sparse/csc.py +0 -3
  394. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  395. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  396. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  397. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  398. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  399. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  400. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  401. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  402. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  403. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  404. scipy/sparse/csr.py +0 -5
  405. scipy/sparse/data.py +1 -6
  406. scipy/sparse/dia.py +0 -7
  407. scipy/sparse/dok.py +0 -10
  408. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  409. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  410. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  411. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  412. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  413. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  414. scipy/sparse/linalg/_interface.py +17 -18
  415. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  416. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  417. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  418. scipy/sparse/linalg/_isolve/minres.py +5 -5
  419. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  420. scipy/sparse/linalg/_isolve/utils.py +2 -8
  421. scipy/sparse/linalg/_matfuncs.py +1 -1
  422. scipy/sparse/linalg/_norm.py +1 -1
  423. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  424. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  427. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  428. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  429. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  430. scipy/sparse/tests/test_base.py +214 -42
  431. scipy/sparse/tests/test_common1d.py +7 -7
  432. scipy/sparse/tests/test_construct.py +1 -1
  433. scipy/sparse/tests/test_coo.py +272 -4
  434. scipy/sparse/tests/test_sparsetools.py +5 -0
  435. scipy/sparse/tests/test_sputils.py +36 -7
  436. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  437. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  438. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  439. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  440. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  441. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  442. scipy/spatial/distance.py +49 -42
  443. scipy/spatial/tests/test_distance.py +15 -1
  444. scipy/spatial/tests/test_kdtree.py +1 -0
  445. scipy/spatial/tests/test_qhull.py +7 -2
  446. scipy/spatial/transform/__init__.py +5 -3
  447. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  448. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  449. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  450. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  451. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  452. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  453. scipy/special/__init__.py +1 -47
  454. scipy/special/_add_newdocs.py +34 -772
  455. scipy/special/_basic.py +22 -25
  456. scipy/special/_comb.cpython-312-darwin.so +0 -0
  457. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  458. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  459. scipy/special/_logsumexp.py +67 -58
  460. scipy/special/_orthogonal.pyi +1 -1
  461. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  462. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  463. scipy/special/_spherical_bessel.py +4 -4
  464. scipy/special/_support_alternative_backends.py +212 -119
  465. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  466. scipy/special/_testutils.py +4 -4
  467. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  468. scipy/special/_ufuncs.pyi +1 -0
  469. scipy/special/_ufuncs.pyx +215 -1400
  470. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  471. scipy/special/_ufuncs_cxx.pxd +2 -15
  472. scipy/special/_ufuncs_cxx.pyx +5 -44
  473. scipy/special/_ufuncs_cxx_defs.h +2 -16
  474. scipy/special/_ufuncs_defs.h +0 -8
  475. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  476. scipy/special/cython_special.pxd +1 -1
  477. scipy/special/tests/_cython_examples/meson.build +10 -1
  478. scipy/special/tests/test_basic.py +153 -20
  479. scipy/special/tests/test_boost_ufuncs.py +3 -0
  480. scipy/special/tests/test_cdflib.py +35 -11
  481. scipy/special/tests/test_gammainc.py +16 -0
  482. scipy/special/tests/test_hyp2f1.py +2 -2
  483. scipy/special/tests/test_log1mexp.py +85 -0
  484. scipy/special/tests/test_logsumexp.py +206 -64
  485. scipy/special/tests/test_mpmath.py +1 -0
  486. scipy/special/tests/test_nan_inputs.py +1 -1
  487. scipy/special/tests/test_orthogonal.py +17 -18
  488. scipy/special/tests/test_sf_error.py +3 -2
  489. scipy/special/tests/test_sph_harm.py +6 -7
  490. scipy/special/tests/test_support_alternative_backends.py +211 -76
  491. scipy/stats/__init__.py +4 -1
  492. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  493. scipy/stats/_axis_nan_policy.py +5 -12
  494. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  495. scipy/stats/_continued_fraction.py +387 -0
  496. scipy/stats/_continuous_distns.py +277 -310
  497. scipy/stats/_correlation.py +1 -1
  498. scipy/stats/_covariance.py +6 -3
  499. scipy/stats/_discrete_distns.py +39 -32
  500. scipy/stats/_distn_infrastructure.py +39 -12
  501. scipy/stats/_distribution_infrastructure.py +900 -238
  502. scipy/stats/_entropy.py +9 -10
  503. scipy/{_lib → stats}/_finite_differences.py +1 -1
  504. scipy/stats/_hypotests.py +83 -50
  505. scipy/stats/_kde.py +53 -49
  506. scipy/stats/_ksstats.py +1 -1
  507. scipy/stats/_levy_stable/__init__.py +7 -15
  508. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  509. scipy/stats/_morestats.py +118 -73
  510. scipy/stats/_mstats_basic.py +13 -17
  511. scipy/stats/_mstats_extras.py +8 -8
  512. scipy/stats/_multivariate.py +89 -113
  513. scipy/stats/_new_distributions.py +97 -20
  514. scipy/stats/_page_trend_test.py +12 -5
  515. scipy/stats/_probability_distribution.py +265 -43
  516. scipy/stats/_qmc.py +14 -9
  517. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  518. scipy/stats/_qmvnt.py +16 -95
  519. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  520. scipy/stats/_quantile.py +335 -0
  521. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  522. scipy/stats/_resampling.py +4 -29
  523. scipy/stats/_sampling.py +1 -1
  524. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  525. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  526. scipy/stats/_stats_mstats_common.py +21 -2
  527. scipy/stats/_stats_py.py +550 -476
  528. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  529. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  531. scipy/stats/_variation.py +6 -8
  532. scipy/stats/_wilcoxon.py +13 -7
  533. scipy/stats/tests/common_tests.py +6 -4
  534. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  535. scipy/stats/tests/test_continued_fraction.py +173 -0
  536. scipy/stats/tests/test_continuous.py +379 -60
  537. scipy/stats/tests/test_continuous_basic.py +18 -12
  538. scipy/stats/tests/test_discrete_basic.py +14 -8
  539. scipy/stats/tests/test_discrete_distns.py +16 -16
  540. scipy/stats/tests/test_distributions.py +95 -75
  541. scipy/stats/tests/test_entropy.py +40 -48
  542. scipy/stats/tests/test_fit.py +4 -3
  543. scipy/stats/tests/test_hypotests.py +153 -24
  544. scipy/stats/tests/test_kdeoth.py +109 -41
  545. scipy/stats/tests/test_marray.py +289 -0
  546. scipy/stats/tests/test_morestats.py +79 -47
  547. scipy/stats/tests/test_mstats_basic.py +3 -3
  548. scipy/stats/tests/test_multivariate.py +434 -83
  549. scipy/stats/tests/test_qmc.py +13 -10
  550. scipy/stats/tests/test_quantile.py +199 -0
  551. scipy/stats/tests/test_rank.py +119 -112
  552. scipy/stats/tests/test_resampling.py +47 -56
  553. scipy/stats/tests/test_sampling.py +9 -4
  554. scipy/stats/tests/test_stats.py +799 -939
  555. scipy/stats/tests/test_variation.py +8 -6
  556. scipy/version.py +2 -2
  557. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +560 -567
  560. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  561. scipy/_lib/array_api_extra/_funcs.py +0 -484
  562. scipy/_lib/array_api_extra/_typing.py +0 -8
  563. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  564. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  565. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  566. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  567. scipy/spatial/qhull_src/COPYING.txt +0 -38
  568. scipy/special/libsf_error_state.dylib +0 -0
  569. scipy/special/tests/test_log_softmax.py +0 -109
  570. scipy/special/tests/test_xsf_cuda.py +0 -114
  571. scipy/special/xsf/binom.h +0 -89
  572. scipy/special/xsf/cdflib.h +0 -100
  573. scipy/special/xsf/cephes/airy.h +0 -307
  574. scipy/special/xsf/cephes/besselpoly.h +0 -51
  575. scipy/special/xsf/cephes/beta.h +0 -257
  576. scipy/special/xsf/cephes/cbrt.h +0 -131
  577. scipy/special/xsf/cephes/chbevl.h +0 -85
  578. scipy/special/xsf/cephes/chdtr.h +0 -193
  579. scipy/special/xsf/cephes/const.h +0 -87
  580. scipy/special/xsf/cephes/ellie.h +0 -293
  581. scipy/special/xsf/cephes/ellik.h +0 -251
  582. scipy/special/xsf/cephes/ellpe.h +0 -107
  583. scipy/special/xsf/cephes/ellpk.h +0 -117
  584. scipy/special/xsf/cephes/expn.h +0 -260
  585. scipy/special/xsf/cephes/gamma.h +0 -398
  586. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  587. scipy/special/xsf/cephes/hyperg.h +0 -361
  588. scipy/special/xsf/cephes/i0.h +0 -149
  589. scipy/special/xsf/cephes/i1.h +0 -158
  590. scipy/special/xsf/cephes/igam.h +0 -421
  591. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  592. scipy/special/xsf/cephes/igami.h +0 -313
  593. scipy/special/xsf/cephes/j0.h +0 -225
  594. scipy/special/xsf/cephes/j1.h +0 -198
  595. scipy/special/xsf/cephes/jv.h +0 -715
  596. scipy/special/xsf/cephes/k0.h +0 -164
  597. scipy/special/xsf/cephes/k1.h +0 -163
  598. scipy/special/xsf/cephes/kn.h +0 -243
  599. scipy/special/xsf/cephes/lanczos.h +0 -112
  600. scipy/special/xsf/cephes/ndtr.h +0 -275
  601. scipy/special/xsf/cephes/poch.h +0 -85
  602. scipy/special/xsf/cephes/polevl.h +0 -167
  603. scipy/special/xsf/cephes/psi.h +0 -194
  604. scipy/special/xsf/cephes/rgamma.h +0 -111
  605. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  606. scipy/special/xsf/cephes/shichi.h +0 -248
  607. scipy/special/xsf/cephes/sici.h +0 -224
  608. scipy/special/xsf/cephes/sindg.h +0 -221
  609. scipy/special/xsf/cephes/tandg.h +0 -139
  610. scipy/special/xsf/cephes/trig.h +0 -58
  611. scipy/special/xsf/cephes/unity.h +0 -186
  612. scipy/special/xsf/cephes/zeta.h +0 -172
  613. scipy/special/xsf/config.h +0 -304
  614. scipy/special/xsf/digamma.h +0 -205
  615. scipy/special/xsf/error.h +0 -57
  616. scipy/special/xsf/evalpoly.h +0 -47
  617. scipy/special/xsf/expint.h +0 -266
  618. scipy/special/xsf/hyp2f1.h +0 -694
  619. scipy/special/xsf/iv_ratio.h +0 -173
  620. scipy/special/xsf/lambertw.h +0 -150
  621. scipy/special/xsf/loggamma.h +0 -163
  622. scipy/special/xsf/sici.h +0 -200
  623. scipy/special/xsf/tools.h +0 -427
  624. scipy/special/xsf/trig.h +0 -164
  625. scipy/special/xsf/wright_bessel.h +0 -843
  626. scipy/special/xsf/zlog1.h +0 -35
  627. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  628. scipy-1.15.3.dist-info/WHEEL +0 -4
scipy/special/_basic.py CHANGED
@@ -2693,10 +2693,6 @@ def comb(N, k, *, exact=False, repetition=False):
2693
2693
  exact : bool, optional
2694
2694
  For integers, if `exact` is False, then floating point precision is
2695
2695
  used, otherwise the result is computed exactly.
2696
-
2697
- .. deprecated:: 1.14.0
2698
- ``exact=True`` is deprecated for non-integer `N` and `k` and will raise an
2699
- error in SciPy 1.16.0
2700
2696
  repetition : bool, optional
2701
2697
  If `repetition` is True, then the number of combinations with
2702
2698
  repetition is computed.
@@ -2737,12 +2733,9 @@ def comb(N, k, *, exact=False, repetition=False):
2737
2733
  if int(N) == N and int(k) == k:
2738
2734
  # _comb_int casts inputs to integers, which is safe & intended here
2739
2735
  return _comb_int(N, k)
2740
- # otherwise, we disregard `exact=True`; it makes no sense for
2741
- # non-integral arguments
2742
- msg = ("`exact=True` is deprecated for non-integer `N` and `k` and will raise "
2743
- "an error in SciPy 1.16.0")
2744
- warnings.warn(msg, DeprecationWarning, stacklevel=2)
2745
- return comb(N, k)
2736
+ else:
2737
+ raise ValueError("Non-integer `N` and `k` with `exact=True` is not "
2738
+ "supported.")
2746
2739
  else:
2747
2740
  k, N = asarray(k), asarray(N)
2748
2741
  cond = (k <= N) & (N >= 0) & (k >= 0)
@@ -2796,19 +2789,17 @@ def perm(N, k, exact=False):
2796
2789
  N = np.squeeze(N)[()] # for backward compatibility (accepted size 1 arrays)
2797
2790
  k = np.squeeze(k)[()]
2798
2791
  if not (isscalar(N) and isscalar(k)):
2799
- raise ValueError("`N` and `k` must scalar integers be with `exact=True`.")
2792
+ raise ValueError("`N` and `k` must be scalar integers with `exact=True`.")
2800
2793
 
2801
2794
  floor_N, floor_k = int(N), int(k)
2802
2795
  non_integral = not (floor_N == N and floor_k == k)
2803
- if (k > N) or (N < 0) or (k < 0):
2804
- if non_integral:
2805
- msg = ("Non-integer `N` and `k` with `exact=True` is deprecated and "
2806
- "will raise an error in SciPy 1.16.0.")
2807
- warnings.warn(msg, DeprecationWarning, stacklevel=2)
2808
- return 0
2809
2796
  if non_integral:
2810
2797
  raise ValueError("Non-integer `N` and `k` with `exact=True` is not "
2811
2798
  "supported.")
2799
+
2800
+ if (k > N) or (N < 0) or (k < 0):
2801
+ return 0
2802
+
2812
2803
  val = 1
2813
2804
  for i in range(floor_N - floor_k + 1, floor_N + 1):
2814
2805
  val *= i
@@ -2990,14 +2981,20 @@ def _factorialx_approx_core(n, k, extend):
2990
2981
  # scalar case separately, unified handling would be inefficient for arrays;
2991
2982
  # don't use isscalar due to numpy/numpy#23574; 0-dim arrays treated below
2992
2983
  if not isinstance(n, np.ndarray):
2993
- return (
2994
- np.power(k, (n - n_mod_k) / k)
2995
- * gamma(n / k + 1) / gamma(n_mod_k / k + 1)
2996
- * max(n_mod_k, 1)
2997
- )
2984
+ with warnings.catch_warnings():
2985
+ # large n cause overflow warnings, but infinity is fine
2986
+ warnings.simplefilter("ignore", RuntimeWarning)
2987
+ return (
2988
+ np.power(k, (n - n_mod_k) / k)
2989
+ * gamma(n / k + 1) / gamma(n_mod_k / k + 1)
2990
+ * max(n_mod_k, 1)
2991
+ )
2998
2992
 
2999
2993
  # factor that's independent of the residue class (see factorialk docstring)
3000
- result = np.power(k, n / k) * gamma(n / k + 1)
2994
+ with warnings.catch_warnings():
2995
+ # large n cause overflow warnings, but infinity is fine
2996
+ warnings.simplefilter("ignore", RuntimeWarning)
2997
+ result = np.power(k, n / k) * gamma(n / k + 1)
3001
2998
  # factor dependent on residue r (for `r=0` it's 1, so we skip `r=0`
3002
2999
  # below and thus also avoid evaluating `max(r, 1)`)
3003
3000
  def corr(k, r): return np.power(k, -r / k) / gamma(r / k + 1) * r
@@ -3104,8 +3101,8 @@ def _factorialx_wrapper(fname, n, k, exact, extend):
3104
3101
  elif n in {0, 1}:
3105
3102
  return 1 if exact else np.float64(1)
3106
3103
  elif exact and _is_subdtype(type(n), "i"):
3107
- # calculate with integers
3108
- return _range_prod(1, n, k=k)
3104
+ # calculate with integers; cast away other int types (like unsigned)
3105
+ return _range_prod(1, int(n), k=k)
3109
3106
  elif exact:
3110
3107
  # only relevant for factorial
3111
3108
  raise ValueError(msg_exact_not_possible.format(dtype=type(n)))
Binary file
@@ -1,19 +1,18 @@
1
- import math
2
1
  import numpy as np
3
- from scipy._lib._util import _asarray_validated
4
2
  from scipy._lib._array_api import (
5
3
  array_namespace,
4
+ xp_capabilities,
5
+ xp_device,
6
6
  xp_size,
7
- xp_broadcast_promote,
8
- xp_copy,
7
+ xp_promote,
9
8
  xp_float_to_complex,
10
- is_complex,
11
9
  )
12
10
  from scipy._lib import array_api_extra as xpx
13
11
 
14
12
  __all__ = ["logsumexp", "softmax", "log_softmax"]
15
13
 
16
14
 
15
+ @xp_capabilities()
17
16
  def logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False):
18
17
  """Compute the log of the sum of exponentials of input elements.
19
18
 
@@ -61,7 +60,8 @@ def logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False):
61
60
 
62
61
  See Also
63
62
  --------
64
- numpy.logaddexp, numpy.logaddexp2
63
+ :data:`numpy.logaddexp`
64
+ :data:`numpy.logaddexp2`
65
65
 
66
66
  Notes
67
67
  -----
@@ -108,28 +108,45 @@ def logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False):
108
108
 
109
109
  """
110
110
  xp = array_namespace(a, b)
111
- a, b = xp_broadcast_promote(a, b, ensure_writeable=True, force_floating=True, xp=xp)
111
+ a, b = xp_promote(a, b, broadcast=True, force_floating=True, xp=xp)
112
112
  a = xpx.atleast_nd(a, ndim=1, xp=xp)
113
113
  b = xpx.atleast_nd(b, ndim=1, xp=xp) if b is not None else b
114
114
  axis = tuple(range(a.ndim)) if axis is None else axis
115
115
 
116
116
  if xp_size(a) != 0:
117
+ with np.errstate(divide='ignore', invalid='ignore', over='ignore'):
118
+ # Where result is infinite, we use the direct logsumexp calculation to
119
+ # delegate edge case handling to the behavior of `xp.log` and `xp.exp`,
120
+ # which should follow the C99 standard for complex values.
121
+ b_exp_a = xp.exp(a) if b is None else b * xp.exp(a)
122
+ sum_ = xp.sum(b_exp_a, axis=axis, keepdims=True)
123
+ sgn_inf = _sign(sum_, xp=xp) if return_sign else None
124
+ sum_ = xp.abs(sum_) if return_sign else sum_
125
+ out_inf = xp.log(sum_)
126
+
117
127
  with np.errstate(divide='ignore', invalid='ignore'): # log of zero is OK
118
128
  out, sgn = _logsumexp(a, b, axis=axis, return_sign=return_sign, xp=xp)
129
+
130
+ # Replace infinite results. This probably could be done with an
131
+ # `apply_where`-like strategy to avoid redundant calculation, but currently
132
+ # `apply_where` itself is only for elementwise functions.
133
+ out_finite = xp.isfinite(out)
134
+ out = xp.where(out_finite, out, out_inf)
135
+ sgn = xp.where(out_finite, sgn, sgn_inf) if return_sign else sgn
119
136
  else:
120
137
  shape = np.asarray(a.shape) # NumPy is convenient for shape manipulation
121
138
  shape[axis] = 1
122
- out = xp.full(tuple(shape), -xp.inf, dtype=a.dtype)
139
+ out = xp.full(tuple(shape), -xp.inf, dtype=a.dtype, device=xp_device(a))
123
140
  sgn = xp.sign(out)
124
141
 
125
142
  if xp.isdtype(out.dtype, 'complex floating'):
126
143
  if return_sign:
127
144
  real = xp.real(sgn)
128
- imag = xp_float_to_complex(_wrap_radians(xp.imag(sgn), xp))
145
+ imag = xp_float_to_complex(_wrap_radians(xp.imag(sgn), xp=xp), xp=xp)
129
146
  sgn = real + imag*1j
130
147
  else:
131
148
  real = xp.real(out)
132
- imag = xp_float_to_complex(_wrap_radians(xp.imag(out), xp))
149
+ imag = xp_float_to_complex(_wrap_radians(xp.imag(out), xp=xp), xp=xp)
133
150
  out = real + imag*1j
134
151
 
135
152
  # Deal with shape details - reducing dimensions and convert 0-D to scalar for NumPy
@@ -141,17 +158,15 @@ def logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False):
141
158
  return (out, sgn) if return_sign else out
142
159
 
143
160
 
144
- def _wrap_radians(x, xp=None):
145
- xp = array_namespace(x) if xp is None else xp
161
+ def _wrap_radians(x, *, xp):
146
162
  # Wrap radians to (-pi, pi] interval
147
- out = -((-x + math.pi) % (2 * math.pi) - math.pi)
163
+ wrapped = -((-x + xp.pi) % (2 * xp.pi) - xp.pi)
148
164
  # preserve relative precision
149
165
  no_wrap = xp.abs(x) < xp.pi
150
- out[no_wrap] = x[no_wrap]
151
- return out
166
+ return xp.where(no_wrap, x, wrapped)
152
167
 
153
168
 
154
- def _elements_and_indices_with_max_real(a, axis=-1, xp=None):
169
+ def _elements_and_indices_with_max_real(a, *, axis=-1, xp):
155
170
  # This is an array-API compatible `max` function that works something
156
171
  # like `np.max` for complex input. The important part is that it finds
157
172
  # the element with maximum real part. When there are multiple complex values
@@ -160,61 +175,54 @@ def _elements_and_indices_with_max_real(a, axis=-1, xp=None):
160
175
  # `take_along_axis`, and even if it did, we would have problems with axis tuples.
161
176
  # Feel free to rewrite! It's ugly, but it's not the purpose of the PR, and
162
177
  # it gets the job done.
163
- xp = array_namespace(a) if xp is None else xp
164
178
 
165
179
  if xp.isdtype(a.dtype, "complex floating"):
166
180
  # select all elements with max real part.
167
181
  real_a = xp.real(a)
168
- max = xp.max(real_a, axis=axis, keepdims=True)
169
- mask = real_a == max
182
+ max_ = xp.max(real_a, axis=axis, keepdims=True)
183
+ mask = real_a == max_
170
184
 
171
185
  # Of those, choose one arbitrarily. This is a reasonably
172
186
  # simple, array-API compatible way of doing so that doesn't
173
187
  # have a problem with `axis` being a tuple or None.
174
- i = xp.reshape(xp.arange(xp_size(a)), a.shape)
175
- i[~mask] = -1
188
+ i = xp.reshape(xp.arange(xp_size(a), device=xp_device(a)), a.shape)
189
+ i = xpx.at(i, ~mask).set(-1)
176
190
  max_i = xp.max(i, axis=axis, keepdims=True)
177
191
  mask = i == max_i
178
- a = xp_copy(a)
179
- a[~mask] = 0
180
- max = xp.sum(a, axis=axis, dtype=a.dtype, keepdims=True)
192
+ a = xp.where(mask, a, 0.)
193
+ max_ = xp.sum(a, axis=axis, dtype=a.dtype, keepdims=True)
181
194
  else:
182
- max = xp.max(a, axis=axis, keepdims=True)
183
- mask = a == max
184
-
185
- return xp.asarray(max), xp.asarray(mask)
195
+ max_ = xp.max(a, axis=axis, keepdims=True)
196
+ mask = a == max_
186
197
 
198
+ return max_, mask
187
199
 
188
- def _sign(x, xp):
189
- return x / xp.where(x == 0, xp.asarray(1, dtype=x.dtype), xp.abs(x))
190
200
 
201
+ def _sign(x, *, xp):
202
+ return x / xp.where(x == 0, 1., xp.abs(x))
191
203
 
192
- def _logsumexp(a, b, axis, return_sign, xp):
193
204
 
205
+ def _logsumexp(a, b, *, axis, return_sign, xp):
194
206
  # This has been around for about a decade, so let's consider it a feature:
195
207
  # Even if element of `a` is infinite or NaN, it adds nothing to the sum if
196
208
  # the corresponding weight is zero.
197
209
  if b is not None:
198
- a[b == 0] = -xp.inf
210
+ a = xpx.at(a, b == 0).set(-xp.inf, copy=True)
199
211
 
200
212
  # Find element with maximum real part, since this is what affects the magnitude
201
213
  # of the exponential. Possible enhancement: include log of `b` magnitude in `a`.
202
214
  a_max, i_max = _elements_and_indices_with_max_real(a, axis=axis, xp=xp)
203
215
 
204
216
  # for precision, these terms are separated out of the main sum.
205
- a[i_max] = -xp.inf
217
+ a = xpx.at(a, i_max).set(-xp.inf, copy=True if b is None else None)
206
218
  i_max_dt = xp.astype(i_max, a.dtype)
207
219
  # This is an inefficient way of getting `m` because it is the sum of a sparse
208
220
  # array; however, this is the simplest way I can think of to get the right shape.
209
- m = (xp.sum(i_max_dt, axis=axis, keepdims=True, dtype=a.dtype) if b is None
210
- else xp.sum(b * i_max_dt, axis=axis, keepdims=True, dtype=a.dtype))
211
-
212
- # Arithmetic between infinities will introduce NaNs.
213
- # `+ a_max` at the end naturally corrects for removing them here.
214
- shift = xp.where(xp.isfinite(a_max), a_max, xp.asarray(0, dtype=a_max.dtype))
221
+ b_i_max = i_max_dt if b is None else b * i_max_dt
222
+ m = xp.sum(b_i_max, axis=axis, keepdims=True, dtype=a.dtype)
215
223
 
216
224
  # Shift, exponentiate, scale, and sum
217
- exp = b * xp.exp(a - shift) if b is not None else xp.exp(a - shift)
225
+ exp = b * xp.exp(a - a_max) if b is not None else xp.exp(a - a_max)
218
226
  s = xp.sum(exp, axis=axis, keepdims=True, dtype=exp.dtype)
219
227
  s = xp.where(s == 0, s, s/m)
220
228
 
@@ -233,20 +241,20 @@ def _logsumexp(a, b, axis, return_sign, xp):
233
241
  m = xp.abs(m)
234
242
  else:
235
243
  # `a_max` can have a sign component for complex input
236
- sgn = sgn * xp.exp(xp.imag(a_max) * xp.asarray(1.0j, dtype=a_max.dtype))
244
+ sgn = sgn * xp.exp(xp.imag(a_max) * 1.0j)
237
245
 
238
246
  # Take log and undo shift
239
247
  out = xp.log1p(s) + xp.log(m) + a_max
240
248
 
241
249
  if return_sign:
242
- if is_complex(out, xp):
243
- out = xp.real(out)
250
+ out = xp.real(out)
244
251
  elif xp.isdtype(out.dtype, 'real floating'):
245
- out[sgn < 0] = xp.nan
252
+ out = xpx.at(out)[sgn < 0].set(xp.nan)
246
253
 
247
254
  return out, sgn
248
255
 
249
256
 
257
+ @xp_capabilities()
250
258
  def softmax(x, axis=None):
251
259
  r"""Compute the softmax function.
252
260
 
@@ -338,12 +346,14 @@ def softmax(x, axis=None):
338
346
  array([ 1., 1., 1.])
339
347
 
340
348
  """
341
- x = _asarray_validated(x, check_finite=False)
342
- x_max = np.amax(x, axis=axis, keepdims=True)
343
- exp_x_shifted = np.exp(x - x_max)
344
- return exp_x_shifted / np.sum(exp_x_shifted, axis=axis, keepdims=True)
349
+ xp = array_namespace(x)
350
+ x = xp.asarray(x)
351
+ x_max = xp.max(x, axis=axis, keepdims=True)
352
+ exp_x_shifted = xp.exp(x - x_max)
353
+ return exp_x_shifted / xp.sum(exp_x_shifted, axis=axis, keepdims=True)
345
354
 
346
355
 
356
+ @xp_capabilities()
347
357
  def log_softmax(x, axis=None):
348
358
  r"""Compute the logarithm of the softmax function.
349
359
 
@@ -395,23 +405,22 @@ def log_softmax(x, axis=None):
395
405
  array([ 0., -inf])
396
406
 
397
407
  """
408
+ xp = array_namespace(x)
409
+ x = xp.asarray(x)
398
410
 
399
- x = _asarray_validated(x, check_finite=False)
400
-
401
- x_max = np.amax(x, axis=axis, keepdims=True)
411
+ x_max = xp.max(x, axis=axis, keepdims=True)
402
412
 
403
413
  if x_max.ndim > 0:
404
- x_max[~np.isfinite(x_max)] = 0
405
- elif not np.isfinite(x_max):
414
+ x_max = xpx.at(x_max, ~xp.isfinite(x_max)).set(0)
415
+ elif not xp.isfinite(x_max):
406
416
  x_max = 0
407
417
 
408
418
  tmp = x - x_max
409
- exp_tmp = np.exp(tmp)
419
+ exp_tmp = xp.exp(tmp)
410
420
 
411
421
  # suppress warnings about log of zero
412
422
  with np.errstate(divide='ignore'):
413
- s = np.sum(exp_tmp, axis=axis, keepdims=True)
414
- out = np.log(s)
423
+ s = xp.sum(exp_tmp, axis=axis, keepdims=True)
424
+ out = xp.log(s)
415
425
 
416
- out = tmp - out
417
- return out
426
+ return tmp - out
@@ -1,10 +1,10 @@
1
1
  from typing import (
2
2
  Any,
3
- Callable,
4
3
  Literal,
5
4
  Optional,
6
5
  overload,
7
6
  )
7
+ from collections.abc import Callable
8
8
 
9
9
  import numpy as np
10
10
 
@@ -1,5 +1,5 @@
1
1
  from functools import wraps
2
- from scipy._lib._util import _lazywhere
2
+ import scipy._lib.array_api_extra as xpx
3
3
  import numpy as np
4
4
  from ._ufuncs import (_spherical_jn, _spherical_yn, _spherical_in,
5
5
  _spherical_kn, _spherical_jn_d, _spherical_yn_d,
@@ -28,9 +28,9 @@ def use_reflection(sign_n_even=None, reflection_fun=None):
28
28
  return fun(n, z, derivative) # complex dtype just works
29
29
 
30
30
  f2 = standard_reflection if reflection_fun is None else reflection_fun
31
- return _lazywhere(z.real >= 0, (n, z),
32
- f=lambda n, z: fun(n, z, derivative),
33
- f2=lambda n, z: f2(n, z, derivative))[()]
31
+ return xpx.apply_where(z.real >= 0, (n, z),
32
+ lambda n, z: fun(n, z, derivative),
33
+ lambda n, z: f2(n, z, derivative))[()]
34
34
  return wrapper
35
35
  return decorator
36
36