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
@@ -1,91 +1,182 @@
1
- import os
2
- import sys
3
1
  import functools
2
+ import operator
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass
5
+ from types import ModuleType
4
6
 
5
7
  import numpy as np
6
8
  from scipy._lib._array_api import (
7
- array_namespace, scipy_namespace_for, is_numpy
9
+ array_namespace, scipy_namespace_for, is_numpy, is_dask, is_marray,
10
+ xp_promote, xp_capabilities, SCIPY_ARRAY_API
8
11
  )
12
+ import scipy._lib.array_api_extra as xpx
9
13
  from . import _ufuncs
10
- # These don't really need to be imported, but otherwise IDEs might not realize
11
- # that these are defined in this file / report an error in __init__.py
12
- from ._ufuncs import (
13
- log_ndtr, ndtr, ndtri, erf, erfc, i0, i0e, i1, i1e, gammaln, # noqa: F401
14
- gammainc, gammaincc, logit, expit, entr, rel_entr, xlogy, # noqa: F401
15
- chdtr, chdtrc, betainc, betaincc, stdtr # noqa: F401
16
- )
17
-
18
- _SCIPY_ARRAY_API = os.environ.get("SCIPY_ARRAY_API", False)
19
- array_api_compat_prefix = "scipy._lib.array_api_compat"
20
14
 
21
15
 
22
- def get_array_special_func(f_name, xp, n_array_args):
23
- spx = scipy_namespace_for(xp)
24
- f = None
25
- if is_numpy(xp):
26
- f = getattr(_ufuncs, f_name, None)
27
- elif spx is not None:
28
- f = getattr(spx.special, f_name, None)
16
+ @dataclass
17
+ class _FuncInfo:
18
+ # NumPy-only function. IT MUST BE ELEMENTWISE.
19
+ func: Callable
20
+ # Number of arguments, not counting out=
21
+ # This is for testing purposes only, due to the fact that
22
+ # inspect.signature() just returns *args for ufuncs.
23
+ n_args: int
24
+ # @xp_capabilities decorator, for the purpose of
25
+ # documentation and unit testing. Omit to indicate
26
+ # full support for all backends.
27
+ xp_capabilities: Callable[[Callable], Callable] | None = None
28
+ # Generic implementation to fall back on if there is no native dispatch
29
+ # available. This is a function that accepts (main namespace, scipy namespace)
30
+ # and returns the final callable, or None if not available.
31
+ generic_impl: Callable[
32
+ [ModuleType, ModuleType | None], Callable | None
33
+ ] | None = None
34
+
35
+ @property
36
+ def name(self):
37
+ return self.func.__name__
38
+
39
+ # These are needed by @lru_cache below
40
+ def __hash__(self):
41
+ return hash(self.func)
42
+
43
+ def __eq__(self, other):
44
+ return isinstance(other, _FuncInfo) and self.func == other.func
45
+
46
+ @property
47
+ def wrapper(self):
48
+ if self.name in globals():
49
+ # Already initialised. We are likely in a unit test.
50
+ # Return function potentially overridden by xpx.testing.lazy_xp_function.
51
+ import scipy.special
52
+ return getattr(scipy.special, self.name)
53
+
54
+ if SCIPY_ARRAY_API:
55
+ @functools.wraps(self.func)
56
+ def wrapped(*args, **kwargs):
57
+ xp = array_namespace(*args)
58
+ return self._wrapper_for(xp)(*args, **kwargs)
59
+
60
+ # Allow pickling the function. Normally this is done by @wraps,
61
+ # but in this case it doesn't work because self.func is a ufunc.
62
+ wrapped.__module__ = "scipy.special"
63
+ wrapped.__qualname__ = self.name
64
+ func = wrapped
65
+ else:
66
+ func = self.func
67
+
68
+ capabilities = self.xp_capabilities or xp_capabilities()
69
+ # In order to retain a naked ufunc when SCIPY_ARRAY_API is
70
+ # disabled, xp_capabilities must apply its changes in place.
71
+ cap_func = capabilities(func)
72
+ assert cap_func is func
73
+ return func
74
+
75
+ @functools.lru_cache(1000)
76
+ def _wrapper_for(self, xp):
77
+ if is_numpy(xp):
78
+ return self.func
79
+
80
+ # If a native implementation is available, use that
81
+ spx = scipy_namespace_for(xp)
82
+ f = _get_native_func(xp, spx, self.name)
83
+ if f is not None:
84
+ return f
85
+
86
+ # If generic Array API implementation is available, use that
87
+ if self.generic_impl is not None:
88
+ f = self.generic_impl(xp, spx)
89
+ if f is not None:
90
+ return f
91
+
92
+ if is_marray(xp):
93
+ # Unwrap the array, apply the function on the wrapped namespace,
94
+ # and then re-wrap it.
95
+ # IMPORTANT: this only works because all functions in this module
96
+ # are elementwise. Otherwise, we would not be able to define a
97
+ # general rule for mask propagation.
98
+
99
+ _f = globals()[self.name] # Allow nested wrapping
100
+ def f(*args, _f=_f, xp=xp, **kwargs):
101
+ data_args = [arg.data for arg in args]
102
+ out = _f(*data_args, **kwargs)
103
+ mask = functools.reduce(operator.or_, (arg.mask for arg in args))
104
+ return xp.asarray(out, mask=mask)
105
+
106
+ return f
107
+
108
+ if is_dask(xp):
109
+ # Apply the function to each block of the Dask array.
110
+ # IMPORTANT: map_blocks works only because all functions in this module
111
+ # are elementwise. It would be a grave mistake to apply this to gufuncs
112
+ # or any other function with reductions, as they would change their
113
+ # output depending on chunking!
114
+
115
+ _f = globals()[self.name] # Allow nested wrapping
116
+ def f(*args, _f=_f, xp=xp, **kwargs):
117
+ # Hide dtype kwarg from map_blocks
118
+ return xp.map_blocks(functools.partial(_f, **kwargs), *args)
119
+
120
+ return f
121
+
122
+ # As a final resort, use the NumPy/SciPy implementation
123
+ _f = self.func
124
+ def f(*args, _f=_f, xp=xp, **kwargs):
125
+ # TODO use xpx.lazy_apply to add jax.jit support
126
+ # (but dtype propagation can be non-trivial)
127
+ args = [np.asarray(arg) for arg in args]
128
+ out = _f(*args, **kwargs)
129
+ return xp.asarray(out)
29
130
 
