scipy 1.15.3__cp311-cp311-macosx_12_0_arm64.whl → 1.16.0__cp311-cp311-macosx_12_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 (630) hide show
  1. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  2. scipy/__config__.py +8 -8
  3. scipy/__init__.py +3 -6
  4. scipy/_cyutility.cpython-311-darwin.so +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.cpython-311-darwin.so +0 -0
  9. scipy/_lib/_docscrape.py +1 -1
  10. scipy/_lib/_elementwise_iterative_method.py +15 -26
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_deprecation_call.cpython-311-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-311-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-311-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 +166 -35
  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-311-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-311-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-311-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 +282 -151
  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-311-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-311-darwin.so +0 -0
  126. scipy/integrate/_lsoda.cpython-311-darwin.so +0 -0
  127. scipy/integrate/_ode.py +9 -2
  128. scipy/integrate/_odepack.cpython-311-darwin.so +0 -0
  129. scipy/integrate/_quad_vec.py +21 -29
  130. scipy/integrate/_quadpack.cpython-311-darwin.so +0 -0
  131. scipy/integrate/_quadpack_py.py +11 -7
  132. scipy/integrate/_quadrature.py +3 -3
  133. scipy/integrate/_rules/_base.py +2 -2
  134. scipy/integrate/_tanhsinh.py +48 -47
  135. scipy/integrate/_test_odeint_banded.cpython-311-darwin.so +0 -0
  136. scipy/integrate/_vode.cpython-311-darwin.so +0 -0
  137. scipy/integrate/tests/test__quad_vec.py +0 -6
  138. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  139. scipy/integrate/tests/test_cubature.py +21 -35
  140. scipy/integrate/tests/test_quadrature.py +6 -8
  141. scipy/integrate/tests/test_tanhsinh.py +56 -48
  142. scipy/interpolate/__init__.py +70 -58
  143. scipy/interpolate/_bary_rational.py +22 -22
  144. scipy/interpolate/_bsplines.py +119 -66
  145. scipy/interpolate/_cubic.py +65 -50
  146. scipy/interpolate/_dfitpack.cpython-311-darwin.so +0 -0
  147. scipy/interpolate/_dierckx.cpython-311-darwin.so +0 -0
  148. scipy/interpolate/_fitpack.cpython-311-darwin.so +0 -0
  149. scipy/interpolate/_fitpack2.py +9 -6
  150. scipy/interpolate/_fitpack_impl.py +32 -26
  151. scipy/interpolate/_fitpack_repro.py +23 -19
  152. scipy/interpolate/_interpnd.cpython-311-darwin.so +0 -0
  153. scipy/interpolate/_interpolate.py +30 -12
  154. scipy/interpolate/_ndbspline.py +13 -18
  155. scipy/interpolate/_ndgriddata.py +5 -8
  156. scipy/interpolate/_polyint.py +95 -31
  157. scipy/interpolate/_ppoly.cpython-311-darwin.so +0 -0
  158. scipy/interpolate/_rbf.py +2 -2
  159. scipy/interpolate/_rbfinterp.py +1 -1
  160. scipy/interpolate/_rbfinterp_pythran.cpython-311-darwin.so +0 -0
  161. scipy/interpolate/_rgi.py +31 -26
  162. scipy/interpolate/_rgi_cython.cpython-311-darwin.so +0 -0
  163. scipy/interpolate/dfitpack.py +0 -20
  164. scipy/interpolate/interpnd.py +1 -2
  165. scipy/interpolate/tests/test_bary_rational.py +2 -2
  166. scipy/interpolate/tests/test_bsplines.py +97 -1
  167. scipy/interpolate/tests/test_fitpack2.py +39 -1
  168. scipy/interpolate/tests/test_interpnd.py +32 -20
  169. scipy/interpolate/tests/test_interpolate.py +48 -4
  170. scipy/interpolate/tests/test_rgi.py +2 -1
  171. scipy/io/_fast_matrix_market/__init__.py +2 -0
  172. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  173. scipy/io/_harwell_boeing/hb.py +7 -11
  174. scipy/io/_idl.py +5 -7
  175. scipy/io/_netcdf.py +15 -5
  176. scipy/io/_test_fortran.cpython-311-darwin.so +0 -0
  177. scipy/io/arff/tests/test_arffread.py +3 -3
  178. scipy/io/matlab/__init__.py +5 -3
  179. scipy/io/matlab/_mio.py +4 -1
  180. scipy/io/matlab/_mio5.py +19 -13
  181. scipy/io/matlab/_mio5_utils.cpython-311-darwin.so +0 -0
  182. scipy/io/matlab/_mio_utils.cpython-311-darwin.so +0 -0
  183. scipy/io/matlab/_miobase.py +4 -1
  184. scipy/io/matlab/_streams.cpython-311-darwin.so +0 -0
  185. scipy/io/matlab/tests/test_mio.py +46 -18
  186. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  187. scipy/io/tests/test_mmio.py +7 -1
  188. scipy/io/tests/test_wavfile.py +41 -0
  189. scipy/io/wavfile.py +57 -10
  190. scipy/linalg/_basic.py +113 -86
  191. scipy/linalg/_cythonized_array_utils.cpython-311-darwin.so +0 -0
  192. scipy/linalg/_decomp.py +22 -9
  193. scipy/linalg/_decomp_cholesky.py +28 -13
  194. scipy/linalg/_decomp_cossin.py +45 -30
  195. scipy/linalg/_decomp_interpolative.cpython-311-darwin.so +0 -0
  196. scipy/linalg/_decomp_ldl.py +4 -1
  197. scipy/linalg/_decomp_lu.py +18 -6
  198. scipy/linalg/_decomp_lu_cython.cpython-311-darwin.so +0 -0
  199. scipy/linalg/_decomp_polar.py +2 -0
  200. scipy/linalg/_decomp_qr.py +6 -2
  201. scipy/linalg/_decomp_qz.py +3 -0
  202. scipy/linalg/_decomp_schur.py +3 -1
  203. scipy/linalg/_decomp_svd.py +13 -2
  204. scipy/linalg/_decomp_update.cpython-311-darwin.so +0 -0
  205. scipy/linalg/_expm_frechet.py +4 -0
  206. scipy/linalg/_fblas.cpython-311-darwin.so +0 -0
  207. scipy/linalg/_flapack.cpython-311-darwin.so +0 -0
  208. scipy/linalg/_linalg_pythran.cpython-311-darwin.so +0 -0
  209. scipy/linalg/_matfuncs.py +187 -4
  210. scipy/linalg/_matfuncs_expm.cpython-311-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-darwin.so +0 -0
  212. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  213. scipy/linalg/_matfuncs_sqrtm_triu.cpython-311-darwin.so +0 -0
  214. scipy/linalg/_procrustes.py +2 -0
  215. scipy/linalg/_sketches.py +17 -6
  216. scipy/linalg/_solve_toeplitz.cpython-311-darwin.so +0 -0
  217. scipy/linalg/_solvers.py +7 -2
  218. scipy/linalg/_special_matrices.py +26 -36
  219. scipy/linalg/blas.py +35 -24
  220. scipy/linalg/cython_blas.cpython-311-darwin.so +0 -0
  221. scipy/linalg/cython_lapack.cpython-311-darwin.so +0 -0
  222. scipy/linalg/lapack.py +22 -2
  223. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  224. scipy/linalg/tests/test_basic.py +31 -16
  225. scipy/linalg/tests/test_batch.py +588 -0
  226. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  227. scipy/linalg/tests/test_decomp.py +40 -3
  228. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  229. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  230. scipy/linalg/tests/test_lapack.py +115 -7
  231. scipy/linalg/tests/test_matfuncs.py +157 -102
  232. scipy/linalg/tests/test_procrustes.py +0 -7
  233. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  234. scipy/linalg/tests/test_special_matrices.py +1 -5
  235. scipy/ndimage/__init__.py +1 -0
  236. scipy/ndimage/_cytest.cpython-311-darwin.so +0 -0
  237. scipy/ndimage/_delegators.py +8 -2
  238. scipy/ndimage/_filters.py +453 -5
  239. scipy/ndimage/_interpolation.py +36 -6
  240. scipy/ndimage/_measurements.py +4 -2
  241. scipy/ndimage/_morphology.py +5 -0
  242. scipy/ndimage/_nd_image.cpython-311-darwin.so +0 -0
  243. scipy/ndimage/_ni_docstrings.py +5 -1
  244. scipy/ndimage/_ni_label.cpython-311-darwin.so +0 -0
  245. scipy/ndimage/_ni_support.py +1 -5
  246. scipy/ndimage/_rank_filter_1d.cpython-311-darwin.so +0 -0
  247. scipy/ndimage/_support_alternative_backends.py +18 -6
  248. scipy/ndimage/tests/test_filters.py +370 -259
  249. scipy/ndimage/tests/test_fourier.py +7 -9
  250. scipy/ndimage/tests/test_interpolation.py +68 -61
  251. scipy/ndimage/tests/test_measurements.py +18 -35
  252. scipy/ndimage/tests/test_morphology.py +143 -131
  253. scipy/ndimage/tests/test_splines.py +1 -3
  254. scipy/odr/__odrpack.cpython-311-darwin.so +0 -0
  255. scipy/optimize/_basinhopping.py +13 -7
  256. scipy/optimize/_bglu_dense.cpython-311-darwin.so +0 -0
  257. scipy/optimize/_bracket.py +17 -24
  258. scipy/optimize/_chandrupatla.py +9 -10
  259. scipy/optimize/_cobyla_py.py +104 -123
  260. scipy/optimize/_constraints.py +14 -10
  261. scipy/optimize/_differentiable_functions.py +371 -230
  262. scipy/optimize/_differentialevolution.py +4 -3
  263. scipy/optimize/_direct.cpython-311-darwin.so +0 -0
  264. scipy/optimize/_dual_annealing.py +1 -1
  265. scipy/optimize/_elementwise.py +1 -4
  266. scipy/optimize/_group_columns.cpython-311-darwin.so +0 -0
  267. scipy/optimize/_lbfgsb.cpython-311-darwin.so +0 -0
  268. scipy/optimize/_lbfgsb_py.py +80 -24
  269. scipy/optimize/_linprog_doc.py +2 -2
  270. scipy/optimize/_linprog_highs.py +2 -2
  271. scipy/optimize/_linprog_ip.py +25 -10
  272. scipy/optimize/_linprog_util.py +14 -16
  273. scipy/optimize/_lsap.cpython-311-darwin.so +0 -0
  274. scipy/optimize/_lsq/common.py +3 -3
  275. scipy/optimize/_lsq/dogbox.py +16 -2
  276. scipy/optimize/_lsq/givens_elimination.cpython-311-darwin.so +0 -0
  277. scipy/optimize/_lsq/least_squares.py +198 -126
  278. scipy/optimize/_lsq/lsq_linear.py +6 -6
  279. scipy/optimize/_lsq/trf.py +35 -8
  280. scipy/optimize/_milp.py +3 -1
  281. scipy/optimize/_minimize.py +105 -36
  282. scipy/optimize/_minpack.cpython-311-darwin.so +0 -0
  283. scipy/optimize/_minpack_py.py +21 -14
  284. scipy/optimize/_moduleTNC.cpython-311-darwin.so +0 -0
  285. scipy/optimize/_nnls.py +20 -21
  286. scipy/optimize/_nonlin.py +34 -3
  287. scipy/optimize/_numdiff.py +288 -110
  288. scipy/optimize/_optimize.py +86 -48
  289. scipy/optimize/_pava_pybind.cpython-311-darwin.so +0 -0
  290. scipy/optimize/_remove_redundancy.py +5 -5
  291. scipy/optimize/_root_scalar.py +1 -1
  292. scipy/optimize/_shgo.py +6 -0
  293. scipy/optimize/_shgo_lib/_complex.py +1 -1
  294. scipy/optimize/_slsqp_py.py +216 -124
  295. scipy/optimize/_slsqplib.cpython-311-darwin.so +0 -0
  296. scipy/optimize/_spectral.py +1 -1
  297. scipy/optimize/_tnc.py +8 -1
  298. scipy/optimize/_trlib/_trlib.cpython-311-darwin.so +0 -0
  299. scipy/optimize/_trustregion.py +20 -6
  300. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  301. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  302. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  303. scipy/optimize/_trustregion_constr/projections.py +12 -8
  304. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  305. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  306. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  307. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  308. scipy/optimize/_trustregion_exact.py +0 -1
  309. scipy/optimize/_zeros.cpython-311-darwin.so +0 -0
  310. scipy/optimize/_zeros_py.py +97 -17
  311. scipy/optimize/cython_optimize/_zeros.cpython-311-darwin.so +0 -0
  312. scipy/optimize/slsqp.py +0 -1
  313. scipy/optimize/tests/test__basinhopping.py +1 -1
  314. scipy/optimize/tests/test__differential_evolution.py +4 -4
  315. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  316. scipy/optimize/tests/test__numdiff.py +66 -22
  317. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  318. scipy/optimize/tests/test__shgo.py +9 -1
  319. scipy/optimize/tests/test_bracket.py +36 -46
  320. scipy/optimize/tests/test_chandrupatla.py +133 -135
  321. scipy/optimize/tests/test_cobyla.py +74 -45
  322. scipy/optimize/tests/test_constraints.py +1 -1
  323. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  324. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  325. scipy/optimize/tests/test_least_squares.py +125 -13
  326. scipy/optimize/tests/test_linear_assignment.py +3 -3
  327. scipy/optimize/tests/test_linprog.py +3 -3
  328. scipy/optimize/tests/test_lsq_linear.py +6 -6
  329. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  330. scipy/optimize/tests/test_minpack.py +4 -4
  331. scipy/optimize/tests/test_nnls.py +43 -3
  332. scipy/optimize/tests/test_nonlin.py +36 -0
  333. scipy/optimize/tests/test_optimize.py +98 -20
  334. scipy/optimize/tests/test_slsqp.py +36 -4
  335. scipy/optimize/tests/test_zeros.py +34 -1
  336. scipy/signal/__init__.py +12 -23
  337. scipy/signal/_delegators.py +568 -0
  338. scipy/signal/_filter_design.py +459 -241
  339. scipy/signal/_fir_filter_design.py +262 -90
  340. scipy/signal/_lti_conversion.py +3 -2
  341. scipy/signal/_ltisys.py +118 -91
  342. scipy/signal/_max_len_seq_inner.cpython-311-darwin.so +0 -0
  343. scipy/signal/_peak_finding_utils.cpython-311-darwin.so +0 -0
  344. scipy/signal/_polyutils.py +172 -0
  345. scipy/signal/_short_time_fft.py +519 -70
  346. scipy/signal/_signal_api.py +30 -0
  347. scipy/signal/_signaltools.py +719 -399
  348. scipy/signal/_sigtools.cpython-311-darwin.so +0 -0
  349. scipy/signal/_sosfilt.cpython-311-darwin.so +0 -0
  350. scipy/signal/_spectral_py.py +230 -50
  351. scipy/signal/_spline.cpython-311-darwin.so +0 -0
  352. scipy/signal/_spline_filters.py +108 -68
  353. scipy/signal/_support_alternative_backends.py +73 -0
  354. scipy/signal/_upfirdn.py +4 -1
  355. scipy/signal/_upfirdn_apply.cpython-311-darwin.so +0 -0
  356. scipy/signal/_waveforms.py +2 -11
  357. scipy/signal/_wavelets.py +1 -1
  358. scipy/signal/fir_filter_design.py +1 -0
  359. scipy/signal/spline.py +4 -11
  360. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  361. scipy/signal/tests/test_bsplines.py +114 -79
  362. scipy/signal/tests/test_cont2discrete.py +9 -2
  363. scipy/signal/tests/test_filter_design.py +721 -481
  364. scipy/signal/tests/test_fir_filter_design.py +332 -140
  365. scipy/signal/tests/test_savitzky_golay.py +4 -3
  366. scipy/signal/tests/test_short_time_fft.py +221 -3
  367. scipy/signal/tests/test_signaltools.py +2145 -1349
  368. scipy/signal/tests/test_spectral.py +50 -6
  369. scipy/signal/tests/test_splines.py +161 -96
  370. scipy/signal/tests/test_upfirdn.py +84 -50
  371. scipy/signal/tests/test_waveforms.py +20 -0
  372. scipy/signal/tests/test_windows.py +607 -466
  373. scipy/signal/windows/_windows.py +287 -148
  374. scipy/sparse/__init__.py +23 -4
  375. scipy/sparse/_base.py +270 -108
  376. scipy/sparse/_bsr.py +7 -4
  377. scipy/sparse/_compressed.py +59 -231
  378. scipy/sparse/_construct.py +90 -38
  379. scipy/sparse/_coo.py +115 -181
  380. scipy/sparse/_csc.py +4 -4
  381. scipy/sparse/_csparsetools.cpython-311-darwin.so +0 -0
  382. scipy/sparse/_csr.py +2 -2
  383. scipy/sparse/_data.py +48 -48
  384. scipy/sparse/_dia.py +105 -18
  385. scipy/sparse/_dok.py +0 -23
  386. scipy/sparse/_index.py +4 -4
  387. scipy/sparse/_matrix.py +23 -0
  388. scipy/sparse/_sparsetools.cpython-311-darwin.so +0 -0
  389. scipy/sparse/_sputils.py +37 -22
  390. scipy/sparse/base.py +0 -9
  391. scipy/sparse/bsr.py +0 -14
  392. scipy/sparse/compressed.py +0 -23
  393. scipy/sparse/construct.py +0 -6
  394. scipy/sparse/coo.py +0 -14
  395. scipy/sparse/csc.py +0 -3
  396. scipy/sparse/csgraph/_flow.cpython-311-darwin.so +0 -0
  397. scipy/sparse/csgraph/_matching.cpython-311-darwin.so +0 -0
  398. scipy/sparse/csgraph/_min_spanning_tree.cpython-311-darwin.so +0 -0
  399. scipy/sparse/csgraph/_reordering.cpython-311-darwin.so +0 -0
  400. scipy/sparse/csgraph/_shortest_path.cpython-311-darwin.so +0 -0
  401. scipy/sparse/csgraph/_tools.cpython-311-darwin.so +0 -0
  402. scipy/sparse/csgraph/_traversal.cpython-311-darwin.so +0 -0
  403. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  404. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  405. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  406. scipy/sparse/csr.py +0 -5
  407. scipy/sparse/data.py +1 -6
  408. scipy/sparse/dia.py +0 -7
  409. scipy/sparse/dok.py +0 -10
  410. scipy/sparse/linalg/_dsolve/_superlu.cpython-311-darwin.so +0 -0
  411. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  412. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  413. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-311-darwin.so +0 -0
  414. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  415. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  416. scipy/sparse/linalg/_interface.py +17 -18
  417. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  418. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  419. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  420. scipy/sparse/linalg/_isolve/minres.py +5 -5
  421. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  422. scipy/sparse/linalg/_isolve/utils.py +2 -8
  423. scipy/sparse/linalg/_matfuncs.py +1 -1
  424. scipy/sparse/linalg/_norm.py +1 -1
  425. scipy/sparse/linalg/_propack/_cpropack.cpython-311-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_dpropack.cpython-311-darwin.so +0 -0
  427. scipy/sparse/linalg/_propack/_spropack.cpython-311-darwin.so +0 -0
  428. scipy/sparse/linalg/_propack/_zpropack.cpython-311-darwin.so +0 -0
  429. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  430. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  431. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  432. scipy/sparse/tests/test_base.py +214 -42
  433. scipy/sparse/tests/test_common1d.py +7 -7
  434. scipy/sparse/tests/test_construct.py +1 -1
  435. scipy/sparse/tests/test_coo.py +272 -4
  436. scipy/sparse/tests/test_sparsetools.py +5 -0
  437. scipy/sparse/tests/test_sputils.py +36 -7
  438. scipy/spatial/_ckdtree.cpython-311-darwin.so +0 -0
  439. scipy/spatial/_distance_pybind.cpython-311-darwin.so +0 -0
  440. scipy/spatial/_distance_wrap.cpython-311-darwin.so +0 -0
  441. scipy/spatial/_hausdorff.cpython-311-darwin.so +0 -0
  442. scipy/spatial/_qhull.cpython-311-darwin.so +0 -0
  443. scipy/spatial/_voronoi.cpython-311-darwin.so +0 -0
  444. scipy/spatial/distance.py +49 -42
  445. scipy/spatial/tests/test_distance.py +15 -1
  446. scipy/spatial/tests/test_kdtree.py +1 -0
  447. scipy/spatial/tests/test_qhull.py +7 -2
  448. scipy/spatial/transform/__init__.py +5 -3
  449. scipy/spatial/transform/_rigid_transform.cpython-311-darwin.so +0 -0
  450. scipy/spatial/transform/_rotation.cpython-311-darwin.so +0 -0
  451. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  452. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  453. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  454. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  455. scipy/special/__init__.py +1 -47
  456. scipy/special/_add_newdocs.py +34 -772
  457. scipy/special/_basic.py +22 -25
  458. scipy/special/_comb.cpython-311-darwin.so +0 -0
  459. scipy/special/_ellip_harm_2.cpython-311-darwin.so +0 -0
  460. scipy/special/_gufuncs.cpython-311-darwin.so +0 -0
  461. scipy/special/_logsumexp.py +67 -58
  462. scipy/special/_orthogonal.pyi +1 -1
  463. scipy/special/_specfun.cpython-311-darwin.so +0 -0
  464. scipy/special/_special_ufuncs.cpython-311-darwin.so +0 -0
  465. scipy/special/_spherical_bessel.py +4 -4
  466. scipy/special/_support_alternative_backends.py +212 -119
  467. scipy/special/_test_internal.cpython-311-darwin.so +0 -0
  468. scipy/special/_testutils.py +4 -4
  469. scipy/special/_ufuncs.cpython-311-darwin.so +0 -0
  470. scipy/special/_ufuncs.pyi +1 -0
  471. scipy/special/_ufuncs.pyx +215 -1400
  472. scipy/special/_ufuncs_cxx.cpython-311-darwin.so +0 -0
  473. scipy/special/_ufuncs_cxx.pxd +2 -15
  474. scipy/special/_ufuncs_cxx.pyx +5 -44
  475. scipy/special/_ufuncs_cxx_defs.h +2 -16
  476. scipy/special/_ufuncs_defs.h +0 -8
  477. scipy/special/cython_special.cpython-311-darwin.so +0 -0
  478. scipy/special/cython_special.pxd +1 -1
  479. scipy/special/tests/_cython_examples/meson.build +10 -1
  480. scipy/special/tests/test_basic.py +153 -20
  481. scipy/special/tests/test_boost_ufuncs.py +3 -0
  482. scipy/special/tests/test_cdflib.py +35 -11
  483. scipy/special/tests/test_gammainc.py +16 -0
  484. scipy/special/tests/test_hyp2f1.py +2 -2
  485. scipy/special/tests/test_log1mexp.py +85 -0
  486. scipy/special/tests/test_logsumexp.py +206 -64
  487. scipy/special/tests/test_mpmath.py +1 -0
  488. scipy/special/tests/test_nan_inputs.py +1 -1
  489. scipy/special/tests/test_orthogonal.py +17 -18
  490. scipy/special/tests/test_sf_error.py +3 -2
  491. scipy/special/tests/test_sph_harm.py +6 -7
  492. scipy/special/tests/test_support_alternative_backends.py +211 -76
  493. scipy/stats/__init__.py +4 -1
  494. scipy/stats/_ansari_swilk_statistics.cpython-311-darwin.so +0 -0
  495. scipy/stats/_axis_nan_policy.py +5 -12
  496. scipy/stats/_biasedurn.cpython-311-darwin.so +0 -0
  497. scipy/stats/_continued_fraction.py +387 -0
  498. scipy/stats/_continuous_distns.py +277 -310
  499. scipy/stats/_correlation.py +1 -1
  500. scipy/stats/_covariance.py +6 -3
  501. scipy/stats/_discrete_distns.py +39 -32
  502. scipy/stats/_distn_infrastructure.py +39 -12
  503. scipy/stats/_distribution_infrastructure.py +920 -238
  504. scipy/stats/_entropy.py +9 -10
  505. scipy/{_lib → stats}/_finite_differences.py +1 -1
  506. scipy/stats/_hypotests.py +83 -50
  507. scipy/stats/_kde.py +53 -49
  508. scipy/stats/_ksstats.py +1 -1
  509. scipy/stats/_levy_stable/__init__.py +7 -15
  510. scipy/stats/_levy_stable/levyst.cpython-311-darwin.so +0 -0
  511. scipy/stats/_morestats.py +118 -73
  512. scipy/stats/_mstats_basic.py +13 -17
  513. scipy/stats/_mstats_extras.py +8 -8
  514. scipy/stats/_multivariate.py +89 -113
  515. scipy/stats/_new_distributions.py +97 -20
  516. scipy/stats/_page_trend_test.py +12 -5
  517. scipy/stats/_probability_distribution.py +265 -43
  518. scipy/stats/_qmc.py +14 -9
  519. scipy/stats/_qmc_cy.cpython-311-darwin.so +0 -0
  520. scipy/stats/_qmvnt.py +16 -95
  521. scipy/stats/_qmvnt_cy.cpython-311-darwin.so +0 -0
  522. scipy/stats/_quantile.py +335 -0
  523. scipy/stats/_rcont/rcont.cpython-311-darwin.so +0 -0
  524. scipy/stats/_resampling.py +5 -30
  525. scipy/stats/_sampling.py +1 -1
  526. scipy/stats/_sobol.cpython-311-darwin.so +0 -0
  527. scipy/stats/_stats.cpython-311-darwin.so +0 -0
  528. scipy/stats/_stats_mstats_common.py +21 -2
  529. scipy/stats/_stats_py.py +551 -477
  530. scipy/stats/_stats_pythran.cpython-311-darwin.so +0 -0
  531. scipy/stats/_unuran/unuran_wrapper.cpython-311-darwin.so +0 -0
  532. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  533. scipy/stats/_variation.py +6 -8
  534. scipy/stats/_wilcoxon.py +13 -7
  535. scipy/stats/tests/common_tests.py +6 -4
  536. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  537. scipy/stats/tests/test_continued_fraction.py +173 -0
  538. scipy/stats/tests/test_continuous.py +379 -60
  539. scipy/stats/tests/test_continuous_basic.py +18 -12
  540. scipy/stats/tests/test_discrete_basic.py +14 -8
  541. scipy/stats/tests/test_discrete_distns.py +16 -16
  542. scipy/stats/tests/test_distributions.py +95 -75
  543. scipy/stats/tests/test_entropy.py +40 -48
  544. scipy/stats/tests/test_fit.py +4 -3
  545. scipy/stats/tests/test_hypotests.py +153 -24
  546. scipy/stats/tests/test_kdeoth.py +109 -41
  547. scipy/stats/tests/test_marray.py +289 -0
  548. scipy/stats/tests/test_morestats.py +81 -49
  549. scipy/stats/tests/test_mstats_basic.py +3 -3
  550. scipy/stats/tests/test_multivariate.py +434 -83
  551. scipy/stats/tests/test_qmc.py +13 -10
  552. scipy/stats/tests/test_quantile.py +199 -0
  553. scipy/stats/tests/test_rank.py +119 -112
  554. scipy/stats/tests/test_resampling.py +47 -56
  555. scipy/stats/tests/test_sampling.py +9 -4
  556. scipy/stats/tests/test_stats.py +799 -939
  557. scipy/stats/tests/test_variation.py +8 -6
  558. scipy/version.py +2 -2
  559. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  560. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/METADATA +11 -11
  561. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/RECORD +562 -569
  562. scipy-1.16.0.dist-info/WHEEL +6 -0
  563. scipy/_lib/array_api_extra/_funcs.py +0 -484
  564. scipy/_lib/array_api_extra/_typing.py +0 -8
  565. scipy/interpolate/_bspl.cpython-311-darwin.so +0 -0
  566. scipy/optimize/_cobyla.cpython-311-darwin.so +0 -0
  567. scipy/optimize/_cython_nnls.cpython-311-darwin.so +0 -0
  568. scipy/optimize/_slsqp.cpython-311-darwin.so +0 -0
  569. scipy/spatial/qhull_src/COPYING.txt +0 -38
  570. scipy/special/libsf_error_state.dylib +0 -0
  571. scipy/special/tests/test_log_softmax.py +0 -109
  572. scipy/special/tests/test_xsf_cuda.py +0 -114
  573. scipy/special/xsf/binom.h +0 -89
  574. scipy/special/xsf/cdflib.h +0 -100
  575. scipy/special/xsf/cephes/airy.h +0 -307
  576. scipy/special/xsf/cephes/besselpoly.h +0 -51
  577. scipy/special/xsf/cephes/beta.h +0 -257
  578. scipy/special/xsf/cephes/cbrt.h +0 -131
  579. scipy/special/xsf/cephes/chbevl.h +0 -85
  580. scipy/special/xsf/cephes/chdtr.h +0 -193
  581. scipy/special/xsf/cephes/const.h +0 -87
  582. scipy/special/xsf/cephes/ellie.h +0 -293
  583. scipy/special/xsf/cephes/ellik.h +0 -251
  584. scipy/special/xsf/cephes/ellpe.h +0 -107
  585. scipy/special/xsf/cephes/ellpk.h +0 -117
  586. scipy/special/xsf/cephes/expn.h +0 -260
  587. scipy/special/xsf/cephes/gamma.h +0 -398
  588. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  589. scipy/special/xsf/cephes/hyperg.h +0 -361
  590. scipy/special/xsf/cephes/i0.h +0 -149
  591. scipy/special/xsf/cephes/i1.h +0 -158
  592. scipy/special/xsf/cephes/igam.h +0 -421
  593. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  594. scipy/special/xsf/cephes/igami.h +0 -313
  595. scipy/special/xsf/cephes/j0.h +0 -225
  596. scipy/special/xsf/cephes/j1.h +0 -198
  597. scipy/special/xsf/cephes/jv.h +0 -715
  598. scipy/special/xsf/cephes/k0.h +0 -164
  599. scipy/special/xsf/cephes/k1.h +0 -163
  600. scipy/special/xsf/cephes/kn.h +0 -243
  601. scipy/special/xsf/cephes/lanczos.h +0 -112
  602. scipy/special/xsf/cephes/ndtr.h +0 -275
  603. scipy/special/xsf/cephes/poch.h +0 -85
  604. scipy/special/xsf/cephes/polevl.h +0 -167
  605. scipy/special/xsf/cephes/psi.h +0 -194
  606. scipy/special/xsf/cephes/rgamma.h +0 -111
  607. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  608. scipy/special/xsf/cephes/shichi.h +0 -248
  609. scipy/special/xsf/cephes/sici.h +0 -224
  610. scipy/special/xsf/cephes/sindg.h +0 -221
  611. scipy/special/xsf/cephes/tandg.h +0 -139
  612. scipy/special/xsf/cephes/trig.h +0 -58
  613. scipy/special/xsf/cephes/unity.h +0 -186
  614. scipy/special/xsf/cephes/zeta.h +0 -172
  615. scipy/special/xsf/config.h +0 -304
  616. scipy/special/xsf/digamma.h +0 -205
  617. scipy/special/xsf/error.h +0 -57
  618. scipy/special/xsf/evalpoly.h +0 -47
  619. scipy/special/xsf/expint.h +0 -266
  620. scipy/special/xsf/hyp2f1.h +0 -694
  621. scipy/special/xsf/iv_ratio.h +0 -173
  622. scipy/special/xsf/lambertw.h +0 -150
  623. scipy/special/xsf/loggamma.h +0 -163
  624. scipy/special/xsf/sici.h +0 -200
  625. scipy/special/xsf/tools.h +0 -427
  626. scipy/special/xsf/trig.h +0 -164
  627. scipy/special/xsf/wright_bessel.h +0 -843
  628. scipy/special/xsf/zlog1.h +0 -35
  629. scipy/stats/_mvn.cpython-311-darwin.so +0 -0
  630. scipy-1.15.3.dist-info/WHEEL +0 -4
