scipy 1.15.2__cp313-cp313t-macosx_14_0_arm64.whl → 1.16.0rc1__cp313-cp313t-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. scipy/__config__.py +3 -3
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313t-darwin.so +0 -0
  4. scipy/_lib/_array_api.py +497 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-313t-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_ccallback.cpython-313t-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_call.cpython-313t-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-313t-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-313t-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +169 -34
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-313t-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-313t-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +263 -157
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-313t-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-313t-darwin.so +0 -0
  126. scipy/integrate/_ivp/common.py +3 -3
  127. scipy/integrate/_ivp/ivp.py +9 -2
  128. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  129. scipy/integrate/_lsoda.cpython-313t-darwin.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-313t-darwin.so +0 -0
  134. scipy/integrate/_quadpack_py.py +11 -7
  135. scipy/integrate/_quadrature.py +3 -3
  136. scipy/integrate/_rules/_base.py +2 -2
  137. scipy/integrate/_tanhsinh.py +57 -54
  138. scipy/integrate/_test_odeint_banded.cpython-313t-darwin.so +0 -0
  139. scipy/integrate/_vode.cpython-313t-darwin.so +0 -0
  140. scipy/integrate/tests/test__quad_vec.py +0 -6
  141. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  142. scipy/integrate/tests/test_cubature.py +21 -35
  143. scipy/integrate/tests/test_quadrature.py +6 -8
  144. scipy/integrate/tests/test_tanhsinh.py +61 -43
  145. scipy/interpolate/__init__.py +70 -58
  146. scipy/interpolate/_bary_rational.py +22 -22
  147. scipy/interpolate/_bsplines.py +119 -66
  148. scipy/interpolate/_cubic.py +65 -50
  149. scipy/interpolate/_dfitpack.cpython-313t-darwin.so +0 -0
  150. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  151. scipy/interpolate/_fitpack.cpython-313t-darwin.so +0 -0
  152. scipy/interpolate/_fitpack2.py +9 -6
  153. scipy/interpolate/_fitpack_impl.py +32 -26
  154. scipy/interpolate/_fitpack_repro.py +23 -19
  155. scipy/interpolate/_interpnd.cpython-313t-darwin.so +0 -0
  156. scipy/interpolate/_interpolate.py +30 -12
  157. scipy/interpolate/_ndbspline.py +13 -18
  158. scipy/interpolate/_ndgriddata.py +5 -8
  159. scipy/interpolate/_polyint.py +95 -31
  160. scipy/interpolate/_ppoly.cpython-313t-darwin.so +0 -0
  161. scipy/interpolate/_rbf.py +2 -2
  162. scipy/interpolate/_rbfinterp.py +1 -1
  163. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  164. scipy/interpolate/_rgi.py +31 -26
  165. scipy/interpolate/_rgi_cython.cpython-313t-darwin.so +0 -0
  166. scipy/interpolate/dfitpack.py +0 -20
  167. scipy/interpolate/interpnd.py +1 -2
  168. scipy/interpolate/tests/test_bary_rational.py +2 -2
  169. scipy/interpolate/tests/test_bsplines.py +97 -1
  170. scipy/interpolate/tests/test_fitpack2.py +39 -1
  171. scipy/interpolate/tests/test_interpnd.py +32 -20
  172. scipy/interpolate/tests/test_interpolate.py +48 -4
  173. scipy/interpolate/tests/test_rgi.py +2 -1
  174. scipy/io/_fast_matrix_market/__init__.py +2 -0
  175. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  176. scipy/io/_harwell_boeing/hb.py +7 -11
  177. scipy/io/_idl.py +5 -7
  178. scipy/io/_netcdf.py +15 -5
  179. scipy/io/_test_fortran.cpython-313t-darwin.so +0 -0
  180. scipy/io/arff/tests/test_arffread.py +3 -3
  181. scipy/io/matlab/__init__.py +5 -3
  182. scipy/io/matlab/_mio.py +4 -1
  183. scipy/io/matlab/_mio5.py +19 -13
  184. scipy/io/matlab/_mio5_utils.cpython-313t-darwin.so +0 -0
  185. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  186. scipy/io/matlab/_miobase.py +4 -1
  187. scipy/io/matlab/_streams.cpython-313t-darwin.so +0 -0
  188. scipy/io/matlab/tests/test_mio.py +46 -18
  189. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  190. scipy/io/tests/test_mmio.py +7 -1
  191. scipy/io/tests/test_wavfile.py +41 -0
  192. scipy/io/wavfile.py +57 -10
  193. scipy/linalg/_basic.py +113 -86
  194. scipy/linalg/_cythonized_array_utils.cpython-313t-darwin.so +0 -0
  195. scipy/linalg/_decomp.py +22 -9
  196. scipy/linalg/_decomp_cholesky.py +28 -13
  197. scipy/linalg/_decomp_cossin.py +45 -30
  198. scipy/linalg/_decomp_interpolative.cpython-313t-darwin.so +0 -0
  199. scipy/linalg/_decomp_ldl.py +4 -1
  200. scipy/linalg/_decomp_lu.py +18 -6
  201. scipy/linalg/_decomp_lu_cython.cpython-313t-darwin.so +0 -0
  202. scipy/linalg/_decomp_polar.py +2 -0
  203. scipy/linalg/_decomp_qr.py +6 -2
  204. scipy/linalg/_decomp_qz.py +3 -0
  205. scipy/linalg/_decomp_schur.py +3 -1
  206. scipy/linalg/_decomp_svd.py +13 -2
  207. scipy/linalg/_decomp_update.cpython-313t-darwin.so +0 -0
  208. scipy/linalg/_expm_frechet.py +4 -0
  209. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  210. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  211. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  212. scipy/linalg/_matfuncs.py +187 -4
  213. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  214. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  216. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  217. scipy/linalg/_procrustes.py +2 -0
  218. scipy/linalg/_sketches.py +17 -6
  219. scipy/linalg/_solve_toeplitz.cpython-313t-darwin.so +0 -0
  220. scipy/linalg/_solvers.py +7 -2
  221. scipy/linalg/_special_matrices.py +26 -36
  222. scipy/linalg/cython_blas.cpython-313t-darwin.so +0 -0
  223. scipy/linalg/cython_lapack.cpython-313t-darwin.so +0 -0
  224. scipy/linalg/lapack.py +22 -2
  225. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  226. scipy/linalg/tests/test_basic.py +31 -16
  227. scipy/linalg/tests/test_batch.py +588 -0
  228. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  229. scipy/linalg/tests/test_decomp.py +40 -3
  230. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  231. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  232. scipy/linalg/tests/test_interpolative.py +17 -0
  233. scipy/linalg/tests/test_lapack.py +115 -7
  234. scipy/linalg/tests/test_matfuncs.py +157 -102
  235. scipy/linalg/tests/test_procrustes.py +0 -7
  236. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  237. scipy/linalg/tests/test_special_matrices.py +1 -5
  238. scipy/ndimage/__init__.py +1 -0
  239. scipy/ndimage/_cytest.cpython-313t-darwin.so +0 -0
  240. scipy/ndimage/_delegators.py +8 -2
  241. scipy/ndimage/_filters.py +433 -5
  242. scipy/ndimage/_interpolation.py +36 -6
  243. scipy/ndimage/_measurements.py +4 -2
  244. scipy/ndimage/_morphology.py +5 -0
  245. scipy/ndimage/_nd_image.cpython-313t-darwin.so +0 -0
  246. scipy/ndimage/_ndimage_api.py +2 -1
  247. scipy/ndimage/_ni_docstrings.py +5 -1
  248. scipy/ndimage/_ni_label.cpython-313t-darwin.so +0 -0
  249. scipy/ndimage/_ni_support.py +1 -5
  250. scipy/ndimage/_rank_filter_1d.cpython-313t-darwin.so +0 -0
  251. scipy/ndimage/_support_alternative_backends.py +18 -6
  252. scipy/ndimage/tests/test_filters.py +351 -259
  253. scipy/ndimage/tests/test_fourier.py +7 -9
  254. scipy/ndimage/tests/test_interpolation.py +68 -61
  255. scipy/ndimage/tests/test_measurements.py +18 -35
  256. scipy/ndimage/tests/test_morphology.py +143 -131
  257. scipy/ndimage/tests/test_splines.py +1 -3
  258. scipy/odr/__odrpack.cpython-313t-darwin.so +0 -0
  259. scipy/optimize/_basinhopping.py +13 -7
  260. scipy/optimize/_bglu_dense.cpython-313t-darwin.so +0 -0
  261. scipy/optimize/_bracket.py +46 -26
  262. scipy/optimize/_chandrupatla.py +9 -10
  263. scipy/optimize/_cobyla_py.py +104 -123
  264. scipy/optimize/_constraints.py +14 -10
  265. scipy/optimize/_differentiable_functions.py +371 -230
  266. scipy/optimize/_differentialevolution.py +4 -3
  267. scipy/optimize/_direct.cpython-313t-darwin.so +0 -0
  268. scipy/optimize/_dual_annealing.py +1 -1
  269. scipy/optimize/_elementwise.py +1 -4
  270. scipy/optimize/_group_columns.cpython-313t-darwin.so +0 -0
  271. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  272. scipy/optimize/_lbfgsb.cpython-313t-darwin.so +0 -0
  273. scipy/optimize/_lbfgsb_py.py +57 -16
  274. scipy/optimize/_linprog_doc.py +2 -2
  275. scipy/optimize/_linprog_highs.py +11 -11
  276. scipy/optimize/_linprog_ip.py +25 -10
  277. scipy/optimize/_linprog_util.py +18 -19
  278. scipy/optimize/_lsap.cpython-313t-darwin.so +0 -0
  279. scipy/optimize/_lsq/common.py +3 -3
  280. scipy/optimize/_lsq/dogbox.py +16 -2
  281. scipy/optimize/_lsq/givens_elimination.cpython-313t-darwin.so +0 -0
  282. scipy/optimize/_lsq/least_squares.py +198 -126
  283. scipy/optimize/_lsq/lsq_linear.py +6 -6
  284. scipy/optimize/_lsq/trf.py +35 -8
  285. scipy/optimize/_milp.py +3 -1
  286. scipy/optimize/_minimize.py +105 -36
  287. scipy/optimize/_minpack.cpython-313t-darwin.so +0 -0
  288. scipy/optimize/_minpack_py.py +21 -14
  289. scipy/optimize/_moduleTNC.cpython-313t-darwin.so +0 -0
  290. scipy/optimize/_nnls.py +20 -21
  291. scipy/optimize/_nonlin.py +34 -3
  292. scipy/optimize/_numdiff.py +288 -110
  293. scipy/optimize/_optimize.py +86 -48
  294. scipy/optimize/_pava_pybind.cpython-313t-darwin.so +0 -0
  295. scipy/optimize/_remove_redundancy.py +5 -5
  296. scipy/optimize/_root_scalar.py +1 -1
  297. scipy/optimize/_shgo.py +6 -0
  298. scipy/optimize/_shgo_lib/_complex.py +1 -1
  299. scipy/optimize/_slsqp_py.py +216 -124
  300. scipy/optimize/_slsqplib.cpython-313t-darwin.so +0 -0
  301. scipy/optimize/_spectral.py +1 -1
  302. scipy/optimize/_tnc.py +8 -1
  303. scipy/optimize/_trlib/_trlib.cpython-313t-darwin.so +0 -0
  304. scipy/optimize/_trustregion.py +20 -6
  305. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  306. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  307. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  308. scipy/optimize/_trustregion_constr/projections.py +12 -8
  309. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  310. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  311. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  312. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  313. scipy/optimize/_trustregion_exact.py +0 -1
  314. scipy/optimize/_zeros.cpython-313t-darwin.so +0 -0
  315. scipy/optimize/_zeros_py.py +97 -17
  316. scipy/optimize/cython_optimize/_zeros.cpython-313t-darwin.so +0 -0
  317. scipy/optimize/slsqp.py +0 -1
  318. scipy/optimize/tests/test__basinhopping.py +1 -1
  319. scipy/optimize/tests/test__differential_evolution.py +4 -4
  320. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  321. scipy/optimize/tests/test__numdiff.py +66 -22
  322. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  323. scipy/optimize/tests/test__shgo.py +9 -1
  324. scipy/optimize/tests/test_bracket.py +71 -46
  325. scipy/optimize/tests/test_chandrupatla.py +133 -135
  326. scipy/optimize/tests/test_cobyla.py +74 -45
  327. scipy/optimize/tests/test_constraints.py +1 -1
  328. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  329. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  330. scipy/optimize/tests/test_least_squares.py +125 -13
  331. scipy/optimize/tests/test_linear_assignment.py +3 -3
  332. scipy/optimize/tests/test_linprog.py +3 -3
  333. scipy/optimize/tests/test_lsq_linear.py +5 -5
  334. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  335. scipy/optimize/tests/test_minpack.py +4 -4
  336. scipy/optimize/tests/test_nnls.py +43 -3
  337. scipy/optimize/tests/test_nonlin.py +36 -0
  338. scipy/optimize/tests/test_optimize.py +95 -17
  339. scipy/optimize/tests/test_slsqp.py +36 -4
  340. scipy/optimize/tests/test_zeros.py +34 -1
  341. scipy/signal/__init__.py +12 -23
  342. scipy/signal/_delegators.py +568 -0
  343. scipy/signal/_filter_design.py +459 -241
  344. scipy/signal/_fir_filter_design.py +262 -90
  345. scipy/signal/_lti_conversion.py +3 -2
  346. scipy/signal/_ltisys.py +118 -91
  347. scipy/signal/_max_len_seq_inner.cpython-313t-darwin.so +0 -0
  348. scipy/signal/_peak_finding_utils.cpython-313t-darwin.so +0 -0
  349. scipy/signal/_polyutils.py +172 -0
  350. scipy/signal/_short_time_fft.py +553 -76
  351. scipy/signal/_signal_api.py +30 -0
  352. scipy/signal/_signaltools.py +719 -396
  353. scipy/signal/_sigtools.cpython-313t-darwin.so +0 -0
  354. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  355. scipy/signal/_spectral_py.py +221 -50
  356. scipy/signal/_spline.cpython-313t-darwin.so +0 -0
  357. scipy/signal/_spline_filters.py +108 -68
  358. scipy/signal/_support_alternative_backends.py +73 -0
  359. scipy/signal/_upfirdn.py +4 -1
  360. scipy/signal/_upfirdn_apply.cpython-313t-darwin.so +0 -0
  361. scipy/signal/_waveforms.py +2 -11
  362. scipy/signal/_wavelets.py +1 -1
  363. scipy/signal/fir_filter_design.py +1 -0
  364. scipy/signal/spline.py +4 -11
  365. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  366. scipy/signal/tests/test_bsplines.py +114 -79
  367. scipy/signal/tests/test_cont2discrete.py +9 -2
  368. scipy/signal/tests/test_filter_design.py +721 -481
  369. scipy/signal/tests/test_fir_filter_design.py +332 -140
  370. scipy/signal/tests/test_savitzky_golay.py +4 -3
  371. scipy/signal/tests/test_short_time_fft.py +231 -5
  372. scipy/signal/tests/test_signaltools.py +2149 -1348
  373. scipy/signal/tests/test_spectral.py +19 -6
  374. scipy/signal/tests/test_splines.py +161 -96
  375. scipy/signal/tests/test_upfirdn.py +84 -50
  376. scipy/signal/tests/test_waveforms.py +20 -0
  377. scipy/signal/tests/test_windows.py +607 -466
  378. scipy/signal/windows/_windows.py +287 -148
  379. scipy/sparse/__init__.py +23 -4
  380. scipy/sparse/_base.py +269 -120
  381. scipy/sparse/_bsr.py +7 -4
  382. scipy/sparse/_compressed.py +59 -234
  383. scipy/sparse/_construct.py +90 -38
  384. scipy/sparse/_coo.py +115 -181
  385. scipy/sparse/_csc.py +4 -4
  386. scipy/sparse/_csparsetools.cpython-313t-darwin.so +0 -0
  387. scipy/sparse/_csr.py +2 -2
  388. scipy/sparse/_data.py +48 -48
  389. scipy/sparse/_dia.py +105 -21
  390. scipy/sparse/_dok.py +0 -23
  391. scipy/sparse/_index.py +4 -4
  392. scipy/sparse/_matrix.py +23 -0
  393. scipy/sparse/_sparsetools.cpython-313t-darwin.so +0 -0
  394. scipy/sparse/_sputils.py +37 -22
  395. scipy/sparse/base.py +0 -9
  396. scipy/sparse/bsr.py +0 -14
  397. scipy/sparse/compressed.py +0 -23
  398. scipy/sparse/construct.py +0 -6
  399. scipy/sparse/coo.py +0 -14
  400. scipy/sparse/csc.py +0 -3
  401. scipy/sparse/csgraph/_flow.cpython-313t-darwin.so +0 -0
  402. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  403. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  404. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  405. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  406. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  407. scipy/sparse/csgraph/_traversal.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  409. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  410. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  411. scipy/sparse/csr.py +0 -5
  412. scipy/sparse/data.py +1 -6
  413. scipy/sparse/dia.py +0 -7
  414. scipy/sparse/dok.py +0 -10
  415. scipy/sparse/linalg/_dsolve/_superlu.cpython-313t-darwin.so +0 -0
  416. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  417. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  418. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313t-darwin.so +0 -0
  419. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  420. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  421. scipy/sparse/linalg/_expm_multiply.py +8 -3
  422. scipy/sparse/linalg/_interface.py +29 -26
  423. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  424. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  425. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  426. scipy/sparse/linalg/_isolve/minres.py +5 -5
  427. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  428. scipy/sparse/linalg/_isolve/utils.py +2 -8
  429. scipy/sparse/linalg/_matfuncs.py +1 -1
  430. scipy/sparse/linalg/_norm.py +1 -1
  431. scipy/sparse/linalg/_propack/_cpropack.cpython-313t-darwin.so +0 -0
  432. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  433. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  434. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-darwin.so +0 -0
  435. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  436. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  437. scipy/sparse/linalg/tests/test_interface.py +35 -0
  438. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  439. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  440. scipy/sparse/tests/test_base.py +217 -40
  441. scipy/sparse/tests/test_common1d.py +17 -12
  442. scipy/sparse/tests/test_construct.py +1 -1
  443. scipy/sparse/tests/test_coo.py +272 -4
  444. scipy/sparse/tests/test_sparsetools.py +5 -0
  445. scipy/sparse/tests/test_sputils.py +36 -7
  446. scipy/spatial/_ckdtree.cpython-313t-darwin.so +0 -0
  447. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  448. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  449. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  450. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  451. scipy/spatial/_voronoi.cpython-313t-darwin.so +0 -0
  452. scipy/spatial/distance.py +49 -42
  453. scipy/spatial/tests/test_distance.py +3 -1
  454. scipy/spatial/tests/test_kdtree.py +1 -0
  455. scipy/spatial/tests/test_qhull.py +106 -2
  456. scipy/spatial/transform/__init__.py +5 -3
  457. scipy/spatial/transform/_rigid_transform.cpython-313t-darwin.so +0 -0
  458. scipy/spatial/transform/_rotation.cpython-313t-darwin.so +0 -0
  459. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  460. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  461. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  462. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  463. scipy/special/__init__.py +1 -47
  464. scipy/special/_add_newdocs.py +34 -772
  465. scipy/special/_basic.py +22 -25
  466. scipy/special/_comb.cpython-313t-darwin.so +0 -0
  467. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  468. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  469. scipy/special/_logsumexp.py +83 -69
  470. scipy/special/_orthogonal.pyi +1 -1
  471. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  472. scipy/special/_special_ufuncs.cpython-313t-darwin.so +0 -0
  473. scipy/special/_spherical_bessel.py +4 -4
  474. scipy/special/_support_alternative_backends.py +212 -119
  475. scipy/special/_test_internal.cpython-313t-darwin.so +0 -0
  476. scipy/special/_testutils.py +4 -4
  477. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  478. scipy/special/_ufuncs.pyi +1 -0
  479. scipy/special/_ufuncs.pyx +215 -1400
  480. scipy/special/_ufuncs_cxx.cpython-313t-darwin.so +0 -0
  481. scipy/special/_ufuncs_cxx.pxd +2 -15
  482. scipy/special/_ufuncs_cxx.pyx +5 -44
  483. scipy/special/_ufuncs_cxx_defs.h +2 -16
  484. scipy/special/_ufuncs_defs.h +0 -8
  485. scipy/special/cython_special.cpython-313t-darwin.so +0 -0
  486. scipy/special/cython_special.pxd +1 -1
  487. scipy/special/tests/_cython_examples/meson.build +10 -1
  488. scipy/special/tests/test_basic.py +153 -20
  489. scipy/special/tests/test_boost_ufuncs.py +3 -0
  490. scipy/special/tests/test_cdflib.py +35 -11
  491. scipy/special/tests/test_gammainc.py +16 -0
  492. scipy/special/tests/test_hyp2f1.py +23 -2
  493. scipy/special/tests/test_log1mexp.py +85 -0
  494. scipy/special/tests/test_logsumexp.py +220 -64
  495. scipy/special/tests/test_mpmath.py +1 -0
  496. scipy/special/tests/test_nan_inputs.py +1 -1
  497. scipy/special/tests/test_orthogonal.py +17 -18
  498. scipy/special/tests/test_sf_error.py +3 -2
  499. scipy/special/tests/test_sph_harm.py +6 -7
  500. scipy/special/tests/test_support_alternative_backends.py +211 -76
  501. scipy/stats/__init__.py +4 -1
  502. scipy/stats/_ansari_swilk_statistics.cpython-313t-darwin.so +0 -0
  503. scipy/stats/_axis_nan_policy.py +4 -3
  504. scipy/stats/_biasedurn.cpython-313t-darwin.so +0 -0
  505. scipy/stats/_continued_fraction.py +387 -0
  506. scipy/stats/_continuous_distns.py +296 -319
  507. scipy/stats/_covariance.py +6 -3
  508. scipy/stats/_discrete_distns.py +39 -32
  509. scipy/stats/_distn_infrastructure.py +39 -12
  510. scipy/stats/_distribution_infrastructure.py +900 -238
  511. scipy/stats/_entropy.py +7 -8
  512. scipy/{_lib → stats}/_finite_differences.py +1 -1
  513. scipy/stats/_hypotests.py +82 -49
  514. scipy/stats/_kde.py +53 -49
  515. scipy/stats/_ksstats.py +1 -1
  516. scipy/stats/_levy_stable/__init__.py +7 -15
  517. scipy/stats/_levy_stable/levyst.cpython-313t-darwin.so +0 -0
  518. scipy/stats/_morestats.py +112 -67
  519. scipy/stats/_mstats_basic.py +13 -17
  520. scipy/stats/_mstats_extras.py +8 -8
  521. scipy/stats/_multivariate.py +89 -113
  522. scipy/stats/_new_distributions.py +97 -20
  523. scipy/stats/_page_trend_test.py +12 -5
  524. scipy/stats/_probability_distribution.py +265 -43
  525. scipy/stats/_qmc.py +14 -9
  526. scipy/stats/_qmc_cy.cpython-313t-darwin.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  531. scipy/stats/_resampling.py +4 -29
  532. scipy/stats/_sampling.py +1 -1
  533. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  534. scipy/stats/_stats.cpython-313t-darwin.so +0 -0
  535. scipy/stats/_stats_mstats_common.py +19 -2
  536. scipy/stats/_stats_py.py +534 -460
  537. scipy/stats/_stats_pythran.cpython-313t-darwin.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-313t-darwin.so +0 -0
  539. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  540. scipy/stats/_variation.py +5 -7
  541. scipy/stats/_wilcoxon.py +13 -7
  542. scipy/stats/tests/common_tests.py +6 -4
  543. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  544. scipy/stats/tests/test_continued_fraction.py +173 -0
  545. scipy/stats/tests/test_continuous.py +379 -60
  546. scipy/stats/tests/test_continuous_basic.py +18 -12
  547. scipy/stats/tests/test_discrete_basic.py +14 -8
  548. scipy/stats/tests/test_discrete_distns.py +16 -16
  549. scipy/stats/tests/test_distributions.py +117 -75
  550. scipy/stats/tests/test_entropy.py +40 -48
  551. scipy/stats/tests/test_fit.py +4 -3
  552. scipy/stats/tests/test_hypotests.py +153 -24
  553. scipy/stats/tests/test_kdeoth.py +109 -41
  554. scipy/stats/tests/test_marray.py +289 -0
  555. scipy/stats/tests/test_morestats.py +79 -47
  556. scipy/stats/tests/test_mstats_basic.py +3 -3
  557. scipy/stats/tests/test_multivariate.py +434 -83
  558. scipy/stats/tests/test_qmc.py +13 -10
  559. scipy/stats/tests/test_quantile.py +199 -0
  560. scipy/stats/tests/test_rank.py +119 -112
  561. scipy/stats/tests/test_resampling.py +47 -56
  562. scipy/stats/tests/test_sampling.py +9 -4
  563. scipy/stats/tests/test_stats.py +799 -939
  564. scipy/stats/tests/test_variation.py +8 -6
  565. scipy/version.py +2 -2
  566. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  567. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +9 -9
  568. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +569 -576
  569. scipy-1.16.0rc1.dist-info/WHEEL +6 -0
  570. scipy/_lib/array_api_extra/_funcs.py +0 -484
  571. scipy/_lib/array_api_extra/_typing.py +0 -8
  572. scipy/interpolate/_bspl.cpython-313t-darwin.so +0 -0
  573. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  574. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  575. scipy/optimize/_slsqp.cpython-313t-darwin.so +0 -0
  576. scipy/spatial/qhull_src/COPYING.txt +0 -38
  577. scipy/special/libsf_error_state.dylib +0 -0
  578. scipy/special/tests/test_log_softmax.py +0 -109
  579. scipy/special/tests/test_xsf_cuda.py +0 -114
  580. scipy/special/xsf/binom.h +0 -89
  581. scipy/special/xsf/cdflib.h +0 -100
  582. scipy/special/xsf/cephes/airy.h +0 -307
  583. scipy/special/xsf/cephes/besselpoly.h +0 -51
  584. scipy/special/xsf/cephes/beta.h +0 -257
  585. scipy/special/xsf/cephes/cbrt.h +0 -131
  586. scipy/special/xsf/cephes/chbevl.h +0 -85
  587. scipy/special/xsf/cephes/chdtr.h +0 -193
  588. scipy/special/xsf/cephes/const.h +0 -87
  589. scipy/special/xsf/cephes/ellie.h +0 -293
  590. scipy/special/xsf/cephes/ellik.h +0 -251
  591. scipy/special/xsf/cephes/ellpe.h +0 -107
  592. scipy/special/xsf/cephes/ellpk.h +0 -117
  593. scipy/special/xsf/cephes/expn.h +0 -260
  594. scipy/special/xsf/cephes/gamma.h +0 -398
  595. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  596. scipy/special/xsf/cephes/hyperg.h +0 -361
  597. scipy/special/xsf/cephes/i0.h +0 -149
  598. scipy/special/xsf/cephes/i1.h +0 -158
  599. scipy/special/xsf/cephes/igam.h +0 -421
  600. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  601. scipy/special/xsf/cephes/igami.h +0 -313
  602. scipy/special/xsf/cephes/j0.h +0 -225
  603. scipy/special/xsf/cephes/j1.h +0 -198
  604. scipy/special/xsf/cephes/jv.h +0 -715
  605. scipy/special/xsf/cephes/k0.h +0 -164
  606. scipy/special/xsf/cephes/k1.h +0 -163
  607. scipy/special/xsf/cephes/kn.h +0 -243
  608. scipy/special/xsf/cephes/lanczos.h +0 -112
  609. scipy/special/xsf/cephes/ndtr.h +0 -275
  610. scipy/special/xsf/cephes/poch.h +0 -85
  611. scipy/special/xsf/cephes/polevl.h +0 -167
  612. scipy/special/xsf/cephes/psi.h +0 -194
  613. scipy/special/xsf/cephes/rgamma.h +0 -111
  614. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  615. scipy/special/xsf/cephes/shichi.h +0 -248
  616. scipy/special/xsf/cephes/sici.h +0 -224
  617. scipy/special/xsf/cephes/sindg.h +0 -221
  618. scipy/special/xsf/cephes/tandg.h +0 -139
  619. scipy/special/xsf/cephes/trig.h +0 -58
  620. scipy/special/xsf/cephes/unity.h +0 -186
  621. scipy/special/xsf/cephes/zeta.h +0 -172
  622. scipy/special/xsf/config.h +0 -304
  623. scipy/special/xsf/digamma.h +0 -205
  624. scipy/special/xsf/error.h +0 -57
  625. scipy/special/xsf/evalpoly.h +0 -47
  626. scipy/special/xsf/expint.h +0 -266
  627. scipy/special/xsf/hyp2f1.h +0 -694
  628. scipy/special/xsf/iv_ratio.h +0 -173
  629. scipy/special/xsf/lambertw.h +0 -150
  630. scipy/special/xsf/loggamma.h +0 -163
  631. scipy/special/xsf/sici.h +0 -200
  632. scipy/special/xsf/tools.h +0 -427
  633. scipy/special/xsf/trig.h +0 -164
  634. scipy/special/xsf/wright_bessel.h +0 -843
  635. scipy/special/xsf/zlog1.h +0 -35
  636. scipy/stats/_mvn.cpython-313t-darwin.so +0 -0
  637. scipy-1.15.2.dist-info/WHEEL +0 -4