30
- if f is not None:
31
131
  return f
32
132
 
33
- # if generic array-API implementation is available, use that;
34
- # otherwise, fall back to NumPy/SciPy
35
- if f_name in _generic_implementations:
36
- _f = _generic_implementations[f_name](xp=xp, spx=spx)
37
- if _f is not None:
38
- return _f
39
-
40
- _f = getattr(_ufuncs, f_name, None)
41
- def __f(*args, _f=_f, _xp=xp, **kwargs):
42
- array_args = args[:n_array_args]
43
- other_args = args[n_array_args:]
44
- array_args = [np.asarray(arg) for arg in array_args]
45
- out = _f(*array_args, *other_args, **kwargs)
46
- return _xp.asarray(out)
47
133
 
48
- return __f
49
-
50
-
51
- def _get_shape_dtype(*args, xp):
52
- args = xp.broadcast_arrays(*args)
53
- shape = args[0].shape
54
- dtype = xp.result_type(*args)
55
- if xp.isdtype(dtype, 'integral'):
56
- dtype = xp.float64
57
- args = [xp.asarray(arg, dtype=dtype) for arg in args]
58
- return args, shape, dtype
134
+ def _get_native_func(xp, spx, f_name):
135
+ f = getattr(spx.special, f_name, None) if spx else None
136
+ if f is None and hasattr(xp, 'special'):
137
+ # Currently dead branch, in anticipation of 'special' Array API extension
138
+ # https://github.com/data-apis/array-api/issues/725
139
+ f = getattr(xp.special, f_name, None)
140
+ return f
59
141
 