scipy/sparse/_coo.py CHANGED
@@ -298,7 +298,7 @@ class _coo_base(_data_matrix, _minmax_mixin):
298
298
  M, N = self.shape
299
299
  coo_todense(M, N, self.nnz, self.row, self.col, self.data,
300
300
  B.ravel('A'), fortran)
301
- else:
301
+ else: # dim>2
302
302
  if fortran:
303
303
  strides = np.append(1, np.cumprod(self.shape[:-1]))
304
304
  else:
@@ -603,7 +603,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
603
603
  A = self.__class__((new_data, new_coords), shape=self.shape)
604
604
  return A
605
605
 
606
-
607
606
  def _sub_sparse(self, other):
608
607
  if self.ndim < 3:
609
608
  return self.tocsr()._sub_sparse(other)
@@ -616,7 +615,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
616
615
  A = coo_array((new_data, new_coords), shape=self.shape)
617
616
  return A
618
617
 
619
-
620
618
  def _matmul_vector(self, other):
621
619
  if self.ndim > 2:
622
620
  result = np.zeros(math.prod(self.shape[:-1]),
@@ -650,7 +648,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
650
648
  return result[0]
651
649
  return result
652
650
 
653
-
654
651
  def _rmatmul_dispatch(self, other):
655
652
  if isscalarlike(other):
656
653
  return self._mul_scalar(other)
@@ -676,7 +673,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
676
673
  perm = tuple(range(ret.ndim)[:-2]) + tuple(range(ret.ndim)[-2:][::-1])
677
674
  return ret.transpose(perm)
678
675
 
679
-
680
676
  def _matmul_dispatch(self, other):
681
677
  if isscalarlike(other):
682
678
  return self.multiply(other)
@@ -689,7 +685,7 @@ class _coo_base(_data_matrix, _minmax_mixin):
689
685
  # Not interpretable as an array; return NotImplemented so that
690
686
  # other's __rmatmul__ can kick in if that's implemented.
691
687
  return NotImplemented
692
-
688
+ # Allow custom sparse class indicated by attr sparse gh-6520
693
689
  try:
694
690
  other.shape
695
691
  except AttributeError:
@@ -726,7 +722,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
726
722
  f"{err_prefix} (n,..,k={N}),(k={other.shape[-2]},..,m)->(n,..,m)"
727
723
  )