scipy/sparse/_data.py CHANGED
@@ -124,7 +124,7 @@ class _data_matrix(_spbase):
124
124
 
125
125
  data = self._deduped_data()
126
126
  if dtype is not None:
127
- data = data.astype(dtype)
127
+ data = data.astype(dtype, copy=False)
128
128
  return self._with_data(data ** n)
129
129
 
130
130
  ###########################
@@ -172,9 +172,8 @@ class _minmax_mixin:
172
172
  """
173
173
 
174
174
  def _min_or_max_axis(self, axis, min_or_max, explicit):
175
+ # already checked that self.shape[axis] is not zero
175
176
  N = self.shape[axis]
176
- if N == 0:
177
- raise ValueError("zero-size array to reduction operation")
178
177
  M = self.shape[1 - axis]
179
178
  idx_dtype = self._get_index_dtype(maxval=M)
180
179
 
@@ -208,13 +207,9 @@ class _minmax_mixin:
208
207
 
209
208
  def _min_or_max(self, axis, out, min_or_max, explicit):
210
209
  if out is not None:
211
- raise ValueError("Sparse arrays do not support an 'out' parameter.")
210
+ raise ValueError("Sparse min/max does not support an 'out' parameter.")
212
211
 
213
- validateaxis(axis)
214
- if self.ndim == 1:
215
- if axis not in (None, 0, -1):
216
- raise ValueError("axis out of range")
217
- axis = None # avoid calling special axis case. no impact on 1d
212
+ axis = validateaxis(axis, ndim=self.ndim)
218
213
 
219
214
  if axis is None:
220
215
  if 0 in self.shape:
@@ -228,21 +223,15 @@ class _minmax_mixin:
228
223
  m = min_or_max(zero, m)
229
224
  return m
230
225
 
231
- if axis < 0:
232
- axis += 2
233
-
234
- if (axis == 0) or (axis == 1):
235
- return self._min_or_max_axis(axis, min_or_max, explicit)
236
- else:
237
- raise ValueError("axis out of range")
238
-
239
- def _arg_min_or_max_axis(self, axis, argmin_or_argmax, compare, explicit):
240
- if self.shape[axis] == 0:
241
- raise ValueError("Cannot apply the operation along a zero-sized dimension.")
226
+ if any(self.shape[d] == 0 for d in axis):
227
+ raise ValueError("zero-size array to reduction operation")
242
228
 
243
- if axis < 0:
244
- axis += 2
229
+ if self.ndim == 2:
230
+ # note: 2D ensures that len(axis)==1 so we pass in the int axis[0]
231
+ return self._min_or_max_axis(axis[0], min_or_max, explicit)
232
+ return self._min_or_max_axis_nd(axis, min_or_max, explicit)
245
233
 
234
+ def _argminmax_axis(self, axis, argminmax, compare, explicit):
246
235
  zero = self.dtype.type(0)
247
236
 
248
237
  mat = self.tocsc() if axis == 0 else self.tocsr()
@@ -256,7 +245,7 @@ class _minmax_mixin:
256
245
  p, q = mat.indptr[i:i + 2]
257
246
  data = mat.data[p:q]
258
247
  indices = mat.indices[p:q]
259
- extreme_index = argmin_or_argmax(data)
248
+ extreme_index = argminmax(data)
260
249
  extreme_value = data[extreme_index]
261
250
  if explicit:
262
251
  if q - p > 0:
@@ -279,26 +268,31 @@ class _minmax_mixin:
279
268
 
280
269
  return self._ascontainer(ret)
281
270
 
282
- def _arg_min_or_max(self, axis, out, argmin_or_argmax, compare, explicit):
271
+ def _argminmax(self, axis, out, argminmax, compare, explicit):
283
272
  if out is not None:
284
- raise ValueError("Sparse types do not support an 'out' parameter.")
273
+ minmax = "argmin" if argminmax == np.argmin else "argmax"
274
+ raise ValueError(f"Sparse {minmax} does not support an 'out' parameter.")
285
275
 
286
- validateaxis(axis)
287
-
288
- if self.ndim == 1:
289
- if axis not in (None, 0, -1):
290
- raise ValueError("axis out of range")
291
- axis = None # avoid calling special axis case. no impact on 1d
276
+ axis = validateaxis(axis, ndim=self.ndim)
292
277
 
293
278
  if axis is not None:
294
- return self._arg_min_or_max_axis(axis, argmin_or_argmax, compare, explicit)
279
+ if any(self.shape[i] == 0 for i in axis):
280
+ minmax = "argmin" if argminmax == np.argmin else "argmax"
281
+ raise ValueError(f"Cannot apply {minmax} along a zero-sized dimension.")
282
+
283
+ if self.ndim == 2:
284
+ # note: 2D ensures that len(axis)==1 so we pass in the int axis[0]
285
+ return self._argminmax_axis(axis[0], argminmax, compare, explicit)
286
+ return self._argminmax_axis_nd(axis, argminmax, compare, explicit)
295
287
 
296
288
  if 0 in self.shape:
297
- raise ValueError("Cannot apply the operation to an empty matrix.")
289
+ minmax = "argmin" if argminmax == np.argmin else "argmax"
290
+ raise ValueError(f"Cannot apply {minmax} to an empty matrix.")
298
291
 
299
292
  if self.nnz == 0:
300
293
  if explicit:
301
- raise ValueError("Cannot apply the operation to zero matrix "
294
+ minmax = "argmin" if argminmax == np.argmin else "argmax"
295
+ raise ValueError(f"Cannot apply {minmax} to zero matrix "
302
296
  "when explicit=True.")
303
297
  return 0
304
298
 
@@ -306,28 +300,34 @@ class _minmax_mixin:
306
300
  mat = self.tocoo()
307
301
  # Convert to canonical form: no duplicates, sorted indices.
308
302
  mat.sum_duplicates()
309
- extreme_index = argmin_or_argmax(mat.data)
303
+ extreme_index = argminmax(mat.data)
310
304
  if explicit:
311
305
  return extreme_index
312
306
  extreme_value = mat.data[extreme_index]
313
- num_col = mat.shape[-1]
314
307
 
308
+ if mat.ndim > 2:
309
+ mat = mat.reshape(-1)
315
310
  # If the min value is less than zero, or max is greater than zero,
316
311
  # then we do not need to worry about implicit zeros.
317
- if compare(extreme_value, zero):
312
+ # And we use a "cheap test" for the rare case of no implicit zeros.
313
+ maxnnz = math.prod(self.shape)
314
+ if compare(extreme_value, zero) or mat.nnz == maxnnz:
318
315
  # cast to Python int to avoid overflow and RuntimeError
319
- return int(mat.row[extreme_index]) * num_col + int(mat.col[extreme_index])
320
-
321
- # Cheap test for the rare case where we have no implicit zeros.
322
- size = math.prod(self.shape)
323
- if size == mat.nnz:
316
+ if mat.ndim == 1: # includes nD case that was reshaped above
317
+ return int(mat.col[extreme_index])
318
+ # ndim == 2
319
+ num_col = mat.shape[-1]
324
320
  return int(mat.row[extreme_index]) * num_col + int(mat.col[extreme_index])
325
321
 
326
322
  # At this stage, any implicit zero could be the min or max value.
327
323
  # After sum_duplicates(), the `row` and `col` arrays are guaranteed to
328
324
  # be sorted in C-order, which means the linearized indices are sorted.
329
- linear_indices = mat.row * num_col + mat.col
330
- first_implicit_zero_index = _find_missing_index(linear_indices, size)
325
+ if mat.ndim == 1: # includes nD case that was reshaped above
326
+ linear_indices = mat.coords[-1]
327
+ else: # ndim == 2
328
+ num_col = mat.shape[-1]
329
+ linear_indices = mat.row * num_col + mat.col
330
+ first_implicit_zero_index = _find_missing_index(linear_indices, maxnnz)
331
331
  if extreme_value == zero:
332
332
  return min(first_implicit_zero_index, extreme_index)
333
333
  return first_implicit_zero_index
@@ -524,7 +524,7 @@ class _minmax_mixin:
524
524
 
525
525
  explicit : {False, True} optional (default: False)
526
526
  When set to True, only explicitly stored elements will be considered.
527
- If axis is not None and a row/column has no stored elements, argmax
527
+ If axis is not None and an axis has no stored elements, argmax
528
528
  is undefined, so the index ``0`` is returned for that row/column.
529
529
 
530
530
  .. versionadded:: 1.15.0
@@ -534,7 +534,7 @@ class _minmax_mixin:
534
534
  ind : numpy.matrix or int
535
535
  Indices of maximum elements. If matrix, its size along `axis` is 1.
536
536
  """