60
142
 
61
143
  def _rel_entr(xp, spx):
62
144
  def __rel_entr(x, y, *, xp=xp):
63
- args, shape, dtype = _get_shape_dtype(x, y, xp=xp)
64
- x, y = args
65
- res = xp.full(x.shape, xp.inf, dtype=dtype)
66
- res[(x == 0) & (y >= 0)] = xp.asarray(0, dtype=dtype)
67
- i = (x > 0) & (y > 0)
68
- res[i] = x[i] * (xp.log(x[i]) - xp.log(y[i]))
145
+ # https://github.com/data-apis/array-api-extra/issues/160
146
+ mxp = array_namespace(x._meta, y._meta) if is_dask(xp) else xp
147
+ x, y = xp_promote(x, y, broadcast=True, force_floating=True, xp=xp)
148
+ xy_pos = (x > 0) & (y > 0)
149
+ xy_inf = xp.isinf(x) & xp.isinf(y)
150
+ res = xpx.apply_where(
151
+ xy_pos & ~xy_inf,
152
+ (x, y),
153
+ # Note: for very large x, this can overflow.
154
+ lambda x, y: x * (mxp.log(x) - mxp.log(y)),
155
+ fill_value=xp.inf
156
+ )
157
+ res = xpx.at(res)[(x == 0) & (y >= 0)].set(0)
158
+ res = xpx.at(res)[xp.isnan(x) | xp.isnan(y) | (xy_pos & xy_inf)].set(xp.nan)
69
159
  return res
160
+
70
161
  return __rel_entr
71
162
 
72
163
 
73
164
  def _xlogy(xp, spx):
74
165
  def __xlogy(x, y, *, xp=xp):
166
+ x, y = xp_promote(x, y, force_floating=True, xp=xp)
75
167
  with np.errstate(divide='ignore', invalid='ignore'):
76
168
  temp = x * xp.log(y)
77
- return xp.where(x == 0., xp.asarray(0., dtype=temp.dtype), temp)
169
+ return xp.where(x == 0., 0., temp)
78
170
  return __xlogy
79
171
 
80
172
 
173
+
81
174
  def _chdtr(xp, spx):
82
175
  # The difference between this and just using `gammainc`
83
176
  # defined by `get_array_special_func` is that if `gammainc`
84
177
  # isn't found, we don't want to use the SciPy version; we'll
85
178
  # return None here and use the SciPy version of `chdtr`.
86
- gammainc = getattr(spx.special, 'gammainc', None) if spx else None # noqa: F811
87
- if gammainc is None and hasattr(xp, 'special'):
88
- gammainc = getattr(xp.special, 'gammainc', None)
179
+ gammainc = _get_native_func(xp, spx, 'gammainc')
89
180
  if gammainc is None:
90
181
  return None
91
182
 
@@ -104,9 +195,7 @@ def _chdtrc(xp, spx):
104
195
  # defined by `get_array_special_func` is that if `gammaincc`
105
196
  # isn't found, we don't want to use the SciPy version; we'll
106
197
  # return None here and use the SciPy version of `chdtrc`.
107
- gammaincc = getattr(spx.special, 'gammaincc', None) if spx else None # noqa: F811
108
- if gammaincc is None and hasattr(xp, 'special'):
109
- gammaincc = getattr(xp.special, 'gammaincc', None)
198
+ gammaincc = _get_native_func(xp, spx, 'gammaincc')
110
199
  if gammaincc is None:
111
200
  return None
112
201
 
@@ -119,9 +208,7 @@ def _chdtrc(xp, spx):
119
208
 
120
209
 
121
210
  def _betaincc(xp, spx):
122
- betainc = getattr(spx.special, 'betainc', None) if spx else None # noqa: F811
123
- if betainc is None and hasattr(xp, 'special'):
124
- betainc = getattr(xp.special, 'betainc', None)
211
+ betainc = _get_native_func(xp, spx, 'betainc')
125
212
  if betainc is None:
126
213
  return None
127
214
 