728
724
 
729
-
730
725
  if isscalarlike(other):
731
726
  # scalar value
732
727
  return self._mul_scalar(other)
@@ -771,7 +766,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
771
766
  result = result.reshape(result.shape[:-1])
772
767
  return result
773
768
 
774
-
775
769
  def _matmul_multivector(self, other):
776
770
  result_dtype = upcast_char(self.dtype.char, other.dtype.char)
777
771
  if self.ndim >= 3 or other.ndim >= 3:
@@ -807,7 +801,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
807
801
  self.data, other.ravel('C'), result)
808
802
  return result.view(type=type(other))
809
803
 
810
-
811
804
  def dot(self, other):
812
805
  """Return the dot product of two arrays.
813
806
 
@@ -861,6 +854,7 @@ class _coo_base(_data_matrix, _minmax_mixin):
861
854
  >>> A.dot(B).shape
862
855
  (3, 4, 5, 5, 4, 3)
863
856
  """
857
+ # handle non-array input: lists, ints, etc
864
858
  if not (issparse(other) or isdense(other) or isscalarlike(other)):
865
859
  # If it's a list or whatever, treat it like an array
866
860
  o_array = np.asanyarray(other)
@@ -872,118 +866,68 @@ class _coo_base(_data_matrix, _minmax_mixin):
872
866
  except AttributeError:
873
867
  other = o_array
874
868
 
875
- if self.ndim < 3 and (np.isscalar(other) or other.ndim<3):
876
- return _spbase.dot(self, other)
877
869
  # Handle scalar multiplication
878
- if np.isscalar(other):
870
+ if isscalarlike(other):
879
871
  return self * other
872
+
873
+ # other.shape[-2:][0] gets last index of 1d, next to last index of >1d
874
+ if self.shape[-1] != other.shape[-2:][0]:
875
+ raise ValueError(f"shapes {self.shape} and {other.shape}"
876
+ " are not aligned for n-D dot")
877
+
878
+ if self.ndim < 3 and other.ndim < 3:
879
+ return self @ other
880
880
  if isdense(other):
881
881
  return self._dense_dot(other)
882
- elif other.format != "coo":
883
- raise TypeError("input must be a COO matrix/array")
884
- elif self.ndim == 1 and other.ndim == 1:
885
- # Handle inner product of vectors (1-D arrays)
886
- if self.shape[0] != other.shape[0]:
887
- raise ValueError(f"shapes {self.shape} and {other.shape}"
888
- " are not aligned for inner product")
889
- return self @ other
890
- elif self.ndim == 2 and other.ndim == 2:
891
- # Handle matrix multiplication (2-D arrays)
892
- if self.shape[1] != other.shape[0]:
893
- raise ValueError(f"shapes {self.shape} and {other.shape}"
894
- " are not aligned for matmul")
895
- return self @ other
896
- else:
897
- return self._sparse_dot(other)
898
-
882
+ return self._sparse_dot(other.tocoo())
899
883
 