537
- return self._arg_min_or_max(axis, out, np.argmax, np.greater, explicit)
537
+ return self._argminmax(axis, out, np.argmax, np.greater, explicit)
538
538
 
539
539
  def argmin(self, axis=None, out=None, *, explicit=False):
540
540
  """Return indices of minimum elements along an axis.
@@ -556,7 +556,7 @@ class _minmax_mixin:
556
556
 
557
557
  explicit : {False, True} optional (default: False)
558
558
  When set to True, only explicitly stored elements will be considered.
559
- If axis is not None and a row/column has no stored elements, argmin
559
+ If axis is not None and an axis has no stored elements, argmin
560
560
  is undefined, so the index ``0`` is returned for that row/column.
561
561
 
562
562
  .. versionadded:: 1.15.0
@@ -566,4 +566,4 @@ class _minmax_mixin:
566
566
  ind : numpy.matrix or int
567
567
  Indices of minimum elements. If matrix, its size along `axis` is 1.
568
568
  """
569
- return self._arg_min_or_max(axis, out, np.argmin, np.less, explicit)
569
+ return self._argminmax(axis, out, np.argmin, np.less, explicit)
scipy/sparse/_dia.py CHANGED
@@ -11,9 +11,10 @@ from ._matrix import spmatrix
11
11
  from ._base import issparse, _formats, _spbase, sparray