@@ -132,9 +219,7 @@ def _betaincc(xp, spx):
132
219
 
133
220
 
134
221
  def _stdtr(xp, spx):
135
- betainc = getattr(spx.special, 'betainc', None) if spx else None # noqa: F811
136
- if betainc is None and hasattr(xp, 'special'):
137
- betainc = getattr(xp.special, 'betainc', None)
222
+ betainc = _get_native_func(xp, spx, 'betainc')
138
223
  if betainc is None:
139
224
  return None
140
225
 
@@ -146,57 +231,65 @@ def _stdtr(xp, spx):
146
231
  return __stdtr
147
232
 
148
233
 
149
- _generic_implementations = {'rel_entr': _rel_entr,
150
- 'xlogy': _xlogy,
151
- 'chdtr': _chdtr,
152
- 'chdtrc': _chdtrc,
153
- 'betaincc': _betaincc,
154
- 'stdtr': _stdtr,
155
- }
156
-
157
-
158
- # functools.wraps doesn't work because:
159
- # 'numpy.ufunc' object has no attribute '__module__'
160
- def support_alternative_backends(f_name, n_array_args):
161
- func = getattr(_ufuncs, f_name)
162
-
163
- @functools.wraps(func)
164
- def wrapped(*args, **kwargs):
165
- xp = array_namespace(*args[:n_array_args])
166
- f = get_array_special_func(f_name, xp, n_array_args)
167
- return f(*args, **kwargs)
168
-
169
- return wrapped
170
-
171
-
172
- array_special_func_map = {
173
- 'log_ndtr': 1,
174
- 'ndtr': 1,
175
- 'ndtri': 1,
176
- 'erf': 1,
177
- 'erfc': 1,
178
- 'i0': 1,
179
- 'i0e': 1,
180
- 'i1': 1,
181
- 'i1e': 1,
182
- 'gammaln': 1,
183
- 'gammainc': 2,
184
- 'gammaincc': 2,
185
- 'logit': 1,
186
- 'expit': 1,
187
- 'entr': 1,
188
- 'rel_entr': 2,
189
- 'xlogy': 2,
190
- 'chdtr': 2,
191
- 'chdtrc': 2,
192
- 'betainc': 3,
193
- 'betaincc': 3,
194
- 'stdtr': 2,
195
- }
196
-
197
- for f_name, n_array_args in array_special_func_map.items():
198
- f = (support_alternative_backends(f_name, n_array_args) if _SCIPY_ARRAY_API
199
- else getattr(_ufuncs, f_name))
200
- sys.modules[__name__].__dict__[f_name] = f
201
-
202
- __all__ = list(array_special_func_map)
234
+ def _stdtrit(xp, spx):
235
+ # Need either native stdtr or native betainc
236
+ stdtr = _get_native_func(xp, spx, 'stdtr') or _stdtr(xp, spx)
237
+ # If betainc is not defined, the root-finding would be done with `xp`
238
+ # despite `stdtr` being evaluated with SciPy/NumPy `stdtr`. Save the
239
+ # conversions: in this case, just evaluate `stdtrit` with SciPy/NumPy.
240
+ if stdtr is None:
241
+ return None
242
+
243
+ from scipy.optimize.elementwise import bracket_root, find_root
244
+
245
+ def __stdtrit(df, p):
246
+ def fun(t, df, p): return stdtr(df, t) - p
247
+ res_bracket = bracket_root(fun, xp.zeros_like(p), args=(df, p))
248
+ res_root = find_root(fun, res_bracket.bracket, args=(df, p))
249
+ return res_root.x
250
+
251
+ return __stdtrit
252
+
253
+
254
+ # Inventory of automatically dispatched functions
255
+ # IMPORTANT: these must all be **elementwise** functions!
256
+
257
+ # PyTorch doesn't implement `betainc`.
258
+ # On torch CPU we can fall back to NumPy, but on GPU it won't work.
259
+ _needs_betainc = xp_capabilities(cpu_only=True, exceptions=['jax.numpy', 'cupy'])
260
+
261
+ _special_funcs = (
262
+ _FuncInfo(_ufuncs.betainc, 3, _needs_betainc),
263
+ _FuncInfo(_ufuncs.betaincc, 3, _needs_betainc, generic_impl=_betaincc),
264
+ _FuncInfo(_ufuncs.chdtr, 2, generic_impl=_chdtr),
265
+ _FuncInfo(_ufuncs.chdtrc, 2, generic_impl=_chdtrc),
266
+ _FuncInfo(_ufuncs.erf, 1),
267
+ _FuncInfo(_ufuncs.erfc, 1),
268
+ _FuncInfo(_ufuncs.entr, 1),
269
+ _FuncInfo(_ufuncs.expit, 1),
270
+ _FuncInfo(_ufuncs.i0, 1),
271
+ _FuncInfo(_ufuncs.i0e, 1),
272
+ _FuncInfo(_ufuncs.i1, 1),
273
+ _FuncInfo(_ufuncs.i1e, 1),
274
+ _FuncInfo(_ufuncs.log_ndtr, 1),
275
+ _FuncInfo(_ufuncs.logit, 1),
276
+ _FuncInfo(_ufuncs.gammaln, 1),
277
+ _FuncInfo(_ufuncs.gammainc, 2),
278
+ _FuncInfo(_ufuncs.gammaincc, 2),
279
+ _FuncInfo(_ufuncs.ndtr, 1),
280
+ _FuncInfo(_ufuncs.ndtri, 1),
281
+ _FuncInfo(_ufuncs.rel_entr, 2, generic_impl=_rel_entr),
282
+ _FuncInfo(_ufuncs.stdtr, 2, _needs_betainc, generic_impl=_stdtr),
283
+ _FuncInfo(_ufuncs.stdtrit, 2,
284
+ xp_capabilities(
285
+ cpu_only=True, exceptions=['cupy'], # needs betainc
286
+ skip_backends=[("jax.numpy", "no scipy.optimize support")]),
287
+ generic_impl=_stdtrit),
288
+ _FuncInfo(_ufuncs.xlogy, 2, generic_impl=_xlogy),
289
+ )
290
+
291
+ # Override ufuncs.
292
+ # When SCIPY_ARRAY_API is disabled, this exclusively updates the docstrings in place
293
+ # and populates the xp_capabilities table, while retaining the original ufuncs.
294
+ globals().update({nfo.func.__name__: nfo.wrapper for nfo in _special_funcs})
295
+ __all__ = [nfo.func.__name__ for nfo in _special_funcs]
@@ -294,13 +294,13 @@ class FuncData:
294
294
  msg = [""]