900
884
  def _sparse_dot(self, other):
901
- self_is_1d = self.ndim == 1
902
- other_is_1d = other.ndim == 1
903
-
904
- # reshape to 2-D if self or other is 1-D
905
- if self_is_1d:
906
- self = self.reshape(self._shape_as_2d) # prepend 1 to shape
907
- if other_is_1d:
908
- other = other.reshape((other.shape[0], 1)) # append 1 to shape
909
-
910
- if self.shape[-1] != other.shape[-2]:
911
- raise ValueError(f"shapes {self.shape} and {other.shape}"
912
- " are not aligned for n-D dot")
913
-
914
- # Prepare the tensors for dot operation
885
+ # already checked: at least one is >2d, neither scalar, both are coo
915
886
  # Ravel non-reduced axes coordinates
916
- self_raveled_coords = _ravel_non_reduced_axes(self.coords,
917
- self.shape, [self.ndim-1])
918
- other_raveled_coords = _ravel_non_reduced_axes(other.coords,
919
- other.shape, [other.ndim-2])
887
+ self_2d, s_new_shape = _convert_to_2d(self, [self.ndim - 1])
888
+ other_2d, o_new_shape = _convert_to_2d(other, [max(0, other.ndim - 2)])
920
889
 
921
- # Get the shape of the non-reduced axes
922
- self_nonreduced_shape = self.shape[:-1]
923
- other_nonreduced_shape = other.shape[:-2] + other.shape[-1:]
890
+ prod = self_2d @ other_2d.T # routes via 2-D CSR
891
+ prod = prod.tocoo()
924
892
 