12
12
  from ._data import _data_matrix
13
13
  from ._sputils import (
14
- isshape, upcast_char, getdtype, get_sum_dtype, validateaxis, check_shape
14
+ isdense, isscalarlike, isshape, upcast_char, getdtype, get_sum_dtype,
15
+ validateaxis, check_shape
15
16
  )
16
- from ._sparsetools import dia_matvec
17
+ from ._sparsetools import dia_matmat, dia_matvec, dia_matvecs
17
18
 
18
19
 
19
20
  class _dia_base(_data_matrix):
@@ -89,10 +90,10 @@ class _dia_base(_data_matrix):
89
90
  raise ValueError('data array must have rank 2')
90
91
 
91
92
  if self.data.shape[0] != len(self.offsets):
92
- raise ValueError('number of diagonals (%d) '
93
- 'does not match the number of offsets (%d)'
94
- % (self.data.shape[0], len(self.offsets)))
95
-
93
+ raise ValueError(
94
+ f'number of diagonals ({self.data.shape[0]}) does not match the number '
95
+ f'of offsets ({len(self.offsets)})'
96
+ )
96
97
  if len(np.unique(self.offsets)) != len(self.offsets):
97
98
  raise ValueError('offset array contains duplicate values')
98
99
 
@@ -142,16 +143,13 @@ class _dia_base(_data_matrix):
142
143
  _getnnz.__doc__ = _spbase._getnnz.__doc__