295
295
  msg.append(f"Max |adiff|: {diff[bad_j].max():g}")
296
296
  msg.append(f"Max |rdiff|: {rdiff[bad_j].max():g}")
297
- msg.append("Bad results (%d out of %d) for the following points "
298
- "(in output %d):"
299
- % (np.sum(bad_j), point_count, output_num,))
297
+ msg.append(f"Bad results ({np.sum(bad_j)} out of "
298
+ f"{point_count}) for the following points "
299
+ f"(in output {output_num}):")
300
300
  for j in np.nonzero(bad_j)[0]:
301
301
  j = int(j)
302
302
  def fmt(x):
303
- return '%30s' % np.array2string(x[j], precision=18)
303
+ return f'{np.array2string(x[j], precision=18):30s}'
304
304
  a = " ".join(map(fmt, params))
305
305
  b = " ".join(map(fmt, got))
306
306
  c = " ".join(map(fmt, wanted))
scipy/special/_ufuncs.pyi CHANGED
@@ -265,6 +265,7 @@ _kolmogp: np.ufunc
265
265
  _lambertw: np.ufunc
266
266
  _lanczos_sum_expg_scaled: np.ufunc
267
267
  _lgam1p: np.ufunc
268
+ _log1mexp: np.ufunc
268
269
  _log1pmx: np.ufunc
269
270
  _riemann_zeta: np.ufunc
270
271
  _scaled_exp1: np.ufunc