925
- # Create 2D coords arrays
926
- ravel_coords_shape_self = (math.prod(self_nonreduced_shape), self.shape[-1])
927
- ravel_coords_shape_other = (other.shape[-2], math.prod(other_nonreduced_shape))
928
-
929
- self_2d_coords = (self_raveled_coords, self.coords[-1])
930
- other_2d_coords = (other.coords[-2], other_raveled_coords)
931
-
932
- self_2d = coo_array((self.data, self_2d_coords), ravel_coords_shape_self)
933
- other_2d = coo_array((other.data, other_2d_coords), ravel_coords_shape_other)
934
-
935
- prod = (self_2d @ other_2d).tocoo() # routes via 2-D CSR
936
-
937
- # Combine the shapes of the non-reduced axes
938
- combined_shape = self_nonreduced_shape + other_nonreduced_shape
893
+ # Combine the shapes of the non-contracted axes
894
+ combined_shape = s_new_shape + o_new_shape
939
895
 
940
896
  # Unravel the 2D coordinates to get multi-dimensional coordinates
941
- shapes = (self_nonreduced_shape, other_nonreduced_shape)
942
- prod_coords = []
943
- for c, s in zip(prod.coords, shapes):
944
- prod_coords.extend(np.unravel_index(c, s))
945
-
946
- prod_arr = coo_array((prod.data, prod_coords), combined_shape)
947
-
948
- # reshape back if a or b were originally 1-D
949
- # TODO: Move this logic before computation of prod_coords for efficiency
950
- if self_is_1d:
951
- prod_arr = prod_arr.reshape(combined_shape[1:])
952
- if other_is_1d:
953
- prod_arr = prod_arr.reshape(combined_shape[:-1])
897
+ coords = []
898
+ new_shapes = (s_new_shape, o_new_shape) if s_new_shape else (o_new_shape,)
899
+ for c, s in zip(prod.coords, new_shapes):
900
+ coords.extend(np.unravel_index(c, s))
954
901
 
955
- return prod_arr
902
+ # Construct the resulting COO array with coords and shape
903
+ return coo_array((prod.data, coords), shape=combined_shape)
956
904
 
957
905
  def _dense_dot(self, other):
958
- self_is_1d = self.ndim == 1
959
- other_is_1d = other.ndim == 1
960
-
961
- # reshape to 2-D if self or other is 1-D
962
- if self_is_1d:
963
- self = self.reshape(self._shape_as_2d) # prepend 1 to shape
964
- if other_is_1d:
965
- other = other.reshape((other.shape[0], 1)) # append 1 to shape
966
-
967
- if self.shape[-1] != other.shape[-2]:
968
- raise ValueError(f"shapes {self.shape} and {other.shape}"
969
- " are not aligned for n-D dot")
906
+ # already checked: self is >0d, other is dense and >0d
907
+ # Ravel non-reduced axes coordinates
908
+ s_ndim = self.ndim
909
+ if s_ndim <= 2:
910
+ s_new_shape = () if s_ndim == 1 else (self.shape[0],)
911
+ self_2d = self
912
+ else:
913
+ self_2d, s_new_shape = _convert_to_2d(self, [self.ndim - 1])
970
914
 
971
- new_shape_self = (
972
- self.shape[:-1] + (1,) * (len(other.shape) - 1) + self.shape[-1:]
973
- )
974
- new_shape_other = (1,) * (len(self.shape) - 1) + other.shape
915
+ o_ndim = other.ndim
916
+ if o_ndim <= 2:
917
+ o_new_shape = () if o_ndim == 1 else (other.shape[-1],)
918
+ other_2d = other
919
+ else:
920
+ o_new_shape = other.shape[:-2] + other.shape[-1:]
921
+ reorder_dims = (o_ndim - 2, *range(o_ndim - 2), o_ndim - 1)
922
+ o_reorg = np.transpose(other, reorder_dims)
923
+ other_2d = o_reorg.reshape((other.shape[-2], math.prod(o_new_shape)))
975
924
 
976
- result_shape = self.shape[:-1] + other.shape[:-2] + other.shape[-1:]
977
- result = self.reshape(new_shape_self) @ other.reshape(new_shape_other)
978
- prod_arr = result.reshape(result_shape)
925
+ prod = self_2d @ other_2d # routes via 2-D CSR
979
926
 