143
144
 
144
145
  def sum(self, axis=None, dtype=None, out=None):
145
- validateaxis(axis)
146
-
147
- if axis is not None and axis < 0:
148
- axis += 2
146
+ axis = validateaxis(axis)
149
147
 
150
148
  res_dtype = get_sum_dtype(self.dtype)
151
149
  num_rows, num_cols = self.shape
152
150
  ret = None
153
151
 
154
- if axis == 0:
152
+ if axis == (0,):
155
153
  mask = self._data_mask()
156
154
  x = (self.data * mask).sum(axis=0)
157
155
  if x.shape[0] == num_cols:
@@ -161,7 +159,7 @@ class _dia_base(_data_matrix):
161
159
  res[:x.shape[0]] = x
162
160
  ret = self._ascontainer(res, dtype=res_dtype)
163
161
 
164
- else:
162
+ else: # axis is None or (1,)
165
163
  row_sums = np.zeros((num_rows, 1), dtype=res_dtype)
166
164
  one = np.ones(num_cols, dtype=res_dtype)
167
165
  dia_matvec(num_rows, num_cols, len(self.offsets),
@@ -174,21 +172,19 @@ class _dia_base(_data_matrix):
174
172
 
175
173
  ret = self._ascontainer(row_sums.sum(axis=axis))
176
174
 
177
- if out is not None and out.shape != ret.shape:
178
- raise ValueError("dimensions do not match")
179
-
180
175
  return ret.sum(axis=(), dtype=dtype, out=out)
181
176
 
182
177
  sum.__doc__ = _spbase.sum.__doc__
183
178
 
184
- def _add_sparse(self, other):
179
+ def _add_sparse(self, other, sub=False):
185
180
  # If other is not DIA format, let them handle us instead.
186
181
  if not isinstance(other, _dia_base):
187
182
  return other._add_sparse(self)
188
183
 
189
184
  # Fast path for exact equality of the sparsity structure.
190
185
  if np.array_equal(self.offsets, other.offsets):
191
- return self._with_data(self.data + other.data)
186
+ return self._with_data(self.data - other.data if sub else
187
+ self.data + other.data)
192
188
 
193
189
  # Find the union of the offsets (which will be sorted and unique).
194
190
  new_offsets = np.union1d(self.offsets, other.offsets)
@@ -201,26 +197,91 @@ class _dia_base(_data_matrix):
201
197
  # permutation of the existing offsets and the diagonal lengths match.
202
198
  if self_d == other_d and len(new_offsets) == len(self.offsets):
203
199
  new_data = self.data[_invert_index(self_idx)]
204
- new_data[other_idx, :] += other.data
200
+ if sub:
201
+ new_data[other_idx, :] -= other.data
202
+ else:
203
+ new_data[other_idx, :] += other.data
205
204
  elif self_d == other_d and len(new_offsets) == len(other.offsets):
206
- new_data = other.data[_invert_index(other_idx)]
205
+ if sub:
206
+ new_data = -other.data[_invert_index(other_idx)]
207
+ else:
208
+ new_data = other.data[_invert_index(other_idx)]
207
209
  new_data[self_idx, :] += self.data
208
210
  else:
209
211
  # Maximum diagonal length of the result.
210
212
  d = min(self.shape[0] + new_offsets[-1], self.shape[1])
211
213
 
212
- # Add all diagonals to a freshly-allocated data array.
214
+ # Add all diagonals to a freshly allocated data array.
213
215
  new_data = np.zeros(
214
216
  (len(new_offsets), d),
215
217
  dtype=np.result_type(self.data, other.data),
216
218
  )
217
219
  new_data[self_idx, :self_d] += self.data[:, :d]
218
- new_data[other_idx, :other_d] += other.data[:, :d]
220
+ if sub:
221
+ new_data[other_idx, :other_d] -= other.data[:, :d]
222
+ else:
223
+ new_data[other_idx, :other_d] += other.data[:, :d]
219
224
  return self._dia_container((new_data, new_offsets), shape=self.shape)
220
225
 
226
+ def _sub_sparse(self, other):
227
+ # If other is not DIA format, use default handler.
228
+ if not isinstance(other, _dia_base):
229
+ return super()._sub_sparse(other)
230
+
231
+ return self._add_sparse(other, sub=True)
232
+
221
233
  def _mul_scalar(self, other):
222
234
  return self._with_data(self.data * other)
223
235
 
236
+ def multiply(self, other):
237
+ if isscalarlike(other):
238
+ return self._mul_scalar(other)
239
+
240
+ if isdense(other):
241
+ if other.ndim > 2:
242
+ return self.toarray() * other
243
+
244
+ # Use default handler for pathological cases.
245
+ if 0 in self.shape or 1 in self.shape or 0 in other.shape:
246
+ return super().multiply(other)
247
+
248
+ other = np.atleast_2d(other)
249
+ other_rows, other_cols = other.shape
250
+ rows, cols = self.shape
251
+ L = min(self.data.shape[1], cols)
252
+ data = self.data[:, :L].astype(np.result_type(self.data, other))
253
+ if other_rows == 1:
254
+ data *= other[0, :L]
255
+ elif other_rows != rows:
256
+ raise ValueError('inconsistent shapes')
257
+ else:
258
+ j = np.arange(L)
259
+ if L > rows:
260
+ i = (j - self.offsets[:, None]) % rows
261
+ else: # can use faster method
262
+ i = j - self.offsets[:, None] % rows
263
+ if other_cols == 1:
264
+ j = 0
265
+ elif other_cols != cols:
266
+ raise ValueError('inconsistent shapes')
267
+ data *= other[i, j]
268
+ return self._with_data(data)
269
+
270
+ # If other is not DIA format or needs broadcasting (unreasonable
271
+ # use case for DIA anyway), use default handler.
272
+ if not isinstance(other, _dia_base) or other.shape != self.shape:
273
+ return super().multiply(other)
274
+
275
+ # Find common offsets (unique diagonals don't contribute)
276
+ # and indices corresponding to them in multiplicand and multiplier.
277
+ offsets, self_idx, other_idx = \
278
+ np.intersect1d(self.offsets, other.offsets,
279
+ assume_unique=True, return_indices=True)
280
+ # Only overlapping length of diagonals can have non-zero products.
281
+ L = min(self.data.shape[1], other.data.shape[1])
282
+ data = self.data[self_idx, :L] * other.data[other_idx, :L]
283
+ return self._dia_container((data, offsets), shape=self.shape)
284
+
224
285
  def _matmul_vector(self, other):
225
286
  x = other
226
287
 
@@ -236,6 +297,29 @@ class _dia_base(_data_matrix):
236
297
 
237
298
  return y
238
299
 
300
+ def _matmul_multivector(self, other):
301
+ res = np.zeros((self.shape[0], other.shape[1]),
302
+ dtype=np.result_type(self.data, other))
303
+ dia_matvecs(*self.shape, *self.data.shape, self.offsets, self.data,
304
+ other.shape[1], other, res)
305
+ return res
306
+
307
+ def _matmul_sparse(self, other):
308
+ # If other is not DIA format, use default handler.
309
+ if not isinstance(other, _dia_base):
310
+ return super()._matmul_sparse(other)
311
+
312
+ # If any dimension is zero, return empty array immediately.
313
+ if 0 in self.shape or 0 in other.shape:
314
+ return self._dia_container((self.shape[0], other.shape[1]))
315
+
316
+ offsets, data = dia_matmat(*self.shape, *self.data.shape,
317
+ self.offsets, self.data,
318
+ other.shape[1], *other.data.shape,
319
+ other.offsets, other.data)
320
+ return self._dia_container((data.reshape(len(offsets), -1), offsets),
321
+ (self.shape[0], other.shape[1]))
322
+
239
323
  def _setdiag(self, values, k=0):
240
324
  M, N = self.shape
241
325
 
scipy/sparse/_dok.py CHANGED
@@ -5,7 +5,6 @@ __docformat__ = "restructuredtext en"
5
5
  __all__ = ['dok_array', 'dok_matrix', 'isspmatrix_dok']
6
6
 
7
7
  import itertools
8
- from warnings import warn
9
8
  import numpy as np
10
9
 
11
10
  from ._matrix import spmatrix
@@ -421,28 +420,6 @@ class _dok_base(_spbase, IndexMixin, dict):
421
420
 
422
421
  transpose.__doc__ = _spbase.transpose.__doc__
423
422
 
424
- def conjtransp(self):
425
- """DEPRECATED: Return the conjugate transpose.
426
-
427
- .. deprecated:: 1.14.0
428
-
429
- `conjtransp` is deprecated and will be removed in v1.16.0.
430
- Use ``.T.conj()`` instead.
431
- """
432
- msg = ("`conjtransp` is deprecated and will be removed in v1.16.0. "
433
- "Use `.T.conj()` instead.")
434
- warn(msg, DeprecationWarning, stacklevel=2)
435
-
436
- if self.ndim == 1:
437
- new = self.tocoo()
438
- new.data = new.data.conjugate()
439
- return new
440
-
441
- M, N = self.shape
442
- new = self._dok_container((N, M), dtype=self.dtype)
443
- new._dict = {(right, left): np.conj(val) for (left, right), val in self.items()}
444
- return new
445
-
446
423
  def copy(self):
447
424
  new = self._dok_container(self.shape, dtype=self.dtype)
448
425
  new._dict.update(self._dict)
scipy/sparse/_index.py CHANGED
@@ -329,12 +329,12 @@ class IndexMixin:
329
329
  # Check bounds
330
330
  max_indx = x.max()
331
331
  if max_indx >= length:
332
- raise IndexError('index (%d) out of range' % max_indx)
332
+ raise IndexError(f'index ({max_indx}) out of range')
333
333
 
334
334
  min_indx = x.min()
335
335
  if min_indx < 0:
336
336
  if min_indx < -length:
337
- raise IndexError('index (%d) out of range' % min_indx)
337
+ raise IndexError(f'index ({min_indx}) out of range')
338
338
  if x is idx or not x.flags.owndata:
339
339
  x = x.copy()
340
340
  x[x < 0] += length
@@ -346,7 +346,7 @@ class IndexMixin:
346
346
  M, N = self.shape
347
347
  i = int(i)
348
348
  if i < -M or i >= M:
349
- raise IndexError('index (%d) out of range' % i)
349
+ raise IndexError(f'index ({i}) out of range')
350
350
  if i < 0:
351
351
  i += M
352
352
  return self._get_intXslice(i, slice(None))
@@ -357,7 +357,7 @@ class IndexMixin:
357
357
  M, N = self.shape
358
358
  i = int(i)
359
359
  if i < -N or i >= N:
360
- raise IndexError('index (%d) out of range' % i)
360
+ raise IndexError(f'index ({i}) out of range')
361
361
  if i < 0:
362
362
  i += N
363
363
  return self._get_sliceXint(slice(None), i)
scipy/sparse/_matrix.py CHANGED
@@ -144,3 +144,26 @@ class spmatrix:
144
144
  `numpy.matrix` object that shares the same memory.
145
145
  """
146
146
  return super().todense(order, out)
147
+
148
+ @classmethod
149
+ def __class_getitem__(cls, arg, /):
150
+ """
151
+ Return a parametrized wrapper around the `~scipy.sparse.spmatrix` type.
152
+
153
+ .. versionadded:: 1.16.0
154
+
155
+ Returns
156
+ -------
157
+ alias : types.GenericAlias
158
+ A parametrized `~scipy.sparse.spmatrix` type.
159
+
160
+ Examples
161
+ --------
162
+ >>> import numpy as np
163
+ >>> from scipy.sparse import coo_matrix
164
+
165
+ >>> coo_matrix[np.int8]
166
+ scipy.sparse._coo.coo_matrix[numpy.int8]
167
+ """
168
+ from types import GenericAlias
169
+ return GenericAlias(cls, arg)
scipy/sparse/_sputils.py CHANGED
@@ -134,7 +134,7 @@ def getdtype(dtype, a=None, default=None):
134
134
 
135
135
  if newdtype not in supported_dtypes:
136
136
  supported_dtypes_fmt = ", ".join(t.__name__ for t in supported_dtypes)
137
- raise ValueError(f"scipy.sparse does not support dtype {newdtype.name}. "
137
+ raise ValueError(f"scipy.sparse does not support dtype {newdtype}. "
138
138
  f"The only supported types are: {supported_dtypes_fmt}.")
139
139
  return newdtype
140
140
 
@@ -403,27 +403,42 @@ def isdense(x) -> bool:
403
403
  return isinstance(x, np.ndarray)
404
404
 
405
405
 
406
- def validateaxis(axis) -> None:
406
+ def validateaxis(axis, *, ndim=2) -> tuple[int, ...] | None:
407
407
  if axis is None:
408
- return
409
- axis_type = type(axis)
410
-
411
- # In NumPy, you can pass in tuples for 'axis', but they are
412
- # not very useful for sparse matrices given their limited
413
- # dimensions, so let's make it explicit that they are not
414
- # allowed to be passed in
415
- if isinstance(axis, tuple):
416
- raise TypeError("Tuples are not accepted for the 'axis' parameter. "
417
- "Please pass in one of the following: "
418
- "{-2, -1, 0, 1, None}.")
419
-
420
- # If not a tuple, check that the provided axis is actually
421
- # an integer and raise a TypeError similar to NumPy's
422
- if not np.issubdtype(np.dtype(axis_type), np.integer):
423
- raise TypeError(f"axis must be an integer, not {axis_type.__name__}")
424
-
425
- if not (-2 <= axis <= 1):
426
- raise ValueError("axis out of range")
408
+ return None
409
+
410
+ if axis == ():
411
+ raise ValueError(
412
+ "sparse does not accept 0D axis (). Either use toarray (for dense) "
413
+ "or copy (for sparse)."
414
+ )
415
+
416
+ if not isinstance(axis, tuple):
417
+ # If not a tuple, check that the provided axis is actually
418
+ # an integer and raise a TypeError similar to NumPy's
419
+ if not np.issubdtype(np.dtype(type(axis)), np.integer):
420
+ raise TypeError(f'axis must be an integer/tuple of ints, not {type(axis)}')
421
+ axis = (axis,)
422
+
423
+ canon_axis = []
424
+ for ax in axis:
425
+ if not isintlike(ax):
426
+ raise TypeError(f"axis must be an integer. (given {ax})")
427
+ if ax < 0:
428
+ ax += ndim
429
+ if ax < 0 or ax >= ndim:
430
+ raise ValueError("axis out of range for ndim")
431
+ canon_axis.append(ax)
432
+
433
+ len_axis = len(canon_axis)
434
+ if len_axis != len(set(canon_axis)):
435
+ raise ValueError("duplicate value in axis")
436
+ elif len_axis > ndim:
437
+ raise ValueError("axis tuple has too many elements")
438
+ elif len_axis == ndim:
439
+ return None
440
+ else:
441
+ return tuple(canon_axis)
427
442
 
428
443
 
429
444
  def check_shape(args, current_shape=None, *, allow_nd=(2,)) -> tuple[int, ...]:
@@ -509,7 +524,7 @@ def broadcast_shapes(*shapes):
509
524
  """
510
525
  if not shapes:
511
526
  return ()
512
- shapes = [shp if isinstance(shp, (tuple, list)) else (shp,) for shp in shapes]
527
+ shapes = [shp if isinstance(shp, tuple | list) else (shp,) for shp in shapes]
513
528
  big_shp = max(shapes, key=len)
514
529
  out = list(big_shp)
515
530
  for shp in shapes:
scipy/sparse/base.py CHANGED
@@ -6,20 +6,11 @@ from scipy._lib.deprecation import _sub_module_deprecation
6
6
 
7
7
 
8
8
  __all__ = [ # noqa: F822
9
- 'MAXPRINT',
10
9
  'SparseEfficiencyWarning',
11
- 'SparseFormatWarning',
12
10
  'SparseWarning',
13
- 'asmatrix',
14
- 'check_reshape_kwargs',
15
- 'check_shape',
16
- 'get_sum_dtype',
17
- 'isdense',
18
- 'isscalarlike',
19
11
  'issparse',
20
12
  'isspmatrix',
21
13
  'spmatrix',
22
- 'validateaxis',
23
14
  ]
24
15
 
25
16
 
scipy/sparse/bsr.py CHANGED
@@ -6,23 +6,9 @@ from scipy._lib.deprecation import _sub_module_deprecation
6
6
 
7
7
 
8
8
  __all__ = [ # noqa: F822
9
- 'bsr_matmat',
10
9
  'bsr_matrix',
11
- 'bsr_matvec',
12
- 'bsr_matvecs',
13
- 'bsr_sort_indices',
14
- 'bsr_tocsr',
15
- 'bsr_transpose',
16
- 'check_shape',
17
- 'csr_matmat_maxnnz',
18
- 'getdata',
19
- 'getdtype',
20
- 'isshape',
21
10
  'isspmatrix_bsr',
22
11
  'spmatrix',
23
- 'to_native',
24
- 'upcast',
25
- 'warn',
26
12
  ]
27
13
 
28
14
 
@@ -6,30 +6,7 @@ from scipy._lib.deprecation import _sub_module_deprecation
6
6
 
7
7
 
8
8
  __all__ = [ # noqa: F822
9
- 'IndexMixin',
10
9
  'SparseEfficiencyWarning',
11
- 'check_shape',
12
- 'csr_column_index1',
13
- 'csr_column_index2',
14
- 'csr_row_index',
15
- 'csr_row_slice',
16
- 'csr_sample_offsets',
17
- 'csr_sample_values',
18
- 'csr_todense',
19
- 'downcast_intp_index',
20
- 'get_csr_submatrix',
21
- 'get_sum_dtype',
22
- 'getdtype',
23
- 'is_pydata_spmatrix',
24
- 'isdense',
25
- 'isintlike',
26
- 'isscalarlike',
27
- 'isshape',
28
- 'operator',
29
- 'to_native',
30
- 'upcast',
31
- 'upcast_char',
32
- 'warn',
33
10
  ]
34
11
 
35
12