scipy 1.15.3__cp313-cp313-win_amd64.whl → 1.16.0rc2__cp313-cp313-win_amd64.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 (759) hide show
  1. scipy/__config__.py +8 -8
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cp313-win_amd64.dll.a +0 -0
  4. scipy/_cyutility.cp313-win_amd64.pyd +0 -0
  5. scipy/_lib/_array_api.py +486 -161
  6. scipy/_lib/_array_api_compat_vendor.py +9 -0
  7. scipy/_lib/_bunch.py +4 -0
  8. scipy/_lib/_ccallback_c.cp313-win_amd64.dll.a +0 -0
  9. scipy/_lib/_ccallback_c.cp313-win_amd64.pyd +0 -0
  10. scipy/_lib/_docscrape.py +1 -1
  11. scipy/_lib/_elementwise_iterative_method.py +15 -26
  12. scipy/_lib/_fpumode.cp313-win_amd64.dll.a +0 -0
  13. scipy/_lib/_fpumode.cp313-win_amd64.pyd +0 -0
  14. scipy/_lib/_sparse.py +41 -0
  15. scipy/_lib/_test_ccallback.cp313-win_amd64.dll.a +0 -0
  16. scipy/_lib/_test_ccallback.cp313-win_amd64.pyd +0 -0
  17. scipy/_lib/_test_deprecation_call.cp313-win_amd64.dll.a +0 -0
  18. scipy/_lib/_test_deprecation_call.cp313-win_amd64.pyd +0 -0
  19. scipy/_lib/_test_deprecation_def.cp313-win_amd64.dll.a +0 -0
  20. scipy/_lib/_test_deprecation_def.cp313-win_amd64.pyd +0 -0
  21. scipy/_lib/_testutils.py +6 -2
  22. scipy/_lib/_uarray/_uarray.cp313-win_amd64.dll.a +0 -0
  23. scipy/_lib/_uarray/_uarray.cp313-win_amd64.pyd +0 -0
  24. scipy/_lib/_util.py +222 -125
  25. scipy/_lib/array_api_compat/__init__.py +4 -4
  26. scipy/_lib/array_api_compat/_internal.py +19 -6
  27. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  28. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  29. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  30. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  31. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  32. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  33. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  34. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  35. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  36. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  37. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  38. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  39. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  40. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  41. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  42. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  43. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  44. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  45. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  46. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  47. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  48. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  49. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  50. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  51. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  52. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  53. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  54. scipy/_lib/array_api_extra/__init__.py +26 -3
  55. scipy/_lib/array_api_extra/_delegation.py +171 -0
  56. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  57. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  58. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  59. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  60. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  61. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  62. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  63. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  64. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  65. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  66. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  67. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  68. scipy/_lib/array_api_extra/testing.py +359 -0
  69. scipy/_lib/decorator.py +2 -2
  70. scipy/_lib/doccer.py +1 -7
  71. scipy/_lib/messagestream.cp313-win_amd64.dll.a +0 -0
  72. scipy/_lib/messagestream.cp313-win_amd64.pyd +0 -0
  73. scipy/_lib/pyprima/__init__.py +212 -0
  74. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  75. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  76. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  77. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  78. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  79. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  80. scipy/_lib/pyprima/cobyla/update.py +289 -0
  81. scipy/_lib/pyprima/common/__init__.py +0 -0
  82. scipy/_lib/pyprima/common/_bounds.py +34 -0
  83. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  84. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  85. scipy/_lib/pyprima/common/_project.py +173 -0
  86. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  87. scipy/_lib/pyprima/common/consts.py +47 -0
  88. scipy/_lib/pyprima/common/evaluate.py +99 -0
  89. scipy/_lib/pyprima/common/history.py +38 -0
  90. scipy/_lib/pyprima/common/infos.py +30 -0
  91. scipy/_lib/pyprima/common/linalg.py +435 -0
  92. scipy/_lib/pyprima/common/message.py +290 -0
  93. scipy/_lib/pyprima/common/powalg.py +131 -0
  94. scipy/_lib/pyprima/common/preproc.py +277 -0
  95. scipy/_lib/pyprima/common/present.py +5 -0
  96. scipy/_lib/pyprima/common/ratio.py +54 -0
  97. scipy/_lib/pyprima/common/redrho.py +47 -0
  98. scipy/_lib/pyprima/common/selectx.py +296 -0
  99. scipy/_lib/tests/test__util.py +105 -121
  100. scipy/_lib/tests/test_array_api.py +166 -35
  101. scipy/_lib/tests/test_bunch.py +7 -0
  102. scipy/_lib/tests/test_ccallback.py +2 -10
  103. scipy/_lib/tests/test_public_api.py +13 -0
  104. scipy/cluster/_hierarchy.cp313-win_amd64.dll.a +0 -0
  105. scipy/cluster/_hierarchy.cp313-win_amd64.pyd +0 -0
  106. scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.dll.a +0 -0
  107. scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.pyd +0 -0
  108. scipy/cluster/_vq.cp313-win_amd64.dll.a +0 -0
  109. scipy/cluster/_vq.cp313-win_amd64.pyd +0 -0
  110. scipy/cluster/hierarchy.py +393 -223
  111. scipy/cluster/tests/test_hierarchy.py +273 -335
  112. scipy/cluster/tests/test_vq.py +45 -61
  113. scipy/cluster/vq.py +39 -35
  114. scipy/conftest.py +263 -157
  115. scipy/constants/_constants.py +4 -1
  116. scipy/constants/tests/test_codata.py +2 -2
  117. scipy/constants/tests/test_constants.py +11 -18
  118. scipy/datasets/_download_all.py +15 -1
  119. scipy/datasets/_fetchers.py +7 -1
  120. scipy/datasets/_utils.py +1 -1
  121. scipy/differentiate/_differentiate.py +25 -25
  122. scipy/differentiate/tests/test_differentiate.py +24 -25
  123. scipy/fft/_basic.py +20 -0
  124. scipy/fft/_helper.py +3 -34
  125. scipy/fft/_pocketfft/helper.py +29 -1
  126. scipy/fft/_pocketfft/pypocketfft.cp313-win_amd64.dll.a +0 -0
  127. scipy/fft/_pocketfft/pypocketfft.cp313-win_amd64.pyd +0 -0
  128. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  129. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  130. scipy/fft/_realtransforms.py +13 -0
  131. scipy/fft/tests/test_basic.py +27 -25
  132. scipy/fft/tests/test_fftlog.py +16 -7
  133. scipy/fft/tests/test_helper.py +18 -34
  134. scipy/fft/tests/test_real_transforms.py +8 -10
  135. scipy/fftpack/convolve.cp313-win_amd64.dll.a +0 -0
  136. scipy/fftpack/convolve.cp313-win_amd64.pyd +0 -0
  137. scipy/fftpack/tests/test_basic.py +2 -4
  138. scipy/fftpack/tests/test_real_transforms.py +8 -9
  139. scipy/integrate/_bvp.py +9 -3
  140. scipy/integrate/_cubature.py +3 -2
  141. scipy/integrate/_dop.cp313-win_amd64.dll.a +0 -0
  142. scipy/integrate/_dop.cp313-win_amd64.pyd +0 -0
  143. scipy/integrate/_lsoda.cp313-win_amd64.dll.a +0 -0
  144. scipy/integrate/_lsoda.cp313-win_amd64.pyd +0 -0
  145. scipy/integrate/_ode.py +9 -2
  146. scipy/integrate/_odepack.cp313-win_amd64.dll.a +0 -0
  147. scipy/integrate/_odepack.cp313-win_amd64.pyd +0 -0
  148. scipy/integrate/_quad_vec.py +21 -29
  149. scipy/integrate/_quadpack.cp313-win_amd64.dll.a +0 -0
  150. scipy/integrate/_quadpack.cp313-win_amd64.pyd +0 -0
  151. scipy/integrate/_quadpack_py.py +11 -7
  152. scipy/integrate/_quadrature.py +3 -3
  153. scipy/integrate/_rules/_base.py +2 -2
  154. scipy/integrate/_tanhsinh.py +48 -47
  155. scipy/integrate/_test_multivariate.cp313-win_amd64.dll.a +0 -0
  156. scipy/integrate/_test_multivariate.cp313-win_amd64.pyd +0 -0
  157. scipy/integrate/_test_odeint_banded.cp313-win_amd64.dll.a +0 -0
  158. scipy/integrate/_test_odeint_banded.cp313-win_amd64.pyd +0 -0
  159. scipy/integrate/_vode.cp313-win_amd64.dll.a +0 -0
  160. scipy/integrate/_vode.cp313-win_amd64.pyd +0 -0
  161. scipy/integrate/tests/test__quad_vec.py +0 -6
  162. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  163. scipy/integrate/tests/test_cubature.py +21 -35
  164. scipy/integrate/tests/test_quadrature.py +6 -8
  165. scipy/integrate/tests/test_tanhsinh.py +56 -48
  166. scipy/interpolate/__init__.py +70 -58
  167. scipy/interpolate/_bary_rational.py +22 -22
  168. scipy/interpolate/_bsplines.py +119 -66
  169. scipy/interpolate/_cubic.py +65 -50
  170. scipy/interpolate/_dfitpack.cp313-win_amd64.dll.a +0 -0
  171. scipy/interpolate/_dfitpack.cp313-win_amd64.pyd +0 -0
  172. scipy/interpolate/_dierckx.cp313-win_amd64.dll.a +0 -0
  173. scipy/interpolate/_dierckx.cp313-win_amd64.pyd +0 -0
  174. scipy/interpolate/_fitpack.cp313-win_amd64.dll.a +0 -0
  175. scipy/interpolate/_fitpack.cp313-win_amd64.pyd +0 -0
  176. scipy/interpolate/_fitpack2.py +9 -6
  177. scipy/interpolate/_fitpack_impl.py +32 -26
  178. scipy/interpolate/_fitpack_repro.py +23 -19
  179. scipy/interpolate/_interpnd.cp313-win_amd64.dll.a +0 -0
  180. scipy/interpolate/_interpnd.cp313-win_amd64.pyd +0 -0
  181. scipy/interpolate/_interpolate.py +30 -12
  182. scipy/interpolate/_ndbspline.py +13 -18
  183. scipy/interpolate/_ndgriddata.py +5 -8
  184. scipy/interpolate/_polyint.py +95 -31
  185. scipy/interpolate/_ppoly.cp313-win_amd64.dll.a +0 -0
  186. scipy/interpolate/_ppoly.cp313-win_amd64.pyd +0 -0
  187. scipy/interpolate/_rbf.py +2 -2
  188. scipy/interpolate/_rbfinterp.py +1 -1
  189. scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.dll.a +0 -0
  190. scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.pyd +0 -0
  191. scipy/interpolate/_rgi.py +31 -26
  192. scipy/interpolate/_rgi_cython.cp313-win_amd64.dll.a +0 -0
  193. scipy/interpolate/_rgi_cython.cp313-win_amd64.pyd +0 -0
  194. scipy/interpolate/dfitpack.py +0 -20
  195. scipy/interpolate/interpnd.py +1 -2
  196. scipy/interpolate/tests/test_bary_rational.py +2 -2
  197. scipy/interpolate/tests/test_bsplines.py +97 -1
  198. scipy/interpolate/tests/test_fitpack2.py +39 -1
  199. scipy/interpolate/tests/test_interpnd.py +32 -20
  200. scipy/interpolate/tests/test_interpolate.py +48 -4
  201. scipy/interpolate/tests/test_rgi.py +2 -1
  202. scipy/io/_fast_matrix_market/__init__.py +2 -0
  203. scipy/io/_fast_matrix_market/_fmm_core.cp313-win_amd64.dll.a +0 -0
  204. scipy/io/_fast_matrix_market/_fmm_core.cp313-win_amd64.pyd +0 -0
  205. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  206. scipy/io/_harwell_boeing/hb.py +7 -11
  207. scipy/io/_idl.py +5 -7
  208. scipy/io/_netcdf.py +15 -5
  209. scipy/io/_test_fortran.cp313-win_amd64.dll.a +0 -0
  210. scipy/io/_test_fortran.cp313-win_amd64.pyd +0 -0
  211. scipy/io/arff/tests/test_arffread.py +3 -3
  212. scipy/io/matlab/__init__.py +5 -3
  213. scipy/io/matlab/_mio.py +4 -1
  214. scipy/io/matlab/_mio5.py +19 -13
  215. scipy/io/matlab/_mio5_utils.cp313-win_amd64.dll.a +0 -0
  216. scipy/io/matlab/_mio5_utils.cp313-win_amd64.pyd +0 -0
  217. scipy/io/matlab/_mio_utils.cp313-win_amd64.dll.a +0 -0
  218. scipy/io/matlab/_mio_utils.cp313-win_amd64.pyd +0 -0
  219. scipy/io/matlab/_miobase.py +4 -1
  220. scipy/io/matlab/_streams.cp313-win_amd64.dll.a +0 -0
  221. scipy/io/matlab/_streams.cp313-win_amd64.pyd +0 -0
  222. scipy/io/matlab/tests/test_mio.py +46 -18
  223. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  224. scipy/io/tests/test_mmio.py +7 -1
  225. scipy/io/tests/test_wavfile.py +41 -0
  226. scipy/io/wavfile.py +57 -10
  227. scipy/linalg/_basic.py +113 -86
  228. scipy/linalg/_cythonized_array_utils.cp313-win_amd64.dll.a +0 -0
  229. scipy/linalg/_cythonized_array_utils.cp313-win_amd64.pyd +0 -0
  230. scipy/linalg/_decomp.py +22 -9
  231. scipy/linalg/_decomp_cholesky.py +28 -13
  232. scipy/linalg/_decomp_cossin.py +45 -30
  233. scipy/linalg/_decomp_interpolative.cp313-win_amd64.dll.a +0 -0
  234. scipy/linalg/_decomp_interpolative.cp313-win_amd64.pyd +0 -0
  235. scipy/linalg/_decomp_ldl.py +4 -1
  236. scipy/linalg/_decomp_lu.py +18 -6
  237. scipy/linalg/_decomp_lu_cython.cp313-win_amd64.dll.a +0 -0
  238. scipy/linalg/_decomp_lu_cython.cp313-win_amd64.pyd +0 -0
  239. scipy/linalg/_decomp_polar.py +2 -0
  240. scipy/linalg/_decomp_qr.py +6 -2
  241. scipy/linalg/_decomp_qz.py +3 -0
  242. scipy/linalg/_decomp_schur.py +3 -1
  243. scipy/linalg/_decomp_svd.py +13 -2
  244. scipy/linalg/_decomp_update.cp313-win_amd64.dll.a +0 -0
  245. scipy/linalg/_decomp_update.cp313-win_amd64.pyd +0 -0
  246. scipy/linalg/_expm_frechet.py +4 -0
  247. scipy/linalg/_fblas.cp313-win_amd64.dll.a +0 -0
  248. scipy/linalg/_fblas.cp313-win_amd64.pyd +0 -0
  249. scipy/linalg/_flapack.cp313-win_amd64.dll.a +0 -0
  250. scipy/linalg/_flapack.cp313-win_amd64.pyd +0 -0
  251. scipy/linalg/_linalg_pythran.cp313-win_amd64.dll.a +0 -0
  252. scipy/linalg/_linalg_pythran.cp313-win_amd64.pyd +0 -0
  253. scipy/linalg/_matfuncs.py +187 -4
  254. scipy/linalg/_matfuncs_expm.cp313-win_amd64.dll.a +0 -0
  255. scipy/linalg/_matfuncs_expm.cp313-win_amd64.pyd +0 -0
  256. scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.dll.a +0 -0
  257. scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.pyd +0 -0
  258. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  259. scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.dll.a +0 -0
  260. scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.pyd +0 -0
  261. scipy/linalg/_procrustes.py +2 -0
  262. scipy/linalg/_sketches.py +17 -6
  263. scipy/linalg/_solve_toeplitz.cp313-win_amd64.dll.a +0 -0
  264. scipy/linalg/_solve_toeplitz.cp313-win_amd64.pyd +0 -0
  265. scipy/linalg/_solvers.py +7 -2
  266. scipy/linalg/_special_matrices.py +26 -36
  267. scipy/linalg/cython_blas.cp313-win_amd64.dll.a +0 -0
  268. scipy/linalg/cython_blas.cp313-win_amd64.pyd +0 -0
  269. scipy/linalg/cython_lapack.cp313-win_amd64.dll.a +0 -0
  270. scipy/linalg/cython_lapack.cp313-win_amd64.pyd +0 -0
  271. scipy/linalg/lapack.py +22 -2
  272. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  273. scipy/linalg/tests/test_basic.py +31 -16
  274. scipy/linalg/tests/test_batch.py +588 -0
  275. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  276. scipy/linalg/tests/test_decomp.py +40 -3
  277. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  278. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  279. scipy/linalg/tests/test_lapack.py +115 -7
  280. scipy/linalg/tests/test_matfuncs.py +157 -102
  281. scipy/linalg/tests/test_procrustes.py +0 -7
  282. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  283. scipy/linalg/tests/test_special_matrices.py +1 -5
  284. scipy/ndimage/__init__.py +1 -0
  285. scipy/ndimage/_ctest.cp313-win_amd64.dll.a +0 -0
  286. scipy/ndimage/_ctest.cp313-win_amd64.pyd +0 -0
  287. scipy/ndimage/_cytest.cp313-win_amd64.dll.a +0 -0
  288. scipy/ndimage/_cytest.cp313-win_amd64.pyd +0 -0
  289. scipy/ndimage/_delegators.py +8 -2
  290. scipy/ndimage/_filters.py +453 -5
  291. scipy/ndimage/_interpolation.py +36 -6
  292. scipy/ndimage/_measurements.py +4 -2
  293. scipy/ndimage/_morphology.py +5 -0
  294. scipy/ndimage/_nd_image.cp313-win_amd64.dll.a +0 -0
  295. scipy/ndimage/_nd_image.cp313-win_amd64.pyd +0 -0
  296. scipy/ndimage/_ni_docstrings.py +5 -1
  297. scipy/ndimage/_ni_label.cp313-win_amd64.dll.a +0 -0
  298. scipy/ndimage/_ni_label.cp313-win_amd64.pyd +0 -0
  299. scipy/ndimage/_ni_support.py +1 -5
  300. scipy/ndimage/_rank_filter_1d.cp313-win_amd64.dll.a +0 -0
  301. scipy/ndimage/_rank_filter_1d.cp313-win_amd64.pyd +0 -0
  302. scipy/ndimage/_support_alternative_backends.py +18 -6
  303. scipy/ndimage/tests/test_filters.py +370 -259
  304. scipy/ndimage/tests/test_fourier.py +7 -9
  305. scipy/ndimage/tests/test_interpolation.py +68 -61
  306. scipy/ndimage/tests/test_measurements.py +18 -35
  307. scipy/ndimage/tests/test_morphology.py +143 -131
  308. scipy/ndimage/tests/test_splines.py +1 -3
  309. scipy/odr/__odrpack.cp313-win_amd64.dll.a +0 -0
  310. scipy/odr/__odrpack.cp313-win_amd64.pyd +0 -0
  311. scipy/optimize/_basinhopping.py +13 -7
  312. scipy/optimize/_bglu_dense.cp313-win_amd64.dll.a +0 -0
  313. scipy/optimize/_bglu_dense.cp313-win_amd64.pyd +0 -0
  314. scipy/optimize/_bracket.py +17 -24
  315. scipy/optimize/_chandrupatla.py +9 -10
  316. scipy/optimize/_cobyla_py.py +104 -123
  317. scipy/optimize/_constraints.py +14 -10
  318. scipy/optimize/_differentiable_functions.py +371 -230
  319. scipy/optimize/_differentialevolution.py +4 -3
  320. scipy/optimize/_direct.cp313-win_amd64.dll.a +0 -0
  321. scipy/optimize/_direct.cp313-win_amd64.pyd +0 -0
  322. scipy/optimize/_dual_annealing.py +1 -1
  323. scipy/optimize/_elementwise.py +1 -4
  324. scipy/optimize/_group_columns.cp313-win_amd64.dll.a +0 -0
  325. scipy/optimize/_group_columns.cp313-win_amd64.pyd +0 -0
  326. scipy/optimize/_highspy/_core.cp313-win_amd64.dll.a +0 -0
  327. scipy/optimize/_highspy/_core.cp313-win_amd64.pyd +0 -0
  328. scipy/optimize/_highspy/_highs_options.cp313-win_amd64.dll.a +0 -0
  329. scipy/optimize/_highspy/_highs_options.cp313-win_amd64.pyd +0 -0
  330. scipy/optimize/_lbfgsb.cp313-win_amd64.dll.a +0 -0
  331. scipy/optimize/_lbfgsb.cp313-win_amd64.pyd +0 -0
  332. scipy/optimize/_lbfgsb_py.py +57 -16
  333. scipy/optimize/_linprog_doc.py +2 -2
  334. scipy/optimize/_linprog_highs.py +2 -2
  335. scipy/optimize/_linprog_ip.py +25 -10
  336. scipy/optimize/_linprog_util.py +14 -16
  337. scipy/optimize/_lsap.cp313-win_amd64.dll.a +0 -0
  338. scipy/optimize/_lsap.cp313-win_amd64.pyd +0 -0
  339. scipy/optimize/_lsq/common.py +3 -3
  340. scipy/optimize/_lsq/dogbox.py +16 -2
  341. scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.dll.a +0 -0
  342. scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.pyd +0 -0
  343. scipy/optimize/_lsq/least_squares.py +198 -126
  344. scipy/optimize/_lsq/lsq_linear.py +6 -6
  345. scipy/optimize/_lsq/trf.py +35 -8
  346. scipy/optimize/_milp.py +3 -1
  347. scipy/optimize/_minimize.py +105 -36
  348. scipy/optimize/_minpack.cp313-win_amd64.dll.a +0 -0
  349. scipy/optimize/_minpack.cp313-win_amd64.pyd +0 -0
  350. scipy/optimize/_minpack_py.py +21 -14
  351. scipy/optimize/_moduleTNC.cp313-win_amd64.dll.a +0 -0
  352. scipy/optimize/_moduleTNC.cp313-win_amd64.pyd +0 -0
  353. scipy/optimize/_nnls.py +20 -21
  354. scipy/optimize/_nonlin.py +34 -3
  355. scipy/optimize/_numdiff.py +288 -110
  356. scipy/optimize/_optimize.py +86 -48
  357. scipy/optimize/_pava_pybind.cp313-win_amd64.dll.a +0 -0
  358. scipy/optimize/_pava_pybind.cp313-win_amd64.pyd +0 -0
  359. scipy/optimize/_remove_redundancy.py +5 -5
  360. scipy/optimize/_root_scalar.py +1 -1
  361. scipy/optimize/_shgo.py +6 -0
  362. scipy/optimize/_shgo_lib/_complex.py +1 -1
  363. scipy/optimize/_slsqp_py.py +216 -124
  364. scipy/optimize/_slsqplib.cp313-win_amd64.dll.a +0 -0
  365. scipy/optimize/_slsqplib.cp313-win_amd64.pyd +0 -0
  366. scipy/optimize/_spectral.py +1 -1
  367. scipy/optimize/_tnc.py +8 -1
  368. scipy/optimize/_trlib/_trlib.cp313-win_amd64.dll.a +0 -0
  369. scipy/optimize/_trlib/_trlib.cp313-win_amd64.pyd +0 -0
  370. scipy/optimize/_trustregion.py +20 -6
  371. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  372. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  373. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  374. scipy/optimize/_trustregion_constr/projections.py +12 -8
  375. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  376. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  377. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  378. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  379. scipy/optimize/_trustregion_exact.py +0 -1
  380. scipy/optimize/_zeros.cp313-win_amd64.dll.a +0 -0
  381. scipy/optimize/_zeros.cp313-win_amd64.pyd +0 -0
  382. scipy/optimize/_zeros_py.py +97 -17
  383. scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.dll.a +0 -0
  384. scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.pyd +0 -0
  385. scipy/optimize/slsqp.py +0 -1
  386. scipy/optimize/tests/test__basinhopping.py +1 -1
  387. scipy/optimize/tests/test__differential_evolution.py +4 -4
  388. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  389. scipy/optimize/tests/test__numdiff.py +66 -22
  390. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  391. scipy/optimize/tests/test__shgo.py +9 -1
  392. scipy/optimize/tests/test_bracket.py +36 -46
  393. scipy/optimize/tests/test_chandrupatla.py +133 -135
  394. scipy/optimize/tests/test_cobyla.py +74 -45
  395. scipy/optimize/tests/test_constraints.py +1 -1
  396. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  397. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  398. scipy/optimize/tests/test_least_squares.py +125 -13
  399. scipy/optimize/tests/test_linear_assignment.py +3 -3
  400. scipy/optimize/tests/test_linprog.py +3 -3
  401. scipy/optimize/tests/test_lsq_linear.py +6 -6
  402. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  403. scipy/optimize/tests/test_minpack.py +4 -4
  404. scipy/optimize/tests/test_nnls.py +43 -3
  405. scipy/optimize/tests/test_nonlin.py +36 -0
  406. scipy/optimize/tests/test_optimize.py +95 -17
  407. scipy/optimize/tests/test_slsqp.py +36 -4
  408. scipy/optimize/tests/test_zeros.py +34 -1
  409. scipy/signal/__init__.py +12 -23
  410. scipy/signal/_delegators.py +568 -0
  411. scipy/signal/_filter_design.py +459 -241
  412. scipy/signal/_fir_filter_design.py +262 -90
  413. scipy/signal/_lti_conversion.py +3 -2
  414. scipy/signal/_ltisys.py +118 -91
  415. scipy/signal/_max_len_seq_inner.cp313-win_amd64.dll.a +0 -0
  416. scipy/signal/_max_len_seq_inner.cp313-win_amd64.pyd +0 -0
  417. scipy/signal/_peak_finding_utils.cp313-win_amd64.dll.a +0 -0
  418. scipy/signal/_peak_finding_utils.cp313-win_amd64.pyd +0 -0
  419. scipy/signal/_polyutils.py +172 -0
  420. scipy/signal/_short_time_fft.py +519 -70
  421. scipy/signal/_signal_api.py +30 -0
  422. scipy/signal/_signaltools.py +719 -399
  423. scipy/signal/_sigtools.cp313-win_amd64.dll.a +0 -0
  424. scipy/signal/_sigtools.cp313-win_amd64.pyd +0 -0
  425. scipy/signal/_sosfilt.cp313-win_amd64.dll.a +0 -0
  426. scipy/signal/_sosfilt.cp313-win_amd64.pyd +0 -0
  427. scipy/signal/_spectral_py.py +230 -50
  428. scipy/signal/_spline.cp313-win_amd64.dll.a +0 -0
  429. scipy/signal/_spline.cp313-win_amd64.pyd +0 -0
  430. scipy/signal/_spline_filters.py +108 -68
  431. scipy/signal/_support_alternative_backends.py +73 -0
  432. scipy/signal/_upfirdn.py +4 -1
  433. scipy/signal/_upfirdn_apply.cp313-win_amd64.dll.a +0 -0
  434. scipy/signal/_upfirdn_apply.cp313-win_amd64.pyd +0 -0
  435. scipy/signal/_waveforms.py +2 -11
  436. scipy/signal/_wavelets.py +1 -1
  437. scipy/signal/fir_filter_design.py +1 -0
  438. scipy/signal/spline.py +4 -11
  439. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  440. scipy/signal/tests/test_bsplines.py +114 -79
  441. scipy/signal/tests/test_cont2discrete.py +9 -2
  442. scipy/signal/tests/test_filter_design.py +721 -481
  443. scipy/signal/tests/test_fir_filter_design.py +332 -140
  444. scipy/signal/tests/test_savitzky_golay.py +4 -3
  445. scipy/signal/tests/test_short_time_fft.py +221 -3
  446. scipy/signal/tests/test_signaltools.py +2144 -1348
  447. scipy/signal/tests/test_spectral.py +50 -6
  448. scipy/signal/tests/test_splines.py +161 -96
  449. scipy/signal/tests/test_upfirdn.py +84 -50
  450. scipy/signal/tests/test_waveforms.py +20 -0
  451. scipy/signal/tests/test_windows.py +607 -466
  452. scipy/signal/windows/_windows.py +287 -148
  453. scipy/sparse/__init__.py +23 -4
  454. scipy/sparse/_base.py +270 -108
  455. scipy/sparse/_bsr.py +7 -4
  456. scipy/sparse/_compressed.py +59 -231
  457. scipy/sparse/_construct.py +90 -38
  458. scipy/sparse/_coo.py +115 -181
  459. scipy/sparse/_csc.py +4 -4
  460. scipy/sparse/_csparsetools.cp313-win_amd64.dll.a +0 -0
  461. scipy/sparse/_csparsetools.cp313-win_amd64.pyd +0 -0
  462. scipy/sparse/_csr.py +2 -2
  463. scipy/sparse/_data.py +48 -48
  464. scipy/sparse/_dia.py +105 -18
  465. scipy/sparse/_dok.py +0 -23
  466. scipy/sparse/_index.py +4 -4
  467. scipy/sparse/_matrix.py +23 -0
  468. scipy/sparse/_sparsetools.cp313-win_amd64.dll.a +0 -0
  469. scipy/sparse/_sparsetools.cp313-win_amd64.pyd +0 -0
  470. scipy/sparse/_sputils.py +37 -22
  471. scipy/sparse/base.py +0 -9
  472. scipy/sparse/bsr.py +0 -14
  473. scipy/sparse/compressed.py +0 -23
  474. scipy/sparse/construct.py +0 -6
  475. scipy/sparse/coo.py +0 -14
  476. scipy/sparse/csc.py +0 -3
  477. scipy/sparse/csgraph/_flow.cp313-win_amd64.dll.a +0 -0
  478. scipy/sparse/csgraph/_flow.cp313-win_amd64.pyd +0 -0
  479. scipy/sparse/csgraph/_matching.cp313-win_amd64.dll.a +0 -0
  480. scipy/sparse/csgraph/_matching.cp313-win_amd64.pyd +0 -0
  481. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.dll.a +0 -0
  482. scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.pyd +0 -0
  483. scipy/sparse/csgraph/_reordering.cp313-win_amd64.dll.a +0 -0
  484. scipy/sparse/csgraph/_reordering.cp313-win_amd64.pyd +0 -0
  485. scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.dll.a +0 -0
  486. scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.pyd +0 -0
  487. scipy/sparse/csgraph/_tools.cp313-win_amd64.dll.a +0 -0
  488. scipy/sparse/csgraph/_tools.cp313-win_amd64.pyd +0 -0
  489. scipy/sparse/csgraph/_traversal.cp313-win_amd64.dll.a +0 -0
  490. scipy/sparse/csgraph/_traversal.cp313-win_amd64.pyd +0 -0
  491. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  492. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  493. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  494. scipy/sparse/csr.py +0 -5
  495. scipy/sparse/data.py +1 -6
  496. scipy/sparse/dia.py +0 -7
  497. scipy/sparse/dok.py +0 -10
  498. scipy/sparse/linalg/_dsolve/_superlu.cp313-win_amd64.dll.a +0 -0
  499. scipy/sparse/linalg/_dsolve/_superlu.cp313-win_amd64.pyd +0 -0
  500. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  501. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  502. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-win_amd64.dll.a +0 -0
  503. scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-win_amd64.pyd +0 -0
  504. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  505. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  506. scipy/sparse/linalg/_interface.py +17 -18
  507. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  508. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  509. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  510. scipy/sparse/linalg/_isolve/minres.py +5 -5
  511. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  512. scipy/sparse/linalg/_isolve/utils.py +2 -8
  513. scipy/sparse/linalg/_matfuncs.py +1 -1
  514. scipy/sparse/linalg/_norm.py +1 -1
  515. scipy/sparse/linalg/_propack/_cpropack.cp313-win_amd64.dll.a +0 -0
  516. scipy/sparse/linalg/_propack/_cpropack.cp313-win_amd64.pyd +0 -0
  517. scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.dll.a +0 -0
  518. scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.pyd +0 -0
  519. scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.dll.a +0 -0
  520. scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.pyd +0 -0
  521. scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.dll.a +0 -0
  522. scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.pyd +0 -0
  523. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  524. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  525. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  526. scipy/sparse/tests/test_base.py +214 -42
  527. scipy/sparse/tests/test_common1d.py +7 -7
  528. scipy/sparse/tests/test_construct.py +1 -1
  529. scipy/sparse/tests/test_coo.py +272 -4
  530. scipy/sparse/tests/test_sparsetools.py +5 -0
  531. scipy/sparse/tests/test_sputils.py +36 -7
  532. scipy/spatial/_ckdtree.cp313-win_amd64.dll.a +0 -0
  533. scipy/spatial/_ckdtree.cp313-win_amd64.pyd +0 -0
  534. scipy/spatial/_distance_pybind.cp313-win_amd64.dll.a +0 -0
  535. scipy/spatial/_distance_pybind.cp313-win_amd64.pyd +0 -0
  536. scipy/spatial/_distance_wrap.cp313-win_amd64.dll.a +0 -0
  537. scipy/spatial/_distance_wrap.cp313-win_amd64.pyd +0 -0
  538. scipy/spatial/_hausdorff.cp313-win_amd64.dll.a +0 -0
  539. scipy/spatial/_hausdorff.cp313-win_amd64.pyd +0 -0
  540. scipy/spatial/_qhull.cp313-win_amd64.dll.a +0 -0
  541. scipy/spatial/_qhull.cp313-win_amd64.pyd +0 -0
  542. scipy/spatial/_voronoi.cp313-win_amd64.dll.a +0 -0
  543. scipy/spatial/_voronoi.cp313-win_amd64.pyd +0 -0
  544. scipy/spatial/distance.py +49 -42
  545. scipy/spatial/tests/test_distance.py +15 -1
  546. scipy/spatial/tests/test_kdtree.py +1 -0
  547. scipy/spatial/tests/test_qhull.py +7 -2
  548. scipy/spatial/transform/__init__.py +5 -3
  549. scipy/spatial/transform/_rigid_transform.cp313-win_amd64.dll.a +0 -0
  550. scipy/spatial/transform/_rigid_transform.cp313-win_amd64.pyd +0 -0
  551. scipy/spatial/transform/_rotation.cp313-win_amd64.dll.a +0 -0
  552. scipy/spatial/transform/_rotation.cp313-win_amd64.pyd +0 -0
  553. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  554. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  555. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  556. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  557. scipy/special/__init__.py +1 -47
  558. scipy/special/_add_newdocs.py +34 -772
  559. scipy/special/_basic.py +22 -25
  560. scipy/special/_comb.cp313-win_amd64.dll.a +0 -0
  561. scipy/special/_comb.cp313-win_amd64.pyd +0 -0
  562. scipy/special/_ellip_harm_2.cp313-win_amd64.dll.a +0 -0
  563. scipy/special/_ellip_harm_2.cp313-win_amd64.pyd +0 -0
  564. scipy/special/_gufuncs.cp313-win_amd64.dll.a +0 -0
  565. scipy/special/_gufuncs.cp313-win_amd64.pyd +0 -0
  566. scipy/special/_logsumexp.py +67 -58
  567. scipy/special/_orthogonal.pyi +1 -1
  568. scipy/special/_specfun.cp313-win_amd64.dll.a +0 -0
  569. scipy/special/_specfun.cp313-win_amd64.pyd +0 -0
  570. scipy/special/_special_ufuncs.cp313-win_amd64.dll.a +0 -0
  571. scipy/special/_special_ufuncs.cp313-win_amd64.pyd +0 -0
  572. scipy/special/_spherical_bessel.py +4 -4
  573. scipy/special/_support_alternative_backends.py +212 -119
  574. scipy/special/_test_internal.cp313-win_amd64.dll.a +0 -0
  575. scipy/special/_test_internal.cp313-win_amd64.pyd +0 -0
  576. scipy/special/_testutils.py +4 -4
  577. scipy/special/_ufuncs.cp313-win_amd64.dll.a +0 -0
  578. scipy/special/_ufuncs.cp313-win_amd64.pyd +0 -0
  579. scipy/special/_ufuncs.pyi +1 -0
  580. scipy/special/_ufuncs.pyx +215 -1400
  581. scipy/special/_ufuncs_cxx.cp313-win_amd64.dll.a +0 -0
  582. scipy/special/_ufuncs_cxx.cp313-win_amd64.pyd +0 -0
  583. scipy/special/_ufuncs_cxx.pxd +2 -15
  584. scipy/special/_ufuncs_cxx.pyx +5 -44
  585. scipy/special/_ufuncs_cxx_defs.h +2 -16
  586. scipy/special/_ufuncs_defs.h +0 -8
  587. scipy/special/cython_special.cp313-win_amd64.dll.a +0 -0
  588. scipy/special/cython_special.cp313-win_amd64.pyd +0 -0
  589. scipy/special/cython_special.pxd +1 -1
  590. scipy/special/tests/_cython_examples/meson.build +10 -1
  591. scipy/special/tests/test_basic.py +153 -20
  592. scipy/special/tests/test_boost_ufuncs.py +3 -0
  593. scipy/special/tests/test_cdflib.py +35 -11
  594. scipy/special/tests/test_gammainc.py +16 -0
  595. scipy/special/tests/test_hyp2f1.py +2 -2
  596. scipy/special/tests/test_log1mexp.py +85 -0
  597. scipy/special/tests/test_logsumexp.py +206 -64
  598. scipy/special/tests/test_mpmath.py +1 -0
  599. scipy/special/tests/test_nan_inputs.py +1 -1
  600. scipy/special/tests/test_orthogonal.py +17 -18
  601. scipy/special/tests/test_sf_error.py +3 -2
  602. scipy/special/tests/test_sph_harm.py +6 -7
  603. scipy/special/tests/test_support_alternative_backends.py +211 -76
  604. scipy/stats/__init__.py +4 -1
  605. scipy/stats/_ansari_swilk_statistics.cp313-win_amd64.dll.a +0 -0
  606. scipy/stats/_ansari_swilk_statistics.cp313-win_amd64.pyd +0 -0
  607. scipy/stats/_axis_nan_policy.py +5 -12
  608. scipy/stats/_biasedurn.cp313-win_amd64.dll.a +0 -0
  609. scipy/stats/_biasedurn.cp313-win_amd64.pyd +0 -0
  610. scipy/stats/_continued_fraction.py +387 -0
  611. scipy/stats/_continuous_distns.py +277 -310
  612. scipy/stats/_correlation.py +1 -1
  613. scipy/stats/_covariance.py +6 -3
  614. scipy/stats/_discrete_distns.py +39 -32
  615. scipy/stats/_distn_infrastructure.py +39 -12
  616. scipy/stats/_distribution_infrastructure.py +900 -238
  617. scipy/stats/_entropy.py +9 -10
  618. scipy/{_lib → stats}/_finite_differences.py +1 -1
  619. scipy/stats/_hypotests.py +83 -50
  620. scipy/stats/_kde.py +53 -49
  621. scipy/stats/_ksstats.py +1 -1
  622. scipy/stats/_levy_stable/__init__.py +7 -15
  623. scipy/stats/_levy_stable/levyst.cp313-win_amd64.dll.a +0 -0
  624. scipy/stats/_levy_stable/levyst.cp313-win_amd64.pyd +0 -0
  625. scipy/stats/_morestats.py +118 -73
  626. scipy/stats/_mstats_basic.py +13 -17
  627. scipy/stats/_mstats_extras.py +8 -8
  628. scipy/stats/_multivariate.py +89 -113
  629. scipy/stats/_new_distributions.py +97 -20
  630. scipy/stats/_page_trend_test.py +12 -5
  631. scipy/stats/_probability_distribution.py +265 -43
  632. scipy/stats/_qmc.py +14 -9
  633. scipy/stats/_qmc_cy.cp313-win_amd64.dll.a +0 -0
  634. scipy/stats/_qmc_cy.cp313-win_amd64.pyd +0 -0
  635. scipy/stats/_qmvnt.py +16 -95
  636. scipy/stats/_qmvnt_cy.cp313-win_amd64.dll.a +0 -0
  637. scipy/stats/_qmvnt_cy.cp313-win_amd64.pyd +0 -0
  638. scipy/stats/_quantile.py +335 -0
  639. scipy/stats/_rcont/rcont.cp313-win_amd64.dll.a +0 -0
  640. scipy/stats/_rcont/rcont.cp313-win_amd64.pyd +0 -0
  641. scipy/stats/_resampling.py +4 -29
  642. scipy/stats/_sampling.py +1 -1
  643. scipy/stats/_sobol.cp313-win_amd64.dll.a +0 -0
  644. scipy/stats/_sobol.cp313-win_amd64.pyd +0 -0
  645. scipy/stats/_stats.cp313-win_amd64.dll.a +0 -0
  646. scipy/stats/_stats.cp313-win_amd64.pyd +0 -0
  647. scipy/stats/_stats_mstats_common.py +21 -2
  648. scipy/stats/_stats_py.py +550 -476
  649. scipy/stats/_stats_pythran.cp313-win_amd64.dll.a +0 -0
  650. scipy/stats/_stats_pythran.cp313-win_amd64.pyd +0 -0
  651. scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.dll.a +0 -0
  652. scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.pyd +0 -0
  653. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  654. scipy/stats/_variation.py +6 -8
  655. scipy/stats/_wilcoxon.py +13 -7
  656. scipy/stats/tests/common_tests.py +6 -4
  657. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  658. scipy/stats/tests/test_continued_fraction.py +173 -0
  659. scipy/stats/tests/test_continuous.py +379 -60
  660. scipy/stats/tests/test_continuous_basic.py +18 -12
  661. scipy/stats/tests/test_discrete_basic.py +14 -8
  662. scipy/stats/tests/test_discrete_distns.py +16 -16
  663. scipy/stats/tests/test_distributions.py +95 -75
  664. scipy/stats/tests/test_entropy.py +40 -48
  665. scipy/stats/tests/test_fit.py +4 -3
  666. scipy/stats/tests/test_hypotests.py +153 -24
  667. scipy/stats/tests/test_kdeoth.py +109 -41
  668. scipy/stats/tests/test_marray.py +289 -0
  669. scipy/stats/tests/test_morestats.py +79 -47
  670. scipy/stats/tests/test_mstats_basic.py +3 -3
  671. scipy/stats/tests/test_multivariate.py +434 -83
  672. scipy/stats/tests/test_qmc.py +13 -10
  673. scipy/stats/tests/test_quantile.py +199 -0
  674. scipy/stats/tests/test_rank.py +119 -112
  675. scipy/stats/tests/test_resampling.py +47 -56
  676. scipy/stats/tests/test_sampling.py +9 -4
  677. scipy/stats/tests/test_stats.py +799 -939
  678. scipy/stats/tests/test_variation.py +8 -6
  679. scipy/version.py +2 -2
  680. scipy-1.16.0rc2.dist-info/DELVEWHEEL +2 -0
  681. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  682. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  683. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +685 -693
  684. scipy/_lib/array_api_extra/_funcs.py +0 -484
  685. scipy/_lib/array_api_extra/_typing.py +0 -8
  686. scipy/interpolate/_bspl.cp313-win_amd64.dll.a +0 -0
  687. scipy/interpolate/_bspl.cp313-win_amd64.pyd +0 -0
  688. scipy/optimize/_cobyla.cp313-win_amd64.dll.a +0 -0
  689. scipy/optimize/_cobyla.cp313-win_amd64.pyd +0 -0
  690. scipy/optimize/_cython_nnls.cp313-win_amd64.dll.a +0 -0
  691. scipy/optimize/_cython_nnls.cp313-win_amd64.pyd +0 -0
  692. scipy/optimize/_slsqp.cp313-win_amd64.dll.a +0 -0
  693. scipy/optimize/_slsqp.cp313-win_amd64.pyd +0 -0
  694. scipy/spatial/qhull_src/COPYING.txt +0 -38
  695. scipy/special/libsf_error_state.dll +0 -0
  696. scipy/special/libsf_error_state.dll.a +0 -0
  697. scipy/special/tests/test_log_softmax.py +0 -109
  698. scipy/special/tests/test_xsf_cuda.py +0 -114
  699. scipy/special/xsf/binom.h +0 -89
  700. scipy/special/xsf/cdflib.h +0 -100
  701. scipy/special/xsf/cephes/airy.h +0 -307
  702. scipy/special/xsf/cephes/besselpoly.h +0 -51
  703. scipy/special/xsf/cephes/beta.h +0 -257
  704. scipy/special/xsf/cephes/cbrt.h +0 -131
  705. scipy/special/xsf/cephes/chbevl.h +0 -85
  706. scipy/special/xsf/cephes/chdtr.h +0 -193
  707. scipy/special/xsf/cephes/const.h +0 -87
  708. scipy/special/xsf/cephes/ellie.h +0 -293
  709. scipy/special/xsf/cephes/ellik.h +0 -251
  710. scipy/special/xsf/cephes/ellpe.h +0 -107
  711. scipy/special/xsf/cephes/ellpk.h +0 -117
  712. scipy/special/xsf/cephes/expn.h +0 -260
  713. scipy/special/xsf/cephes/gamma.h +0 -398
  714. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  715. scipy/special/xsf/cephes/hyperg.h +0 -361
  716. scipy/special/xsf/cephes/i0.h +0 -149
  717. scipy/special/xsf/cephes/i1.h +0 -158
  718. scipy/special/xsf/cephes/igam.h +0 -421
  719. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  720. scipy/special/xsf/cephes/igami.h +0 -313
  721. scipy/special/xsf/cephes/j0.h +0 -225
  722. scipy/special/xsf/cephes/j1.h +0 -198
  723. scipy/special/xsf/cephes/jv.h +0 -715
  724. scipy/special/xsf/cephes/k0.h +0 -164
  725. scipy/special/xsf/cephes/k1.h +0 -163
  726. scipy/special/xsf/cephes/kn.h +0 -243
  727. scipy/special/xsf/cephes/lanczos.h +0 -112
  728. scipy/special/xsf/cephes/ndtr.h +0 -275
  729. scipy/special/xsf/cephes/poch.h +0 -85
  730. scipy/special/xsf/cephes/polevl.h +0 -167
  731. scipy/special/xsf/cephes/psi.h +0 -194
  732. scipy/special/xsf/cephes/rgamma.h +0 -111
  733. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  734. scipy/special/xsf/cephes/shichi.h +0 -248
  735. scipy/special/xsf/cephes/sici.h +0 -224
  736. scipy/special/xsf/cephes/sindg.h +0 -221
  737. scipy/special/xsf/cephes/tandg.h +0 -139
  738. scipy/special/xsf/cephes/trig.h +0 -58
  739. scipy/special/xsf/cephes/unity.h +0 -186
  740. scipy/special/xsf/cephes/zeta.h +0 -172
  741. scipy/special/xsf/config.h +0 -304
  742. scipy/special/xsf/digamma.h +0 -205
  743. scipy/special/xsf/error.h +0 -57
  744. scipy/special/xsf/evalpoly.h +0 -47
  745. scipy/special/xsf/expint.h +0 -266
  746. scipy/special/xsf/hyp2f1.h +0 -694
  747. scipy/special/xsf/iv_ratio.h +0 -173
  748. scipy/special/xsf/lambertw.h +0 -150
  749. scipy/special/xsf/loggamma.h +0 -163
  750. scipy/special/xsf/sici.h +0 -200
  751. scipy/special/xsf/tools.h +0 -427
  752. scipy/special/xsf/trig.h +0 -164
  753. scipy/special/xsf/wright_bessel.h +0 -843
  754. scipy/special/xsf/zlog1.h +0 -35
  755. scipy/stats/_mvn.cp313-win_amd64.dll.a +0 -0
  756. scipy/stats/_mvn.cp313-win_amd64.pyd +0 -0
  757. scipy-1.15.3.dist-info/DELVEWHEEL +0 -2
  758. /scipy-1.15.3-cp313-cp313-win_amd64.whl → /scipy-1.16.0rc2-cp313-cp313-win_amd64.whl +0 -0
  759. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