980
- # reshape back if a or b were originally 1-D
981
- if self_is_1d:
982
- prod_arr = prod_arr.reshape(result_shape[1:])
983
- if other_is_1d:
984
- prod_arr = prod_arr.reshape(result_shape[:-1])
927
+ # Combine the shapes of the non-contracted axes
928
+ combined_shape = s_new_shape + o_new_shape
929
+ return prod.reshape(combined_shape)
985
930
 
986
- return prod_arr
987
931
 
988
932
  def tensordot(self, other, axes=2):
989
933
  """Return the tensordot product with another array along the given axes.
@@ -1097,85 +1041,52 @@ class _coo_base(_data_matrix, _minmax_mixin):
1097
1041
  else:
1098
1042
  return self._sparse_tensordot(other, axes_self, axes_other)
1099
1043
 
1100
-
1101
- def _sparse_tensordot(self, other, axes_self, axes_other):
1102
- ndim_self = len(self.shape)
1103
- ndim_other = len(other.shape)
1104
-
1044
+ def _sparse_tensordot(self, other, s_axes, o_axes):
1105
1045
  # Prepare the tensors for tensordot operation
1106
1046
  # Ravel non-reduced axes coordinates
1107
- self_non_red_coords = _ravel_non_reduced_axes(self.coords, self.shape,
1108
- axes_self)
1109
- self_reduced_coords = np.ravel_multi_index(
1110
- [self.coords[ax] for ax in axes_self], [self.shape[ax] for ax in axes_self])
1111
- other_non_red_coords = _ravel_non_reduced_axes(other.coords, other.shape,
1112
- axes_other)
1113
- other_reduced_coords = np.ravel_multi_index(
1114
- [other.coords[a] for a in axes_other], [other.shape[a] for a in axes_other]
1115
- )
1116
- # Get the shape of the non-reduced axes
1117
- self_nonreduced_shape = tuple(self.shape[ax] for ax in range(ndim_self)
1118
- if ax not in axes_self)
1119
- other_nonreduced_shape = tuple(other.shape[ax] for ax in range(ndim_other)
1120
- if ax not in axes_other)
1121
-
1122
- # Create 2D coords arrays
1123
- ravel_coords_shape_self = (math.prod(self_nonreduced_shape),
1124
- math.prod([self.shape[ax] for ax in axes_self]))
1125
- ravel_coords_shape_other = (math.prod([other.shape[ax] for ax in axes_other]),
1126
- math.prod(other_nonreduced_shape))
1127
-
1128
- self_2d_coords = (self_non_red_coords, self_reduced_coords)
1129
- other_2d_coords = (other_reduced_coords, other_non_red_coords)
1130
-
1131
- self_2d = coo_array((self.data, self_2d_coords), ravel_coords_shape_self)
1132
- other_2d = coo_array((other.data, other_2d_coords), ravel_coords_shape_other)
1047
+ self_2d, s_new_shape = _convert_to_2d(self, s_axes)
1048
+ other_2d, o_new_shape = _convert_to_2d(other, o_axes)
1133
1049
 
1134
1050
  # Perform matrix multiplication (routed via 2-D CSR)
1135
- prod = (self_2d @ other_2d).tocoo()
1051
+ prod = self_2d @ other_2d.T
1052
+ # handle case of scalar result (axis includes all axes for both)
1053
+ if not issparse(prod):
1054
+ return prod
1055
+ prod = prod.tocoo()
1136
1056
 
1137
1057
  # Combine the shapes of the non-contracted axes
1138
- combined_shape = self_nonreduced_shape + other_nonreduced_shape
1058
+ combined_shape = s_new_shape + o_new_shape
1139
1059
 
1140
1060
  # Unravel the 2D coordinates to get multi-dimensional coordinates
1141
1061
  coords = []
1142
- for c, s in zip(prod.coords, (self_nonreduced_shape, other_nonreduced_shape)):
1062
+ new_shapes = (s_new_shape, o_new_shape) if s_new_shape else (o_new_shape,)
1063
+ for c, s in zip(prod.coords, new_shapes):
1143
1064
  if s:
1144
1065
  coords.extend(np.unravel_index(c, s))
1145
1066
 
1146
- if coords == []: # if result is scalar
1147
- return sum(prod.data)
1148
-
1149
- # Construct the resulting COO array with combined coordinates and shape
1067
+ # Construct the resulting COO array with coords and shape
1150
1068
  return coo_array((prod.data, coords), shape=combined_shape)
1151
1069
 
1070
+ def _dense_tensordot(self, other, s_axes, o_axes):
1071
+ s_ndim = len(self.shape)
1072
+ o_ndim = len(other.shape)
1152
1073
 
1153
- def _dense_tensordot(self, other, axes_self, axes_other):
1154
- ndim_self = len(self.shape)
1155
- ndim_other = len(other.shape)
1074
+ s_non_axes = [i for i in range(s_ndim) if i not in s_axes]
1075
+ s_axes_shape = [self.shape[i] for i in s_axes]
1076
+ s_non_axes_shape = [self.shape[i] for i in s_non_axes]
1156
1077
 
1157
- non_reduced_axes_self = [ax for ax in range(ndim_self) if ax not in axes_self]
1158
- reduced_shape_self = [self.shape[s] for s in axes_self]
1159
- non_reduced_shape_self = [self.shape[s] for s in non_reduced_axes_self]
1078
+ o_non_axes = [i for i in range(o_ndim) if i not in o_axes]
1079
+ o_axes_shape = [other.shape[i] for i in o_axes]
1080
+ o_non_axes_shape = [other.shape[i] for i in o_non_axes]
1160
1081
 
1161
- non_reduced_axes_other = [ax for ax in range(ndim_other)
1162
- if ax not in axes_other]
1163
- reduced_shape_other = [other.shape[s] for s in axes_other]
1164
- non_reduced_shape_other = [other.shape[s] for s in non_reduced_axes_other]
1165
-
1166
- permute_self = non_reduced_axes_self + axes_self
1167
- permute_other = (
1168
- non_reduced_axes_other[:-1] + axes_other + non_reduced_axes_other[-1:]
1169
- )
1170
- self = self.transpose(permute_self)
1171
- other = np.transpose(other, permute_other)
1082
+ left = self.transpose(s_non_axes + s_axes)
1083
+ right = np.transpose(other, o_non_axes[:-1] + o_axes + o_non_axes[-1:])
1172
1084
 
1173
- reshape_self = (*non_reduced_shape_self, math.prod(reduced_shape_self))
1174
- reshape_other = (*non_reduced_shape_other[:-1], math.prod(reduced_shape_other),
1175
- *non_reduced_shape_other[-1:])
1176
-
1177
- return self.reshape(reshape_self).dot(other.reshape(reshape_other))
1085
+ reshape_left = (*s_non_axes_shape, math.prod(s_axes_shape))
1086
+ reshape_right = (*o_non_axes_shape[:-1], math.prod(o_axes_shape),
1087
+ *o_non_axes_shape[-1:])
1178
1088
 
1089
+ return left.reshape(reshape_left).dot(right.reshape(reshape_right))
1179
1090
 
1180
1091
  def _matmul_sparse(self, other):
1181
1092
  """
@@ -1219,7 +1130,6 @@ class _coo_base(_data_matrix, _minmax_mixin):
1219
1130
  shape=(*broadcast_shape, self.shape[-2], other.shape[-1]),
1220
1131
  )
1221
1132
 
1222
-
1223
1133
  def _broadcast_to(self, new_shape, copy=False):
