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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (608) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313-darwin.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-313-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_deprecation_call.cpython-313-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-313-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-313-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-313-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-313-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-313-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-313-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-313-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-313-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_quad_vec.py +21 -29
  128. scipy/integrate/_quadpack_py.py +11 -7
  129. scipy/integrate/_quadrature.py +3 -3
  130. scipy/integrate/_rules/_base.py +2 -2
  131. scipy/integrate/_tanhsinh.py +48 -47
  132. scipy/integrate/_test_odeint_banded.cpython-313-darwin.so +0 -0
  133. scipy/integrate/_vode.cpython-313-darwin.so +0 -0
  134. scipy/integrate/tests/test__quad_vec.py +0 -6
  135. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  136. scipy/integrate/tests/test_cubature.py +21 -35
  137. scipy/integrate/tests/test_quadrature.py +6 -8
  138. scipy/integrate/tests/test_tanhsinh.py +56 -48
  139. scipy/interpolate/__init__.py +70 -58
  140. scipy/interpolate/_bary_rational.py +22 -22
  141. scipy/interpolate/_bsplines.py +119 -66
  142. scipy/interpolate/_cubic.py +65 -50
  143. scipy/interpolate/_dfitpack.cpython-313-darwin.so +0 -0
  144. scipy/interpolate/_dierckx.cpython-313-darwin.so +0 -0
  145. scipy/interpolate/_fitpack2.py +9 -6
  146. scipy/interpolate/_fitpack_impl.py +32 -26
  147. scipy/interpolate/_fitpack_repro.py +23 -19
  148. scipy/interpolate/_interpnd.cpython-313-darwin.so +0 -0
  149. scipy/interpolate/_interpolate.py +30 -12
  150. scipy/interpolate/_ndbspline.py +13 -18
  151. scipy/interpolate/_ndgriddata.py +5 -8
  152. scipy/interpolate/_polyint.py +95 -31
  153. scipy/interpolate/_ppoly.cpython-313-darwin.so +0 -0
  154. scipy/interpolate/_rbf.py +2 -2
  155. scipy/interpolate/_rbfinterp.py +1 -1
  156. scipy/interpolate/_rgi.py +31 -26
  157. scipy/interpolate/_rgi_cython.cpython-313-darwin.so +0 -0
  158. scipy/interpolate/dfitpack.py +0 -20
  159. scipy/interpolate/interpnd.py +1 -2
  160. scipy/interpolate/tests/test_bary_rational.py +2 -2
  161. scipy/interpolate/tests/test_bsplines.py +97 -1
  162. scipy/interpolate/tests/test_fitpack2.py +39 -1
  163. scipy/interpolate/tests/test_interpnd.py +32 -20
  164. scipy/interpolate/tests/test_interpolate.py +48 -4
  165. scipy/interpolate/tests/test_rgi.py +2 -1
  166. scipy/io/_fast_matrix_market/__init__.py +2 -0
  167. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  168. scipy/io/_harwell_boeing/hb.py +7 -11
  169. scipy/io/_idl.py +5 -7
  170. scipy/io/_netcdf.py +15 -5
  171. scipy/io/_test_fortran.cpython-313-darwin.so +0 -0
  172. scipy/io/arff/tests/test_arffread.py +3 -3
  173. scipy/io/matlab/__init__.py +5 -3
  174. scipy/io/matlab/_mio.py +4 -1
  175. scipy/io/matlab/_mio5.py +19 -13
  176. scipy/io/matlab/_mio5_utils.cpython-313-darwin.so +0 -0
  177. scipy/io/matlab/_mio_utils.cpython-313-darwin.so +0 -0
  178. scipy/io/matlab/_miobase.py +4 -1
  179. scipy/io/matlab/_streams.cpython-313-darwin.so +0 -0
  180. scipy/io/matlab/tests/test_mio.py +46 -18
  181. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  182. scipy/io/tests/test_mmio.py +7 -1
  183. scipy/io/tests/test_wavfile.py +41 -0
  184. scipy/io/wavfile.py +57 -10
  185. scipy/linalg/_basic.py +113 -86
  186. scipy/linalg/_cythonized_array_utils.cpython-313-darwin.so +0 -0
  187. scipy/linalg/_decomp.py +22 -9
  188. scipy/linalg/_decomp_cholesky.py +28 -13
  189. scipy/linalg/_decomp_cossin.py +45 -30
  190. scipy/linalg/_decomp_interpolative.cpython-313-darwin.so +0 -0
  191. scipy/linalg/_decomp_ldl.py +4 -1
  192. scipy/linalg/_decomp_lu.py +18 -6
  193. scipy/linalg/_decomp_lu_cython.cpython-313-darwin.so +0 -0
  194. scipy/linalg/_decomp_polar.py +2 -0
  195. scipy/linalg/_decomp_qr.py +6 -2
  196. scipy/linalg/_decomp_qz.py +3 -0
  197. scipy/linalg/_decomp_schur.py +3 -1
  198. scipy/linalg/_decomp_svd.py +13 -2
  199. scipy/linalg/_decomp_update.cpython-313-darwin.so +0 -0
  200. scipy/linalg/_expm_frechet.py +4 -0
  201. scipy/linalg/_fblas.cpython-313-darwin.so +0 -0
  202. scipy/linalg/_flapack.cpython-313-darwin.so +0 -0
  203. scipy/linalg/_matfuncs.py +187 -4
  204. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-darwin.so +0 -0
  205. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  206. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-darwin.so +0 -0
  207. scipy/linalg/_procrustes.py +2 -0
  208. scipy/linalg/_sketches.py +17 -6
  209. scipy/linalg/_solve_toeplitz.cpython-313-darwin.so +0 -0
  210. scipy/linalg/_solvers.py +7 -2
  211. scipy/linalg/_special_matrices.py +26 -36
  212. scipy/linalg/cython_blas.cpython-313-darwin.so +0 -0
  213. scipy/linalg/cython_lapack.cpython-313-darwin.so +0 -0
  214. scipy/linalg/lapack.py +22 -2
  215. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  216. scipy/linalg/tests/test_basic.py +31 -16
  217. scipy/linalg/tests/test_batch.py +588 -0
  218. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  219. scipy/linalg/tests/test_decomp.py +40 -3
  220. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  221. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  222. scipy/linalg/tests/test_lapack.py +115 -7
  223. scipy/linalg/tests/test_matfuncs.py +157 -102
  224. scipy/linalg/tests/test_procrustes.py +0 -7
  225. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  226. scipy/linalg/tests/test_special_matrices.py +1 -5
  227. scipy/ndimage/__init__.py +1 -0
  228. scipy/ndimage/_cytest.cpython-313-darwin.so +0 -0
  229. scipy/ndimage/_delegators.py +8 -2
  230. scipy/ndimage/_filters.py +433 -5
  231. scipy/ndimage/_interpolation.py +36 -6
  232. scipy/ndimage/_measurements.py +4 -2
  233. scipy/ndimage/_morphology.py +5 -0
  234. scipy/ndimage/_nd_image.cpython-313-darwin.so +0 -0
  235. scipy/ndimage/_ni_docstrings.py +5 -1
  236. scipy/ndimage/_ni_label.cpython-313-darwin.so +0 -0
  237. scipy/ndimage/_ni_support.py +1 -5
  238. scipy/ndimage/_support_alternative_backends.py +18 -6
  239. scipy/ndimage/tests/test_filters.py +337 -259
  240. scipy/ndimage/tests/test_fourier.py +7 -9
  241. scipy/ndimage/tests/test_interpolation.py +68 -61
  242. scipy/ndimage/tests/test_measurements.py +18 -35
  243. scipy/ndimage/tests/test_morphology.py +143 -131
  244. scipy/ndimage/tests/test_splines.py +1 -3
  245. scipy/optimize/_basinhopping.py +13 -7
  246. scipy/optimize/_bglu_dense.cpython-313-darwin.so +0 -0
  247. scipy/optimize/_bracket.py +17 -24
  248. scipy/optimize/_chandrupatla.py +9 -10
  249. scipy/optimize/_cobyla_py.py +104 -123
  250. scipy/optimize/_constraints.py +14 -10
  251. scipy/optimize/_differentiable_functions.py +371 -230
  252. scipy/optimize/_differentialevolution.py +4 -3
  253. scipy/optimize/_dual_annealing.py +1 -1
  254. scipy/optimize/_elementwise.py +1 -4
  255. scipy/optimize/_lbfgsb_py.py +57 -16
  256. scipy/optimize/_linprog_doc.py +2 -2
  257. scipy/optimize/_linprog_highs.py +2 -2
  258. scipy/optimize/_linprog_ip.py +25 -10
  259. scipy/optimize/_linprog_util.py +14 -16
  260. scipy/optimize/_lsq/common.py +3 -3
  261. scipy/optimize/_lsq/dogbox.py +16 -2
  262. scipy/optimize/_lsq/givens_elimination.cpython-313-darwin.so +0 -0
  263. scipy/optimize/_lsq/least_squares.py +198 -126
  264. scipy/optimize/_lsq/lsq_linear.py +6 -6
  265. scipy/optimize/_lsq/trf.py +35 -8
  266. scipy/optimize/_milp.py +3 -1
  267. scipy/optimize/_minimize.py +105 -36
  268. scipy/optimize/_minpack_py.py +21 -14
  269. scipy/optimize/_moduleTNC.cpython-313-darwin.so +0 -0
  270. scipy/optimize/_nnls.py +20 -21
  271. scipy/optimize/_nonlin.py +34 -3
  272. scipy/optimize/_numdiff.py +288 -110
  273. scipy/optimize/_optimize.py +86 -48
  274. scipy/optimize/_remove_redundancy.py +5 -5
  275. scipy/optimize/_root_scalar.py +1 -1
  276. scipy/optimize/_shgo.py +6 -0
  277. scipy/optimize/_shgo_lib/_complex.py +1 -1
  278. scipy/optimize/_slsqp_py.py +216 -124
  279. scipy/optimize/_slsqplib.cpython-313-darwin.so +0 -0
  280. scipy/optimize/_spectral.py +1 -1
  281. scipy/optimize/_tnc.py +8 -1
  282. scipy/optimize/_trlib/_trlib.cpython-313-darwin.so +0 -0
  283. scipy/optimize/_trustregion.py +20 -6
  284. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  285. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  286. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  287. scipy/optimize/_trustregion_constr/projections.py +12 -8
  288. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  289. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  290. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  291. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  292. scipy/optimize/_trustregion_exact.py +0 -1
  293. scipy/optimize/_zeros.cpython-313-darwin.so +0 -0
  294. scipy/optimize/_zeros_py.py +97 -17
  295. scipy/optimize/cython_optimize/_zeros.cpython-313-darwin.so +0 -0
  296. scipy/optimize/slsqp.py +0 -1
  297. scipy/optimize/tests/test__basinhopping.py +1 -1
  298. scipy/optimize/tests/test__differential_evolution.py +4 -4
  299. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  300. scipy/optimize/tests/test__numdiff.py +66 -22
  301. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  302. scipy/optimize/tests/test__shgo.py +9 -1
  303. scipy/optimize/tests/test_bracket.py +36 -46
  304. scipy/optimize/tests/test_chandrupatla.py +133 -135
  305. scipy/optimize/tests/test_cobyla.py +74 -45
  306. scipy/optimize/tests/test_constraints.py +1 -1
  307. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  308. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  309. scipy/optimize/tests/test_least_squares.py +125 -13
  310. scipy/optimize/tests/test_linear_assignment.py +3 -3
  311. scipy/optimize/tests/test_linprog.py +3 -3
  312. scipy/optimize/tests/test_lsq_linear.py +5 -5
  313. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  314. scipy/optimize/tests/test_minpack.py +4 -4
  315. scipy/optimize/tests/test_nnls.py +43 -3
  316. scipy/optimize/tests/test_nonlin.py +36 -0
  317. scipy/optimize/tests/test_optimize.py +95 -17
  318. scipy/optimize/tests/test_slsqp.py +36 -4
  319. scipy/optimize/tests/test_zeros.py +34 -1
  320. scipy/signal/__init__.py +12 -23
  321. scipy/signal/_delegators.py +568 -0
  322. scipy/signal/_filter_design.py +459 -241
  323. scipy/signal/_fir_filter_design.py +262 -90
  324. scipy/signal/_lti_conversion.py +3 -2
  325. scipy/signal/_ltisys.py +118 -91
  326. scipy/signal/_peak_finding_utils.cpython-313-darwin.so +0 -0
  327. scipy/signal/_polyutils.py +172 -0
  328. scipy/signal/_short_time_fft.py +519 -70
  329. scipy/signal/_signal_api.py +30 -0
  330. scipy/signal/_signaltools.py +719 -399
  331. scipy/signal/_sigtools.cpython-313-darwin.so +0 -0
  332. scipy/signal/_sosfilt.cpython-313-darwin.so +0 -0
  333. scipy/signal/_spectral_py.py +221 -50
  334. scipy/signal/_spline_filters.py +108 -68
  335. scipy/signal/_support_alternative_backends.py +73 -0
  336. scipy/signal/_upfirdn.py +4 -1
  337. scipy/signal/_upfirdn_apply.cpython-313-darwin.so +0 -0
  338. scipy/signal/_waveforms.py +2 -11
  339. scipy/signal/_wavelets.py +1 -1
  340. scipy/signal/fir_filter_design.py +1 -0
  341. scipy/signal/spline.py +4 -11
  342. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  343. scipy/signal/tests/test_bsplines.py +114 -79
  344. scipy/signal/tests/test_cont2discrete.py +9 -2
  345. scipy/signal/tests/test_filter_design.py +721 -481
  346. scipy/signal/tests/test_fir_filter_design.py +332 -140
  347. scipy/signal/tests/test_savitzky_golay.py +4 -3
  348. scipy/signal/tests/test_short_time_fft.py +221 -3
  349. scipy/signal/tests/test_signaltools.py +2144 -1348
  350. scipy/signal/tests/test_spectral.py +19 -6
  351. scipy/signal/tests/test_splines.py +161 -96
  352. scipy/signal/tests/test_upfirdn.py +84 -50
  353. scipy/signal/tests/test_waveforms.py +20 -0
  354. scipy/signal/tests/test_windows.py +607 -466
  355. scipy/signal/windows/_windows.py +287 -148
  356. scipy/sparse/__init__.py +23 -4
  357. scipy/sparse/_base.py +270 -108
  358. scipy/sparse/_bsr.py +7 -4
  359. scipy/sparse/_compressed.py +59 -231
  360. scipy/sparse/_construct.py +90 -38
  361. scipy/sparse/_coo.py +115 -181
  362. scipy/sparse/_csc.py +4 -4
  363. scipy/sparse/_csparsetools.cpython-313-darwin.so +0 -0
  364. scipy/sparse/_csr.py +2 -2
  365. scipy/sparse/_data.py +48 -48
  366. scipy/sparse/_dia.py +105 -18
  367. scipy/sparse/_dok.py +0 -23
  368. scipy/sparse/_index.py +4 -4
  369. scipy/sparse/_matrix.py +23 -0
  370. scipy/sparse/_sparsetools.cpython-313-darwin.so +0 -0
  371. scipy/sparse/_sputils.py +37 -22
  372. scipy/sparse/base.py +0 -9
  373. scipy/sparse/bsr.py +0 -14
  374. scipy/sparse/compressed.py +0 -23
  375. scipy/sparse/construct.py +0 -6
  376. scipy/sparse/coo.py +0 -14
  377. scipy/sparse/csc.py +0 -3
  378. scipy/sparse/csgraph/_flow.cpython-313-darwin.so +0 -0
  379. scipy/sparse/csgraph/_matching.cpython-313-darwin.so +0 -0
  380. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-darwin.so +0 -0
  381. scipy/sparse/csgraph/_reordering.cpython-313-darwin.so +0 -0
  382. scipy/sparse/csgraph/_shortest_path.cpython-313-darwin.so +0 -0
  383. scipy/sparse/csgraph/_tools.cpython-313-darwin.so +0 -0
  384. scipy/sparse/csgraph/_traversal.cpython-313-darwin.so +0 -0
  385. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  386. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  387. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  388. scipy/sparse/csr.py +0 -5
  389. scipy/sparse/data.py +1 -6
  390. scipy/sparse/dia.py +0 -7
  391. scipy/sparse/dok.py +0 -10
  392. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-darwin.so +0 -0
  393. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  394. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  395. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-darwin.so +0 -0
  396. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  397. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  398. scipy/sparse/linalg/_interface.py +17 -18
  399. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  400. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  401. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  402. scipy/sparse/linalg/_isolve/minres.py +5 -5
  403. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  404. scipy/sparse/linalg/_isolve/utils.py +2 -8
  405. scipy/sparse/linalg/_matfuncs.py +1 -1
  406. scipy/sparse/linalg/_norm.py +1 -1
  407. scipy/sparse/linalg/_propack/_cpropack.cpython-313-darwin.so +0 -0
  408. scipy/sparse/linalg/_propack/_dpropack.cpython-313-darwin.so +0 -0
  409. scipy/sparse/linalg/_propack/_spropack.cpython-313-darwin.so +0 -0
  410. scipy/sparse/linalg/_propack/_zpropack.cpython-313-darwin.so +0 -0
  411. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  412. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  413. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  414. scipy/sparse/tests/test_base.py +207 -42
  415. scipy/sparse/tests/test_common1d.py +7 -7
  416. scipy/sparse/tests/test_construct.py +1 -1
  417. scipy/sparse/tests/test_coo.py +272 -4
  418. scipy/sparse/tests/test_sparsetools.py +5 -0
  419. scipy/sparse/tests/test_sputils.py +36 -7
  420. scipy/spatial/_ckdtree.cpython-313-darwin.so +0 -0
  421. scipy/spatial/_hausdorff.cpython-313-darwin.so +0 -0
  422. scipy/spatial/_qhull.cpython-313-darwin.so +0 -0
  423. scipy/spatial/_voronoi.cpython-313-darwin.so +0 -0
  424. scipy/spatial/distance.py +49 -42
  425. scipy/spatial/tests/test_distance.py +3 -1
  426. scipy/spatial/tests/test_kdtree.py +1 -0
  427. scipy/spatial/tests/test_qhull.py +7 -2
  428. scipy/spatial/transform/__init__.py +5 -3
  429. scipy/spatial/transform/_rigid_transform.cpython-313-darwin.so +0 -0
  430. scipy/spatial/transform/_rotation.cpython-313-darwin.so +0 -0
  431. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  432. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  433. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  434. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  435. scipy/special/__init__.py +1 -47
  436. scipy/special/_add_newdocs.py +34 -772
  437. scipy/special/_basic.py +22 -25
  438. scipy/special/_comb.cpython-313-darwin.so +0 -0
  439. scipy/special/_ellip_harm_2.cpython-313-darwin.so +0 -0
  440. scipy/special/_gufuncs.cpython-313-darwin.so +0 -0
  441. scipy/special/_logsumexp.py +67 -58
  442. scipy/special/_orthogonal.pyi +1 -1
  443. scipy/special/_specfun.cpython-313-darwin.so +0 -0
  444. scipy/special/_special_ufuncs.cpython-313-darwin.so +0 -0
  445. scipy/special/_spherical_bessel.py +4 -4
  446. scipy/special/_support_alternative_backends.py +212 -119
  447. scipy/special/_test_internal.cpython-313-darwin.so +0 -0
  448. scipy/special/_testutils.py +4 -4
  449. scipy/special/_ufuncs.cpython-313-darwin.so +0 -0
  450. scipy/special/_ufuncs.pyi +1 -0
  451. scipy/special/_ufuncs.pyx +215 -1400
  452. scipy/special/_ufuncs_cxx.cpython-313-darwin.so +0 -0
  453. scipy/special/_ufuncs_cxx.pxd +2 -15
  454. scipy/special/_ufuncs_cxx.pyx +5 -44
  455. scipy/special/_ufuncs_cxx_defs.h +2 -16
  456. scipy/special/_ufuncs_defs.h +0 -8
  457. scipy/special/cython_special.cpython-313-darwin.so +0 -0
  458. scipy/special/cython_special.pxd +1 -1
  459. scipy/special/tests/_cython_examples/meson.build +10 -1
  460. scipy/special/tests/test_basic.py +153 -20
  461. scipy/special/tests/test_boost_ufuncs.py +3 -0
  462. scipy/special/tests/test_cdflib.py +35 -11
  463. scipy/special/tests/test_gammainc.py +16 -0
  464. scipy/special/tests/test_hyp2f1.py +2 -2
  465. scipy/special/tests/test_log1mexp.py +85 -0
  466. scipy/special/tests/test_logsumexp.py +206 -64
  467. scipy/special/tests/test_mpmath.py +1 -0
  468. scipy/special/tests/test_nan_inputs.py +1 -1
  469. scipy/special/tests/test_orthogonal.py +17 -18
  470. scipy/special/tests/test_sf_error.py +3 -2
  471. scipy/special/tests/test_sph_harm.py +6 -7
  472. scipy/special/tests/test_support_alternative_backends.py +211 -76
  473. scipy/stats/__init__.py +4 -1
  474. scipy/stats/_ansari_swilk_statistics.cpython-313-darwin.so +0 -0
  475. scipy/stats/_axis_nan_policy.py +4 -3
  476. scipy/stats/_biasedurn.cpython-313-darwin.so +0 -0
  477. scipy/stats/_continued_fraction.py +387 -0
  478. scipy/stats/_continuous_distns.py +277 -310
  479. scipy/stats/_covariance.py +6 -3
  480. scipy/stats/_discrete_distns.py +39 -32
  481. scipy/stats/_distn_infrastructure.py +39 -12
  482. scipy/stats/_distribution_infrastructure.py +900 -238
  483. scipy/stats/_entropy.py +7 -8
  484. scipy/{_lib → stats}/_finite_differences.py +1 -1
  485. scipy/stats/_hypotests.py +82 -49
  486. scipy/stats/_kde.py +53 -49
  487. scipy/stats/_ksstats.py +1 -1
  488. scipy/stats/_levy_stable/__init__.py +7 -15
  489. scipy/stats/_levy_stable/levyst.cpython-313-darwin.so +0 -0
  490. scipy/stats/_morestats.py +112 -67
  491. scipy/stats/_mstats_basic.py +13 -17
  492. scipy/stats/_mstats_extras.py +8 -8
  493. scipy/stats/_multivariate.py +89 -113
  494. scipy/stats/_new_distributions.py +97 -20
  495. scipy/stats/_page_trend_test.py +12 -5
  496. scipy/stats/_probability_distribution.py +265 -43
  497. scipy/stats/_qmc.py +14 -9
  498. scipy/stats/_qmc_cy.cpython-313-darwin.so +0 -0
  499. scipy/stats/_qmvnt.py +16 -95
  500. scipy/stats/_qmvnt_cy.cpython-313-darwin.so +0 -0
  501. scipy/stats/_quantile.py +335 -0
  502. scipy/stats/_rcont/rcont.cpython-313-darwin.so +0 -0
  503. scipy/stats/_resampling.py +4 -29
  504. scipy/stats/_sampling.py +1 -1
  505. scipy/stats/_sobol.cpython-313-darwin.so +0 -0
  506. scipy/stats/_stats.cpython-313-darwin.so +0 -0
  507. scipy/stats/_stats_mstats_common.py +19 -2
  508. scipy/stats/_stats_py.py +534 -460
  509. scipy/stats/_unuran/unuran_wrapper.cpython-313-darwin.so +0 -0
  510. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  511. scipy/stats/_variation.py +5 -7
  512. scipy/stats/_wilcoxon.py +13 -7
  513. scipy/stats/tests/common_tests.py +6 -4
  514. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  515. scipy/stats/tests/test_continued_fraction.py +173 -0
  516. scipy/stats/tests/test_continuous.py +379 -60
  517. scipy/stats/tests/test_continuous_basic.py +18 -12
  518. scipy/stats/tests/test_discrete_basic.py +14 -8
  519. scipy/stats/tests/test_discrete_distns.py +16 -16
  520. scipy/stats/tests/test_distributions.py +95 -75
  521. scipy/stats/tests/test_entropy.py +40 -48
  522. scipy/stats/tests/test_fit.py +4 -3
  523. scipy/stats/tests/test_hypotests.py +153 -24
  524. scipy/stats/tests/test_kdeoth.py +109 -41
  525. scipy/stats/tests/test_marray.py +289 -0
  526. scipy/stats/tests/test_morestats.py +79 -47
  527. scipy/stats/tests/test_mstats_basic.py +3 -3
  528. scipy/stats/tests/test_multivariate.py +434 -83
  529. scipy/stats/tests/test_qmc.py +13 -10
  530. scipy/stats/tests/test_quantile.py +199 -0
  531. scipy/stats/tests/test_rank.py +119 -112
  532. scipy/stats/tests/test_resampling.py +47 -56
  533. scipy/stats/tests/test_sampling.py +9 -4
  534. scipy/stats/tests/test_stats.py +799 -939
  535. scipy/stats/tests/test_variation.py +8 -6
  536. scipy/version.py +2 -2
  537. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  538. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +8 -8
  539. {scipy-1.15.3.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +540 -547
  540. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  541. scipy/_lib/array_api_extra/_funcs.py +0 -484
  542. scipy/_lib/array_api_extra/_typing.py +0 -8
  543. scipy/interpolate/_bspl.cpython-313-darwin.so +0 -0
  544. scipy/optimize/_cobyla.cpython-313-darwin.so +0 -0
  545. scipy/optimize/_cython_nnls.cpython-313-darwin.so +0 -0
  546. scipy/optimize/_slsqp.cpython-313-darwin.so +0 -0
  547. scipy/spatial/qhull_src/COPYING.txt +0 -38
  548. scipy/special/libsf_error_state.dylib +0 -0
  549. scipy/special/tests/test_log_softmax.py +0 -109
  550. scipy/special/tests/test_xsf_cuda.py +0 -114
  551. scipy/special/xsf/binom.h +0 -89
  552. scipy/special/xsf/cdflib.h +0 -100
  553. scipy/special/xsf/cephes/airy.h +0 -307
  554. scipy/special/xsf/cephes/besselpoly.h +0 -51
  555. scipy/special/xsf/cephes/beta.h +0 -257
  556. scipy/special/xsf/cephes/cbrt.h +0 -131
  557. scipy/special/xsf/cephes/chbevl.h +0 -85
  558. scipy/special/xsf/cephes/chdtr.h +0 -193
  559. scipy/special/xsf/cephes/const.h +0 -87
  560. scipy/special/xsf/cephes/ellie.h +0 -293
  561. scipy/special/xsf/cephes/ellik.h +0 -251
  562. scipy/special/xsf/cephes/ellpe.h +0 -107
  563. scipy/special/xsf/cephes/ellpk.h +0 -117
  564. scipy/special/xsf/cephes/expn.h +0 -260
  565. scipy/special/xsf/cephes/gamma.h +0 -398
  566. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  567. scipy/special/xsf/cephes/hyperg.h +0 -361
  568. scipy/special/xsf/cephes/i0.h +0 -149
  569. scipy/special/xsf/cephes/i1.h +0 -158
  570. scipy/special/xsf/cephes/igam.h +0 -421
  571. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  572. scipy/special/xsf/cephes/igami.h +0 -313
  573. scipy/special/xsf/cephes/j0.h +0 -225
  574. scipy/special/xsf/cephes/j1.h +0 -198
  575. scipy/special/xsf/cephes/jv.h +0 -715
  576. scipy/special/xsf/cephes/k0.h +0 -164
  577. scipy/special/xsf/cephes/k1.h +0 -163
  578. scipy/special/xsf/cephes/kn.h +0 -243
  579. scipy/special/xsf/cephes/lanczos.h +0 -112
  580. scipy/special/xsf/cephes/ndtr.h +0 -275
  581. scipy/special/xsf/cephes/poch.h +0 -85
  582. scipy/special/xsf/cephes/polevl.h +0 -167
  583. scipy/special/xsf/cephes/psi.h +0 -194
  584. scipy/special/xsf/cephes/rgamma.h +0 -111
  585. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  586. scipy/special/xsf/cephes/shichi.h +0 -248
  587. scipy/special/xsf/cephes/sici.h +0 -224
  588. scipy/special/xsf/cephes/sindg.h +0 -221
  589. scipy/special/xsf/cephes/tandg.h +0 -139
  590. scipy/special/xsf/cephes/trig.h +0 -58
  591. scipy/special/xsf/cephes/unity.h +0 -186
  592. scipy/special/xsf/cephes/zeta.h +0 -172
  593. scipy/special/xsf/config.h +0 -304
  594. scipy/special/xsf/digamma.h +0 -205
  595. scipy/special/xsf/error.h +0 -57
  596. scipy/special/xsf/evalpoly.h +0 -47
  597. scipy/special/xsf/expint.h +0 -266
  598. scipy/special/xsf/hyp2f1.h +0 -694
  599. scipy/special/xsf/iv_ratio.h +0 -173
  600. scipy/special/xsf/lambertw.h +0 -150
  601. scipy/special/xsf/loggamma.h +0 -163
  602. scipy/special/xsf/sici.h +0 -200
  603. scipy/special/xsf/tools.h +0 -427
  604. scipy/special/xsf/trig.h +0 -164
  605. scipy/special/xsf/wright_bessel.h +0 -843
  606. scipy/special/xsf/zlog1.h +0 -35
  607. scipy/stats/_mvn.cpython-313-darwin.so +0 -0
  608. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -1,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))
Binary file
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