scipy/ndimage/_filters.py CHANGED
@@ -33,8 +33,10 @@ import numbers
33
33
  import warnings
34
34
  import numpy as np
35
35
  import operator
36
+ import math
36
37
 
37
38
  from scipy._lib._util import normalize_axis_index
39
+ from scipy._lib._array_api import array_namespace, is_cupy, xp_size
38
40
  from . import _ni_support
39
41
  from . import _nd_image
40
42
  from . import _ni_docstrings
@@ -47,7 +49,433 @@ __all__ = ['correlate1d', 'convolve1d', 'gaussian_filter1d', 'gaussian_filter',
47
49
  'uniform_filter1d', 'uniform_filter', 'minimum_filter1d',
48
50
  'maximum_filter1d', 'minimum_filter', 'maximum_filter',
49
51
  'rank_filter', 'median_filter', 'percentile_filter',
50
- 'generic_filter1d', 'generic_filter']
52
+ 'generic_filter1d', 'generic_filter', 'vectorized_filter']
53
+
54
+
55
+ def _vectorized_filter_iv(input, function, size, footprint, output, mode, cval, origin,
56
+ axes, batch_memory):
57
+ xp = array_namespace(input, footprint, output)
58
+
59
+ # vectorized_filter input validation and standardization
60
+ input = xp.asarray(input)
61
+
62
+ if not callable(function):
63
+ raise ValueError("`function` must be a callable.")
64
+
65
+ if size is None and footprint is None:
66
+ raise ValueError("Either `size` or `footprint` must be provided.")
67
+
68
+ if size is not None and footprint is not None:
69
+ raise ValueError("Either `size` or `footprint` may be provided, not both.")
70
+
71
+ if axes is None:
72
+ axes = tuple(range(-input.ndim, 0))
73
+ elif np.isscalar(axes):
74
+ axes = (axes,)
75
+ n_axes = len(axes)
76
+ n_batch = input.ndim - n_axes
77
+
78
+ if n_axes > input.ndim:
79
+ message = ("The length of `axes` may not exceed the dimensionality of `input`"
80
+ "(`input.ndim`).")
81
+ raise ValueError(message)
82
+
83
+ # Either footprint or size must be provided
84
+ footprinted_function = function
85
+ if size is not None:
86
+ # If provided, size must be an integer or tuple of integers.
87
+ size = (size,)*n_axes if np.isscalar(size) else tuple(size)
88
+ valid = [xp.isdtype(xp.asarray(i).dtype, 'integral') and i > 0 for i in size]
89
+ if not all(valid):
90
+ raise ValueError("All elements of `size` must be positive integers.")
91
+ else:
92
+ # If provided, `footprint` must be array-like
93
+ footprint = xp.asarray(footprint, dtype=xp.bool)
94
+ size = footprint.shape
95
+ def footprinted_function(input, *args, axis=-1, **kwargs):
96
+ return function(input[..., footprint], *args, axis=-1, **kwargs)
97
+
98
+ # And by now, the dimensionality of the footprint must equal the number of axes
99
+ if n_axes != len(size):
100
+ message = ("`axes` must be compatible with the dimensionality "
101
+ "of the window specified by `size` or `footprint`.")
102
+ raise ValueError(message)
103
+
104
+ # If this is not *equal* to the dimensionality of `input`, then `axes`
105
+ # must be a provided tuple, and its length must equal the core dimensionality.
106
+ elif n_axes < input.ndim:
107
+ if axes is None:
108
+ message = ("`axes` must be provided if the dimensionality of the window "
109
+ "(`len(size)` or `footprint.ndim`) does not equal the number "
110
+ "of axes of `input` (`input.ndim`).")
111
+ raise ValueError(message)
112
+ else:
113
+ axes = tuple(range(-n_axes, 0)) if axes is None else axes
114
+
115
+ axes = (axes,) if np.isscalar(axes) else axes
116
+
117
+ # If `origin` is provided, then it must be "broadcastable" to a tuple with length
118
+ # equal to the core dimensionality.
119
+ if origin is None:
120
+ origin = (0,) * n_axes
121
+ else:
122
+ origin = (origin,)*n_axes if np.isscalar(origin) else tuple(origin)
123
+ integral = [xp.isdtype(xp.asarray(i).dtype, 'integral') for i in origin]
124
+ if not all(integral):
125
+ raise ValueError("All elements of `origin` must be integers.")
126
+ if not len(origin) == n_axes:
127
+ message = ("`origin` must be an integer or tuple of integers with length "
128
+ "equal to the number of axes.")
129
+ raise ValueError(message)
130
+
131
+ # mode must be one of the allowed strings, and we should convert it to the
132
+ # value required by `np.pad`/`cp.pad` here.
133
+ valid_modes = {'reflect', 'constant', 'nearest', 'mirror', 'wrap',
134
+ 'grid-mirror', 'grid-constant', 'grid-wrap', 'valid'}
135
+ if mode not in valid_modes:
136
+ raise ValueError(f"`mode` must be one of {valid_modes}.")
137
+ mode_map = {'nearest': 'edge', 'reflect': 'symmetric', 'mirror': 'reflect',
138
+ 'grid-mirror': 'reflect', 'grid-constant': 'constant',
139
+ 'grid-wrap': 'wrap'}
140
+ mode = mode_map.get(mode, mode)
141
+
142
+ if mode == 'valid' and any(origin):
143
+ raise ValueError("`mode='valid'` is incompatible with use of `origin`.")
144
+
145
+ if cval is None:
146
+ cval = 0.0
147
+ elif mode != 'constant':
148
+ raise ValueError("Use of `cval` is compatible only with `mode='constant'`.")
149
+
150
+ # `cval` must be a scalar or "broadcastable" to a tuple with the same
151
+ # dimensionality of `input`. (Full input validation done by `np.pad`/`cp.pad`.)
152
+ if not xp.isdtype(xp.asarray(cval).dtype, 'numeric'):
153
+ raise ValueError("`cval` must include only numbers.")
154
+
155
+ # `batch_memory` must be a positive number.
156
+ temp = xp.asarray(batch_memory)
157
+ if temp.ndim != 0 or (not xp.isdtype(temp.dtype, 'numeric')) or temp <= 0:
158
+ raise ValueError("`batch_memory` must be positive number.")
159
+
160
+ # For simplicity, work with `axes` at the end.
161
+ working_axes = tuple(range(-n_axes, 0))
162
+ input = xp.moveaxis(input, axes, working_axes)
163
+ output = (xp.moveaxis(output, axes, working_axes)
164
+ if output is not None else output)
165
+
166
+ # Wrap the function to limit maximum memory usage, deal with `footprint`,
167
+ # and populate `output`. The latter requires some verbosity because we
168
+ # don't know the output dtype.
169
+ def wrapped_function(view, output=output):
170
+ kwargs = {'axis': working_axes}
171
+
172
+ if working_axes == ():
173
+ return footprinted_function(xp.asarray(view), **kwargs)
174
+
175
+ # for now, assume we only have to iterate over zeroth axis
176
+ chunk_size = math.prod(view.shape[1:]) * view.dtype.itemsize
177
+ slices_per_batch = min(view.shape[0], batch_memory // chunk_size)
178
+ if slices_per_batch < 1:
179
+ raise ValueError("`batch_memory` is insufficient for minimum chunk size.")
180
+
181
+ elif slices_per_batch == view.shape[0]:
182
+ if output is None:
183
+ return footprinted_function(xp.asarray(view), **kwargs)
184
+ else:
185
+ output[...] = footprinted_function(xp.asarray(view), **kwargs)
186
+ return output
187
+
188
+ for i in range(0, view.shape[0], slices_per_batch):
189
+ i2 = min(i + slices_per_batch, view.shape[0])
190
+ if output is None:
191
+ # Look at the dtype before allocating the array. (In a follow-up, we
192
+ # can also look at the shape to support non-scalar elements.)
193
+ temp = footprinted_function(xp.asarray(view[i:i2]), **kwargs)
194
+ output = xp.empty(view.shape[:-n_axes], dtype=temp.dtype)
195
+ output[i:i2, ...] = temp
196
+ else:
197
+ output[i:i2, ...] = footprinted_function(xp.asarray(view[i:i2]),
198
+ **kwargs)
199
+ return output
200
+
201
+ return (input, wrapped_function, size, mode, cval, origin,
202
+ working_axes, axes, n_axes, n_batch, xp)
203
+
204
+
205
+ @_ni_docstrings.docfiller
206
+ def vectorized_filter(input, function, *, size=None, footprint=None, output=None,
207
+ mode='reflect', cval=None, origin=None, axes=None,
208
+ batch_memory=2**30):
209
+ """Filter an array with a vectorized Python callable as the kernel
210
+
211
+ Parameters
212
+ ----------
213
+ %(input)s
214
+ function : callable
215
+ Kernel to apply over a window centered at each element of `input`.
216
+ Callable must have signature::
217
+
218
+ function(window: ndarray, *, axis: int | tuple) -> scalar
219
+
220
+ where ``axis`` specifies the axis (or axes) of ``window`` along which
221
+ the filter function is evaluated.
222
+ size : scalar or tuple, optional
223
+ See `footprint` below. Ignored if `footprint` is given.
224
+ footprint : array, optional
225
+ Either `size` or `footprint` must be defined. `size` gives
226
+ the shape that is taken from the input array, at every element
227
+ position, to define the input to the filter function.
228
+ `footprint` is a boolean array that specifies (implicitly) a
229
+ shape, but also which of the elements within this shape will get
230
+ passed to the filter function. Thus ``size=(n, m)`` is equivalent
231
+ to ``footprint=np.ones((n, m))``.
232
+ We adjust `size` to the number of dimensions indicated by `axes`.
233
+ For instance, if `axes` is ``(0, 2, 1)`` and ``n`` is passed for ``size``,
234
+ then the effective `size` is ``(n, n, n)``.
235
+ %(output)s
236
+ mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
237
+ The `mode` parameter determines how the input array is extended
238
+ beyond its boundaries. Default is 'reflect'. Behavior for each valid
239
+ value is as follows:
240
+
241
+ 'reflect' (`d c b a | a b c d | d c b a`)
242
+ The input is extended by reflecting about the edge of the last
243
+ pixel. This mode is also sometimes referred to as half-sample
244
+ symmetric.
245
+
246
+ 'constant' (`k k k k | a b c d | k k k k`)
247
+ The input is extended by filling all values beyond the edge with
248
+ the same constant value, defined by the `cval` parameter.
249
+
250
+ 'nearest' (`a a a a | a b c d | d d d d`)
251
+ The input is extended by replicating the last pixel.
252
+
253
+ 'mirror' (`d c b | a b c d | c b a`)
254
+ The input is extended by reflecting about the center of the last
255
+ pixel. This mode is also sometimes referred to as whole-sample
256
+ symmetric.
257
+
258
+ 'wrap' (`a b c d | a b c d | a b c d`)
259
+ The input is extended by wrapping around to the opposite edge.
260
+
261
+ 'valid' (`| a b c d |`)
262
+ The input is not extended; rather, the output shape is reduced depending
263
+ on the window size according to the following calculation::
264
+
265
+ window_size = np.asarray(size if size is not None else footprint.shape)
266
+ output_shape = np.asarray(input.shape)
267
+ output_shape[np.asarray(axes)] -= (window_size - 1)
268
+
269
+ %(cval)s
270
+ %(origin_multiple)s
271
+ axes : tuple of int, optional
272
+ If None, `input` is filtered along all axes. Otherwise, `input` is filtered
273
+ along the specified axes. When `axes` is specified, the dimensionality of
274
+ `footprint` and the length of any tuples used for `size` or `origin` must
275
+ match the length of `axes`. The ith axis of `footprint` and the ith element
276
+ in these tuples corresponds to the ith element of `axes`.
277
+ batch_memory : int, default: 2**30
278
+ The maximum number of bytes occupied by data in the ``window``
279
+ array passed to ``function``.
280
+
281
+ Returns
282
+ -------
283
+ output : ndarray
284
+ Filtered array. The dtype is the output dtype of `function`. If `function` is
285
+ scalar-valued when applied to a single window, the shape of the output is that
286
+ of `input` (unless ``mode=='valid'``; see `mode` documentation). If `function`
287
+ is multi-valued when applied to a single window, the placement of the
288
+ corresponding dimensions within the output shape depends entirely on the
289
+ behavior of `function`; see Examples.
290
+
291
+ See Also
292
+ --------
293
+ scipy.ndimage.generic_filter
294
+
295
+ Notes
296
+ -----
297
+ This function works by padding `input` according to `mode`, then calling the
298
+ provided `function` on chunks of a sliding window view over the padded array.
299
+ This approach is very simple and flexible, and so the function has many features
300
+ not offered by some other filter functions (e.g. memory control, ``float16``
301
+ and complex dtype support, and any NaN-handling features provided by the
302
+ `function` argument).
303
+
304
+ However, this brute-force approach may perform considerable redundant work.
305
+ Use a specialized filter (e.g. `minimum_filter` instead of this function with
306
+ `numpy.min` as the callable; `uniform_filter` instead of this function with
307
+ `numpy.mean` as the callable) when possible, as it may use a more efficient
308
+ algorithm.
309
+
310
+ When a specialized filter is not available, this function is ideal when `function`
311
+ is a vectorized, pure-Python callable. Even better performance may be possible
312
+ by passing a `scipy.LowLevelCallable` to `generic_filter`. `generic_filter` may
313
+ also be preferred for expensive callables with large filter footprints and
314
+ callables that are not vectorized (i.e. those without ``axis`` support).
315
+
316
+ This function does not provide the ``extra_arguments`` or ``extra_keywords``
317
+ arguments provided by some `ndimage` functions. There are two reasons:
318
+
319
+ - The passthrough functionality can be achieved by the user: simply wrap the
320
+ original callable in another function that provides the required arguments;
321
+ e.g., ``function=lambda input, axis: function(input, *extra_arguments, axis=axis, **extra_keywords)``.
322
+ - There are use cases for `function` to be passed additional *sliding-window data*
323
+ to `function` besides `input`. This is not yet implemented, but we reserve
324
+ these argument names for such a feature, which would add capability rather than
325
+ providing a duplicate interface to existing capability.
326
+
327
+ Examples
328
+ --------
329
+ Suppose we wish to perform a median filter with even window size on a ``float16``
330
+ image. Furthermore, the image has NaNs that we wish to be ignored (and effectively
331
+ removed by the filter). `median_filter` does not support ``float16`` data, its
332
+ behavior when NaNs are present is not defined, and for even window sizes, it does
333
+ not return the usual sample median - the average of the two middle elements. This
334
+ would be an excellent use case for `vectorized_filter` with
335
+ ``function=np.nanmedian``, which supports the required interface: it accepts a
336
+ data array of any shape as the first positional argument, and tuple of axes as
337
+ keyword argument ``axis``.
338
+
339
+ >>> import numpy as np
340
+ >>> from scipy import datasets, ndimage
341
+ >>> from scipy.ndimage import vectorized_filter
342
+ >>> import matplotlib.pyplot as plt
343
+ >>> ascent = ndimage.zoom(datasets.ascent(), 0.5).astype(np.float16)
344
+ >>> ascent[::16, ::16] = np.nan
345
+ >>> result = vectorized_filter(ascent, function=np.nanmedian, size=4)
346
+
347
+ Plot the original and filtered images.
348
+
349
+ >>> fig = plt.figure()
350
+ >>> plt.gray() # show the filtered result in grayscale
351
+ >>> ax1 = fig.add_subplot(121) # left side
352
+ >>> ax2 = fig.add_subplot(122) # right side
353
+ >>> ax1.imshow(ascent)
354
+ >>> ax2.imshow(result)
355
+ >>> fig.tight_layout()
356
+ >>> plt.show()
357
+
358
+ Another need satisfied by `vectorized_filter` is to perform multi-output
359
+ filters. For instance, suppose we wish to filter an image according to the 25th
360
+ and 75th percentiles in addition to the median. We could perform the three
361
+ filters separately.
362
+
363
+ >>> ascent = ndimage.zoom(datasets.ascent(), 0.5)
364
+ >>> def get_quantile_fun(p):
365
+ ... return lambda x, axis: np.quantile(x, p, axis=axis)
366
+ >>> ref1 = vectorized_filter(ascent, get_quantile_fun(0.25), size=4)
367
+ >>> ref2 = vectorized_filter(ascent, get_quantile_fun(0.50), size=4)
368
+ >>> ref3 = vectorized_filter(ascent, get_quantile_fun(0.75), size=4)
369
+ >>> ref = np.stack([ref1, ref2, ref3])
370
+
371
+ However, `vectorized_filter` also supports filters that return multiple outputs
372
+ as long as `output` is unspecified and `batch_memory` is sufficiently high to
373
+ perform the calculation in a single chunk.
374
+
375
+ >>> def quartiles(x, axis):
376
+ ... return np.quantile(x, [0.25, 0.50, 0.75], axis=axis)
377
+ >>> res = vectorized_filter(ascent, quartiles, size=4, batch_memory=np.inf)
378
+ >>> np.all(np.isclose(res, ref))
379
+ np.True_
380
+
381
+ The placement of the additional dimension(s) corresponding with multiple outputs
382
+ is at the discretion of `function`. `quartiles` happens to prepend one dimension
383
+ corresponding with the three outputs simply because that is the behavior of
384
+ `np.quantile`:
385
+
386
+ >>> res.shape == (3,) + ascent.shape
387
+ True
388
+
389
+ If we wished for this dimension to be appended:
390
+
391
+ >>> def quartiles(x, axis):
392
+ ... return np.moveaxis(np.quantile(x, [0.25, 0.50, 0.75], axis=axis), 0, -1)
393
+ >>> res = vectorized_filter(ascent, quartiles, size=4, batch_memory=np.inf)
394
+ >>> res.shape == ascent.shape + (3,)
395
+ True
396
+
397
+ Suppose we wish to implment a "mode" filter - a filter that selects the most
398
+ frequently occuring value within the window. A simple (but rather slow)
399
+ approach is to use `generic_filter` with `scipy.stats.mode`.
400
+
401
+ >>> from scipy import stats
402
+ >>> rng = np.random.default_rng(3195824598724609246)
403
+ >>> input = rng.integers(255, size=(50, 50)).astype(np.uint8)
404
+ >>> def simple_mode(input):
405
+ ... return stats.mode(input, axis=None).mode
406
+ >>> ref = ndimage.generic_filter(input, simple_mode, size=5)
407
+
408
+ If speed is important, `vectorized_filter` can take advantage of the performance
409
+ benefit of a vectorized callable.
410
+
411
+ >>> def vectorized_mode(x, axis=(-1,)):
412
+ ... n_axes = 1 if np.isscalar(axis) else len(axis)
413
+ ... x = np.moveaxis(x, axis, tuple(range(-n_axes, 0)))
414
+ ... x = np.reshape(x, x.shape[:-n_axes] + (-1,))
415
+ ... y = np.sort(x, axis=-1)
416
+ ... i = np.concatenate([np.ones(y.shape[:-1] + (1,), dtype=bool),
417
+ ... y[..., :-1] != y[..., 1:]], axis=-1)
418
+ ... indices = np.arange(y.size)[i.ravel()]
419
+ ... counts = np.diff(indices, append=y.size)
420
+ ... counts = np.reshape(np.repeat(counts, counts), y.shape)
421
+ ... k = np.argmax(counts, axis=-1, keepdims=True)
422
+ ... return np.take_along_axis(y, k, axis=-1)[..., 0]
423
+ >>> res = vectorized_filter(input, vectorized_mode, size=5)
424
+ >>> np.all(res == ref)
425
+ np.True_
426
+
427
+ Depending on the machine, the `vectorized_filter` version may be as much as
428
+ 100x faster.
429
+
430
+ """ # noqa: E501
431
+
432
+ (input, function, size, mode, cval, origin, working_axes, axes, n_axes, n_batch, xp
433
+ ) = _vectorized_filter_iv(input, function, size, footprint, output, mode, cval,
434
+ origin, axes, batch_memory)
435
+
436
+ # `np.pad`/`cp.pad` raises with these sorts of cases, but the best result is
437
+ # probably to return the original array. It could be argued that we should call
438
+ # the function on the empty array with `axis=None` just to determine the output
439
+ # dtype, but I can also see rationale against that.
440
+ if xp_size(input) == 0:
441
+ return xp.asarray(input)
442
+
443
+ # This seems to be defined.
444
+ if input.ndim == 0 and size == ():
445
+ return xp.asarray(function(input) if footprint is None
446
+ else function(input[footprint]))
447
+
448
+ if is_cupy(xp):
449
+ # CuPy is the only GPU backend that has `pad` (with all modes)
450
+ # and `sliding_window_view`. An enhancement would be to use
451
+ # no-copy conversion to CuPy whenever the data is on the GPU.
452
+ cp = xp # let there be no ambiguity!
453
+ swv = cp.lib.stride_tricks.sliding_window_view
454
+ pad = cp.pad
455
+ else:
456
+ # Try to perform no-copy conversion to NumPy for padding and
457
+ # `sliding_window_view`. (If that fails, fine - for now, the only
458
+ # GPU backend we support is CuPy.)
459
+ swv = np.lib.stride_tricks.sliding_window_view
460
+ pad = np.pad
461
+ input = np.asarray(input)
462
+ cval = np.asarray(cval)[()] if mode == 'constant' else None
463
+
464
+ # Border the image according to `mode` and `offset`.
465
+ if mode != 'valid':
466
+ kwargs = {'constant_values': cval} if mode == 'constant' else {}
467
+ borders = tuple((i//2 + j, (i-1)//2 - j) for i, j in zip(size, origin))
468
+ bordered_input = pad(input, ((0, 0),)*n_batch + borders, mode=mode, **kwargs)
469
+ else:
470
+ bordered_input = input
471
+
472
+ # Evaluate function with sliding window view. Function is already wrapped to
473
+ # manage memory, deal with `footprint`, populate `output`, etc.
474
+ view = swv(bordered_input, size, working_axes)
475
+ res = function(view)
476
+
477
+ # move working_axes back to original positions
478
+ return xp.moveaxis(res, working_axes, axes)
51
479
 
52
480
 
53
481
  def _invalid_origin(origin, lenw):
@@ -738,7 +1166,7 @@ def generic_gradient_magnitude(input, derivative, output=None,
738
1166
 
739
1167
  Returns
740
1168
  -------
741
- generic_gradient_matnitude : ndarray
1169
+ generic_gradient_magnitude : ndarray
742
1170
  Filtered array. Has the same shape as `input`.
743
1171
 
744
1172
  """
@@ -1152,6 +1580,8 @@ def uniform_filter(input, size=3, output=None, mode="reflect",
1152
1580
  with a limited precision, the results may be imprecise because
1153
1581
  intermediate results may be stored with insufficient precision.
1154
1582
 
1583
+ %(nan)s
1584
+
1155
1585
  Examples
1156
1586
  --------
1157
1587
  >>> from scipy import ndimage, datasets
@@ -1469,6 +1899,8 @@ def maximum_filter(input, size=None, footprint=None, output=None,
1469
1899
  A sequence of modes (one per axis) is only supported when the footprint is
1470
1900
  separable. Otherwise, a single mode string must be provided.
1471
1901
 
1902
+ %(nan)s
1903
+
1472
1904
  Examples
1473
1905
  --------
1474
1906
  >>> from scipy import ndimage, datasets
@@ -1667,6 +2099,15 @@ def median_filter(input, size=None, footprint=None, output=None,
1667
2099
  the specialised function `scipy.signal.medfilt2d` may be faster. It is
1668
2100
  however limited to constant mode with ``cval=0``.
1669
2101
 
2102
+ The filter always returns the argument that would appear at index ``n // 2`` in
2103
+ a sorted array, where ``n`` is the number of elements in the footprint of the
2104
+ filter. Note that this differs from the conventional definition of the median
2105
+ when ``n`` is even. Also, this function does not support the ``float16`` dtype,
2106
+ behavior in the presence of NaNs is undefined, and memory consumption scales with
2107
+ ``n**4``. For ``float16`` support, greater control over the definition of the
2108
+ filter, and to limit memory usage, consider using `vectorized_filter` with
2109
+ NumPy functions `np.median` or `np.nanmedian`.
2110
+
1670
2111
  Examples
1671
2112
  --------
1672
2113
  >>> from scipy import ndimage, datasets
@@ -1851,13 +2292,20 @@ def generic_filter(input, function, size=None, footprint=None,
1851
2292
 
1852
2293
  Returns
1853
2294
  -------
1854
- generic_filter : ndarray
2295
+ output : ndarray
1855
2296
  Filtered array. Has the same shape as `input`.
1856
2297
 
2298
+ See Also
2299
+ --------
2300
+ vectorized_filter : similar functionality, but optimized for vectorized callables
2301
+
1857
2302
  Notes
1858
2303
  -----
1859
- This function also accepts low-level callback functions with one of
1860
- the following signatures and wrapped in `scipy.LowLevelCallable`:
2304
+ This function is ideal for use with instances of `scipy.LowLevelCallable`;
2305
+ for vectorized, pure-Python callables, consider `vectorized_filter` for improved
2306
+ performance.
2307
+
2308
+ Low-level callback functions must have one of the following signatures:
1861
2309
 
1862
2310
  .. code:: c
1863
2311
 
@@ -33,6 +33,7 @@ import warnings
33
33
 
34
34
  import numpy as np
35
35
  from scipy._lib._util import normalize_axis_index
36
+ from scipy._lib import array_api_extra as xpx
36
37
 
37
38
  from scipy import special
38
39
  from . import _ni_support
@@ -533,6 +534,35 @@ def affine_transform(input, matrix, offset=0.0, output_shape=None,
533
534
  affine_transform : ndarray
534
535
  The transformed input.
535
536
 
537
+ Examples
538
+ --------
539
+ Use `affine_transform` to stretch an image::
540
+
541
+ >>> from scipy.ndimage import affine_transform
542
+ >>> from scipy.datasets import face
543
+ >>> from matplotlib import pyplot as plt
544
+ >>> import numpy as np
545
+ >>> im = face(gray=True)
546
+ >>> matrix = (0.5, 2)
547
+ >>> im2 = affine_transform(im, matrix)
548
+ >>> plt.imshow(im2)
549
+ >>> plt.show()
550
+
551
+ Rotate an image by 90 degrees and project it onto an expanded canvas::
552
+
553
+ >>> matrix = ((0, 1), (1, 0))
554
+ >>> im3 = affine_transform(im, matrix, output_shape=(1024, 1024))
555
+ >>> plt.imshow(im3)
556
+ >>> plt.show()
557
+
558
+ Offset the rotation so that the image is centred::
559
+
560
+ >>> output_shape = (1200, 1200)
561
+ >>> offset = (np.array(im.shape) - output_shape) / 2
562
+ >>> im4 = affine_transform(im, matrix, offset=offset, output_shape=output_shape)
563
+ >>> plt.imshow(im4)
564
+ >>> plt.show()
565
+
536
566
  Notes
537
567
  -----
538
568
  The given matrix and offset are used to find for each point in the
@@ -616,12 +646,6 @@ def affine_transform(input, matrix, offset=0.0, output_shape=None,
616
646
  if not offset.flags.contiguous:
617
647
  offset = offset.copy()
618
648
  if matrix.ndim == 1:
619
- warnings.warn(
620
- "The behavior of affine_transform with a 1-D "
621
- "array supplied for the matrix parameter has changed in "
622
- "SciPy 0.18.0.",
623
- stacklevel=2
624
- )
625
649
  _nd_image.zoom_shift(filtered, matrix, offset/matrix, output, order,
626
650
  mode, cval, npad, False)
627
651
  else:
@@ -818,6 +842,12 @@ def zoom(input, zoom, output=None, order=3, mode='constant', cval=0.0,
818
842
  complex_output = np.iscomplexobj(input)
819
843
  output = _ni_support._get_output(output, input, shape=output_shape,
820
844
  complex_output=complex_output)
845
+ if all(z == 1 for z in zoom) and prefilter: # early exit for gh-20999
846
+ # zoom 1 means "return original image". If `prefilter=False`,
847
+ # `input` is *not* the original image; processing is still needed
848
+ # to undo the filter. So we only early exit if `prefilter`.
849
+ output = xpx.at(output)[...].set(input)
850
+ return output
821
851
  if complex_output:
822
852
  # import under different name to avoid confusion with zoom parameter
823
853
  from scipy.ndimage._interpolation import zoom as _zoom
@@ -630,6 +630,7 @@ def _stats(input, labels=None, index=None, centered=False):
630
630
  if labels is None:
631
631
  return single_group(input)
632
632
 
633
+ labels = np.asarray(labels)
633
634
  # ensure input and labels match sizes
634
635
  input, labels = np.broadcast_arrays(input, labels)
635
636
 
@@ -944,6 +945,7 @@ def _select(input, labels=None, index=None, find_min=False, find_max=False,
944
945
  if labels is None:
945
946
  return single_group(input, positions)
946
947
 
948
+ labels = np.asarray(labels)
947
949
  # ensure input and labels match sizes
948
950
  input, labels = np.broadcast_arrays(input, labels)
949
951
 
@@ -1053,7 +1055,7 @@ def minimum(input, labels=None, index=None):
1053
1055
 
1054
1056
  Returns
1055
1057
  -------
1056
- minimum : float or list of floats
1058
+ output : a scalar or list of integers or floats based on input type.
1057
1059
  List of minima of `input` over the regions determined by `labels` and
1058
1060
  whose index is in `index`. If `index` or `labels` are not specified, a
1059
1061
  float is returned: the minimal value of `input` if `labels` is None,
@@ -1116,7 +1118,7 @@ def maximum(input, labels=None, index=None):
1116
1118
 
1117
1119
  Returns
1118
1120
  -------
1119
- output : float or list of floats
1121
+ output : a scalar or list of integers or floats based on input type.
1120
1122
  List of maxima of `input` over the regions determined by `labels` and
1121
1123
  whose index is in `index`. If `index` or `labels` are not specified, a
1122
1124
  float is returned: the maximal value of `input` if `labels` is None,
@@ -221,6 +221,10 @@ def _binary_erosion(input, structure, iterations, mask, output,
221
221
  raise TypeError('iterations parameter should be an integer') from e
222
222
 
223
223
  input = np.asarray(input)
224
+ # The Cython code can't cope with broadcasted inputs
225
+ if not input.flags.c_contiguous and not input.flags.f_contiguous:
226
+ input = np.ascontiguousarray(input)
227
+
224
228
  ndim = input.ndim
225
229
  if np.iscomplexobj(input):
226
230
  raise TypeError('Complex type not supported')
@@ -1791,6 +1795,7 @@ def morphological_laplace(input, size=None, footprint=None, structure=None,
1791
1795
  Output
1792
1796
 
1793
1797
  """
1798
+ input = np.asarray(input)
1794
1799
  tmp1 = grey_dilation(input, size, footprint, structure, None, mode,
1795
1800
  cval, origin, axes=axes)
1796
1801
  if isinstance(output, np.ndarray):
Binary file
@@ -17,6 +17,9 @@ _output_doc = (
17
17
  The array in which to place the output, or the dtype of the
18
18
  returned array. By default an array of the same dtype as input
19
19
  will be created.""")
20
+ _nan_doc = (
21
+ """The behavior of this function with NaN elements is undefined. To control
22
+ behavior in the presence of NaNs, consider using `vectorized_filter`.""")
20
23
  _size_foot_doc = (
21
24
  """size : scalar or tuple, optional
22
25
  See footprint, below. Ignored if footprint is given.
@@ -204,7 +207,8 @@ docdict = {
204
207
  'origin_multiple': _origin_multiple_doc,
205
208
  'extra_arguments': _extra_arguments_doc,
206
209
  'extra_keywords': _extra_keywords_doc,
207
- 'prefilter': _prefilter_doc
210
+ 'prefilter': _prefilter_doc,
211
+ 'nan': _nan_doc,
208
212
  }
209
213
 
210
214
  docfiller: Final = doccer.filldoc(docdict)
Binary file
@@ -84,7 +84,7 @@ def _get_output(output, input, shape=None, complex_output=False):
84
84
  else:
85
85
  complex_type = np.promote_types(input.dtype, np.complex64)
86
86
  output = np.zeros(shape, dtype=complex_type)
87
- elif isinstance(output, (type, np.dtype)):
87
+ elif isinstance(output, type | np.dtype):
88
88
  # Classes (like `np.float32`) and dtypes are interpreted as dtype
89
89
  if complex_output and np.dtype(output).kind != 'c':
90
90
  warnings.warn("promoting specified output dtype to complex", stacklevel=3)
@@ -137,7 +137,3 @@ def _skip_if_dtype(arg):
137
137
  return None if issubclass(arg, np.generic) else arg
138
138
  else:
139
139
  return None if isinstance(arg, np.dtype) else arg
140
-
141
-
142
- def _skip_if_int(arg):
143
- return None if (arg is None or isinstance(arg, int)) else arg