1224
1134
  if self.shape == new_shape:
1225
1135
  return self.copy() if copy else self
@@ -1275,6 +1185,26 @@ class _coo_base(_data_matrix, _minmax_mixin):
1275
1185
 
1276
1186
  return coo_array((new_data, new_coords), new_shape)
1277
1187
 
1188
+ def _sum_nd(self, axis, res_dtype, out):
1189
+ # axis and out are preprocessed. out.shape is new_shape
1190
+ A2d, new_shape = _convert_to_2d(self, axis)
1191
+ ones = np.ones((A2d.shape[1], 1), dtype=res_dtype)
1192
+ # sets dtype while loading into out
1193
+ out[...] = (A2d @ ones).reshape(new_shape)
1194
+ return out
1195
+
1196
+ def _min_or_max_axis_nd(self, axis, min_or_max, explicit):
1197
+ A2d, new_shape = _convert_to_2d(self, axis)
1198
+ res = A2d._min_or_max_axis(1, min_or_max, explicit)
1199
+ unraveled_coords = np.unravel_index(res.coords[0], new_shape)
1200
+
1201
+ return coo_array((res.data, unraveled_coords), new_shape)
1202
+
1203
+ def _argminmax_axis_nd(self, axis, argminmax, compare, explicit):
1204
+ A2d, new_shape = _convert_to_2d(self, axis)
1205
+ res_flat = A2d._argminmax_axis(1, argminmax, compare, explicit)
1206
+ return res_flat.reshape(new_shape)
1207
+
1278
1208
 
1279
1209
  def _block_diag(self):
1280
1210
  """
@@ -1332,7 +1262,7 @@ def _process_axes(ndim_a, ndim_b, axes):
1332
1262
  raise ValueError("axes integer is out of bounds for input arrays")
1333
1263
  axes_a = list(range(ndim_a - axes, ndim_a))
1334
1264
  axes_b = list(range(axes))
1335
- elif isinstance(axes, (tuple, list)):
1265
+ elif isinstance(axes, tuple | list):
1336
1266
  if len(axes) != 2:
1337
1267
  raise ValueError("axes must be a tuple/list of length 2")
1338
1268
  axes_a, axes_b = axes
@@ -1349,22 +1279,26 @@ def _process_axes(ndim_a, ndim_b, axes):
1349
1279
  return axes_a, axes_b
1350
1280
 
1351
1281
 
1352
- def _ravel_non_reduced_axes(coords, shape, axes):
1353
- ndim = len(shape)
1354
- non_reduced_axes = [ax for ax in range(ndim) if ax not in axes]
1355
-
1356
- if not non_reduced_axes:
1357
- # Return an array with one row
1358
- return np.zeros_like(coords[0])
1359
-
1360
- # Extract the shape of the non-reduced axes
1361
- non_reduced_shape = [shape[ax] for ax in non_reduced_axes]
1362
-
1363
- # Extract the coordinates of the non-reduced axes
1364
- non_reduced_coords = tuple(coords[idx] for idx in non_reduced_axes)
1365
-
1366
- # Ravel the coordinates into 1D
1367
- return np.ravel_multi_index(non_reduced_coords, non_reduced_shape)
1282
+ def _convert_to_2d(coo, axis):
1283
+ axis_coords = tuple(coo.coords[i] for i in axis)
1284
+ axis_shape = tuple(coo.shape[i] for i in axis)
1285
+ axis_ravel = _ravel_coords(axis_coords, axis_shape)
1286
+
1287
+ ndim = len(coo.coords)
1288
+ non_axis = tuple(i for i in range(ndim) if i not in axis)
1289
+ if non_axis:
1290
+ non_axis_coords = tuple(coo.coords[i] for i in non_axis)
1291
+ non_axis_shape = tuple(coo.shape[i] for i in non_axis)
1292
+ non_axis_ravel = _ravel_coords(non_axis_coords, non_axis_shape)
1293
+ coords_2d = (non_axis_ravel, axis_ravel)
1294
+ shape_2d = (math.prod(non_axis_shape), math.prod(axis_shape))
1295
+ else: # all axes included in axis so result will have 1 element
1296
+ coords_2d = (axis_ravel,)
1297
+ shape_2d = (math.prod(axis_shape),)
1298
+ non_axis_shape = ()
1299
+
1300
+ new_coo = coo_array((coo.data, coords_2d), shape=shape_2d)
1301
+ return new_coo, non_axis_shape
1368
1302
 
1369
1303
 
1370
1304
  def _ravel_coords(coords, shape, order='C'):
scipy/sparse/_csc.py CHANGED
@@ -8,7 +8,7 @@ import numpy as np
8
8
 
9
9
  from ._matrix import spmatrix
10
10
  from ._base import _spbase, sparray
11
- from ._sparsetools import csc_tocsr, expandptr
11
+ from ._sparsetools import csr_tocsc, expandptr
12
12
  from ._sputils import upcast
13
13
 
14
14
  from ._compressed import _cs_matrix
@@ -49,7 +49,7 @@ class _csc_base(_cs_matrix):
49
49
  indices = np.empty(self.nnz, dtype=idx_dtype)
50
50
  data = np.empty(self.nnz, dtype=upcast(self.dtype))
51
51
 
52
- csc_tocsr(M, N,
52
+ csr_tocsc(N, M,
53
53
  self.indptr.astype(idx_dtype),
54
54
  self.indices.astype(idx_dtype),
55
55
  self.data,
@@ -100,7 +100,7 @@ class _csc_base(_cs_matrix):
100
100
  if i < 0:
101
101
  i += M
102
102
  if i < 0 or i >= M:
103
- raise IndexError('index (%d) out of range' % i)
103
+ raise IndexError(f'index ({i}) out of range')
104
104
  return self._get_submatrix(minor=i).tocsr()
105
105
 
106
106
  def _getcol(self, i):
@@ -112,7 +112,7 @@ class _csc_base(_cs_matrix):
112
112
  if i < 0:
113
113
  i += N
114
114
  if i < 0 or i >= N:
115
- raise IndexError('index (%d) out of range' % i)
115
+ raise IndexError(f'index ({i}) out of range')
116
116
  return self._get_submatrix(major=i, copy=True)
117
117
 
118
118
  def _get_intXarray(self, row, col):
scipy/sparse/_csr.py CHANGED
@@ -168,7 +168,7 @@ class _csr_base(_cs_matrix):
168
168
  if i < 0:
169
169
  i += M
170
170
  if i < 0 or i >= M:
171
- raise IndexError('index (%d) out of range' % i)
171
+ raise IndexError(f'index ({i}) out of range')
172
172
  indptr, indices, data = get_csr_submatrix(
173
173
  M, N, self.indptr, self.indices, self.data, i, i + 1, 0, N)
174
174
  return self.__class__((data, indices, indptr), shape=(1, N),
@@ -184,7 +184,7 @@ class _csr_base(_cs_matrix):
184
184
  if i < 0:
185
185
  i += N
186
186
  if i < 0 or i >= N:
187
- raise IndexError('index (%d) out of range' % i)
187
+ raise IndexError(f'index ({i}) out of range')
188
188
  indptr, indices, data = get_csr_submatrix(
189
189
  M, N, self.indptr, self.indices, self.data, 0, M, i, i + 1)
190
190
  return self.__class__((data, indices, indptr), shape=(M, 1),