scipy 1.15.2__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0__cp312-cp312-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 (642) hide show
  1. scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
  2. scipy/.dylibs/libgfortran.5.dylib +0 -0
  3. scipy/.dylibs/libquadmath.0.dylib +0 -0
  4. scipy/__config__.py +5 -5
  5. scipy/__init__.py +3 -6
  6. scipy/_cyutility.cpython-312-darwin.so +0 -0
  7. scipy/_lib/_array_api.py +497 -161
  8. scipy/_lib/_array_api_compat_vendor.py +9 -0
  9. scipy/_lib/_bunch.py +4 -0
  10. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  11. scipy/_lib/_docscrape.py +1 -1
  12. scipy/_lib/_elementwise_iterative_method.py +15 -26
  13. scipy/_lib/_sparse.py +41 -0
  14. scipy/_lib/_test_ccallback.cpython-312-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  16. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  17. scipy/_lib/_testutils.py +6 -2
  18. scipy/_lib/_util.py +222 -125
  19. scipy/_lib/array_api_compat/__init__.py +4 -4
  20. scipy/_lib/array_api_compat/_internal.py +19 -6
  21. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  22. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  23. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  24. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  25. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  26. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  27. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  28. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  29. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  30. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  31. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  32. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  33. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  34. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  35. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  36. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  37. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  38. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  39. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  40. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  41. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  42. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  43. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  44. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  45. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  46. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  47. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  48. scipy/_lib/array_api_extra/__init__.py +26 -3
  49. scipy/_lib/array_api_extra/_delegation.py +171 -0
  50. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  51. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  52. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  53. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  54. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  55. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  61. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  62. scipy/_lib/array_api_extra/testing.py +359 -0
  63. scipy/_lib/decorator.py +2 -2
  64. scipy/_lib/doccer.py +1 -7
  65. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  66. scipy/_lib/pyprima/__init__.py +212 -0
  67. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  68. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  69. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  70. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  71. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  72. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  73. scipy/_lib/pyprima/cobyla/update.py +289 -0
  74. scipy/_lib/pyprima/common/__init__.py +0 -0
  75. scipy/_lib/pyprima/common/_bounds.py +34 -0
  76. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  77. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  78. scipy/_lib/pyprima/common/_project.py +173 -0
  79. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  80. scipy/_lib/pyprima/common/consts.py +47 -0
  81. scipy/_lib/pyprima/common/evaluate.py +99 -0
  82. scipy/_lib/pyprima/common/history.py +38 -0
  83. scipy/_lib/pyprima/common/infos.py +30 -0
  84. scipy/_lib/pyprima/common/linalg.py +435 -0
  85. scipy/_lib/pyprima/common/message.py +290 -0
  86. scipy/_lib/pyprima/common/powalg.py +131 -0
  87. scipy/_lib/pyprima/common/preproc.py +277 -0
  88. scipy/_lib/pyprima/common/present.py +5 -0
  89. scipy/_lib/pyprima/common/ratio.py +54 -0
  90. scipy/_lib/pyprima/common/redrho.py +47 -0
  91. scipy/_lib/pyprima/common/selectx.py +296 -0
  92. scipy/_lib/tests/test__util.py +105 -121
  93. scipy/_lib/tests/test_array_api.py +169 -34
  94. scipy/_lib/tests/test_bunch.py +7 -0
  95. scipy/_lib/tests/test_ccallback.py +2 -10
  96. scipy/_lib/tests/test_public_api.py +13 -0
  97. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  98. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  99. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  100. scipy/cluster/hierarchy.py +393 -223
  101. scipy/cluster/tests/test_hierarchy.py +273 -335
  102. scipy/cluster/tests/test_vq.py +45 -61
  103. scipy/cluster/vq.py +39 -35
  104. scipy/conftest.py +282 -151
  105. scipy/constants/_constants.py +4 -1
  106. scipy/constants/tests/test_codata.py +2 -2
  107. scipy/constants/tests/test_constants.py +11 -18
  108. scipy/datasets/_download_all.py +15 -1
  109. scipy/datasets/_fetchers.py +7 -1
  110. scipy/datasets/_utils.py +1 -1
  111. scipy/differentiate/_differentiate.py +25 -25
  112. scipy/differentiate/tests/test_differentiate.py +24 -25
  113. scipy/fft/_basic.py +20 -0
  114. scipy/fft/_helper.py +3 -34
  115. scipy/fft/_pocketfft/helper.py +29 -1
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  129. scipy/integrate/_ivp/common.py +3 -3
  130. scipy/integrate/_ivp/ivp.py +9 -2
  131. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  132. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  137. scipy/integrate/_quadpack_py.py +11 -7
  138. scipy/integrate/_quadrature.py +3 -3
  139. scipy/integrate/_rules/_base.py +2 -2
  140. scipy/integrate/_tanhsinh.py +57 -54
  141. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  142. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  143. scipy/integrate/tests/test__quad_vec.py +0 -6
  144. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  145. scipy/integrate/tests/test_cubature.py +21 -35
  146. scipy/integrate/tests/test_quadrature.py +6 -8
  147. scipy/integrate/tests/test_tanhsinh.py +61 -43
  148. scipy/interpolate/__init__.py +70 -58
  149. scipy/interpolate/_bary_rational.py +22 -22
  150. scipy/interpolate/_bsplines.py +119 -66
  151. scipy/interpolate/_cubic.py +65 -50
  152. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  153. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  154. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  155. scipy/interpolate/_fitpack2.py +9 -6
  156. scipy/interpolate/_fitpack_impl.py +32 -26
  157. scipy/interpolate/_fitpack_repro.py +23 -19
  158. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  159. scipy/interpolate/_interpolate.py +30 -12
  160. scipy/interpolate/_ndbspline.py +13 -18
  161. scipy/interpolate/_ndgriddata.py +5 -8
  162. scipy/interpolate/_polyint.py +95 -31
  163. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  164. scipy/interpolate/_rbf.py +2 -2
  165. scipy/interpolate/_rbfinterp.py +1 -1
  166. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  167. scipy/interpolate/_rgi.py +31 -26
  168. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  169. scipy/interpolate/dfitpack.py +0 -20
  170. scipy/interpolate/interpnd.py +1 -2
  171. scipy/interpolate/tests/test_bary_rational.py +2 -2
  172. scipy/interpolate/tests/test_bsplines.py +97 -1
  173. scipy/interpolate/tests/test_fitpack2.py +39 -1
  174. scipy/interpolate/tests/test_interpnd.py +32 -20
  175. scipy/interpolate/tests/test_interpolate.py +48 -4
  176. scipy/interpolate/tests/test_rgi.py +2 -1
  177. scipy/io/_fast_matrix_market/__init__.py +2 -0
  178. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  179. scipy/io/_harwell_boeing/hb.py +7 -11
  180. scipy/io/_idl.py +5 -7
  181. scipy/io/_netcdf.py +15 -5
  182. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  183. scipy/io/arff/tests/test_arffread.py +3 -3
  184. scipy/io/matlab/__init__.py +5 -3
  185. scipy/io/matlab/_mio.py +4 -1
  186. scipy/io/matlab/_mio5.py +19 -13
  187. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  188. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  189. scipy/io/matlab/_miobase.py +4 -1
  190. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  191. scipy/io/matlab/tests/test_mio.py +46 -18
  192. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  193. scipy/io/tests/test_mmio.py +7 -1
  194. scipy/io/tests/test_wavfile.py +41 -0
  195. scipy/io/wavfile.py +57 -10
  196. scipy/linalg/_basic.py +113 -86
  197. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp.py +22 -9
  199. scipy/linalg/_decomp_cholesky.py +28 -13
  200. scipy/linalg/_decomp_cossin.py +45 -30
  201. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  202. scipy/linalg/_decomp_ldl.py +4 -1
  203. scipy/linalg/_decomp_lu.py +18 -6
  204. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  205. scipy/linalg/_decomp_polar.py +2 -0
  206. scipy/linalg/_decomp_qr.py +6 -2
  207. scipy/linalg/_decomp_qz.py +3 -0
  208. scipy/linalg/_decomp_schur.py +3 -1
  209. scipy/linalg/_decomp_svd.py +13 -2
  210. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_expm_frechet.py +4 -0
  212. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  214. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  215. scipy/linalg/_matfuncs.py +187 -4
  216. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  217. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  218. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  219. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  220. scipy/linalg/_procrustes.py +2 -0
  221. scipy/linalg/_sketches.py +17 -6
  222. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  223. scipy/linalg/_solvers.py +7 -2
  224. scipy/linalg/_special_matrices.py +26 -36
  225. scipy/linalg/blas.py +35 -24
  226. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  227. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  228. scipy/linalg/lapack.py +22 -2
  229. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  230. scipy/linalg/tests/test_basic.py +31 -16
  231. scipy/linalg/tests/test_batch.py +588 -0
  232. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  233. scipy/linalg/tests/test_decomp.py +40 -3
  234. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  235. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  236. scipy/linalg/tests/test_interpolative.py +17 -0
  237. scipy/linalg/tests/test_lapack.py +115 -7
  238. scipy/linalg/tests/test_matfuncs.py +157 -102
  239. scipy/linalg/tests/test_procrustes.py +0 -7
  240. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  241. scipy/linalg/tests/test_special_matrices.py +1 -5
  242. scipy/ndimage/__init__.py +1 -0
  243. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  244. scipy/ndimage/_delegators.py +8 -2
  245. scipy/ndimage/_filters.py +453 -5
  246. scipy/ndimage/_interpolation.py +36 -6
  247. scipy/ndimage/_measurements.py +4 -2
  248. scipy/ndimage/_morphology.py +5 -0
  249. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  250. scipy/ndimage/_ndimage_api.py +2 -1
  251. scipy/ndimage/_ni_docstrings.py +5 -1
  252. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  253. scipy/ndimage/_ni_support.py +1 -5
  254. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  255. scipy/ndimage/_support_alternative_backends.py +18 -6
  256. scipy/ndimage/tests/test_filters.py +384 -259
  257. scipy/ndimage/tests/test_fourier.py +7 -9
  258. scipy/ndimage/tests/test_interpolation.py +68 -61
  259. scipy/ndimage/tests/test_measurements.py +18 -35
  260. scipy/ndimage/tests/test_morphology.py +143 -131
  261. scipy/ndimage/tests/test_splines.py +1 -3
  262. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  263. scipy/optimize/_basinhopping.py +13 -7
  264. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_bracket.py +46 -26
  266. scipy/optimize/_chandrupatla.py +9 -10
  267. scipy/optimize/_cobyla_py.py +104 -123
  268. scipy/optimize/_constraints.py +14 -10
  269. scipy/optimize/_differentiable_functions.py +371 -230
  270. scipy/optimize/_differentialevolution.py +4 -3
  271. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_dual_annealing.py +1 -1
  273. scipy/optimize/_elementwise.py +1 -4
  274. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  276. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  277. scipy/optimize/_lbfgsb_py.py +80 -24
  278. scipy/optimize/_linprog_doc.py +2 -2
  279. scipy/optimize/_linprog_highs.py +11 -11
  280. scipy/optimize/_linprog_ip.py +25 -10
  281. scipy/optimize/_linprog_util.py +18 -19
  282. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_lsq/common.py +3 -3
  284. scipy/optimize/_lsq/dogbox.py +16 -2
  285. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  286. scipy/optimize/_lsq/least_squares.py +198 -126
  287. scipy/optimize/_lsq/lsq_linear.py +6 -6
  288. scipy/optimize/_lsq/trf.py +35 -8
  289. scipy/optimize/_milp.py +3 -1
  290. scipy/optimize/_minimize.py +105 -36
  291. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  292. scipy/optimize/_minpack_py.py +21 -14
  293. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_nnls.py +20 -21
  295. scipy/optimize/_nonlin.py +34 -3
  296. scipy/optimize/_numdiff.py +288 -110
  297. scipy/optimize/_optimize.py +86 -48
  298. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  299. scipy/optimize/_remove_redundancy.py +5 -5
  300. scipy/optimize/_root_scalar.py +1 -1
  301. scipy/optimize/_shgo.py +6 -0
  302. scipy/optimize/_shgo_lib/_complex.py +1 -1
  303. scipy/optimize/_slsqp_py.py +216 -124
  304. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  305. scipy/optimize/_spectral.py +1 -1
  306. scipy/optimize/_tnc.py +8 -1
  307. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_trustregion.py +20 -6
  309. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  310. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  311. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  312. scipy/optimize/_trustregion_constr/projections.py +12 -8
  313. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  314. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  315. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  316. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  317. scipy/optimize/_trustregion_exact.py +0 -1
  318. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  319. scipy/optimize/_zeros_py.py +97 -17
  320. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  321. scipy/optimize/slsqp.py +0 -1
  322. scipy/optimize/tests/test__basinhopping.py +1 -1
  323. scipy/optimize/tests/test__differential_evolution.py +4 -4
  324. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  325. scipy/optimize/tests/test__numdiff.py +66 -22
  326. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  327. scipy/optimize/tests/test__shgo.py +9 -1
  328. scipy/optimize/tests/test_bracket.py +71 -46
  329. scipy/optimize/tests/test_chandrupatla.py +133 -135
  330. scipy/optimize/tests/test_cobyla.py +74 -45
  331. scipy/optimize/tests/test_constraints.py +1 -1
  332. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  333. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  334. scipy/optimize/tests/test_least_squares.py +125 -13
  335. scipy/optimize/tests/test_linear_assignment.py +3 -3
  336. scipy/optimize/tests/test_linprog.py +3 -3
  337. scipy/optimize/tests/test_lsq_linear.py +6 -6
  338. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  339. scipy/optimize/tests/test_minpack.py +4 -4
  340. scipy/optimize/tests/test_nnls.py +43 -3
  341. scipy/optimize/tests/test_nonlin.py +36 -0
  342. scipy/optimize/tests/test_optimize.py +98 -20
  343. scipy/optimize/tests/test_slsqp.py +36 -4
  344. scipy/optimize/tests/test_zeros.py +34 -1
  345. scipy/signal/__init__.py +12 -23
  346. scipy/signal/_delegators.py +568 -0
  347. scipy/signal/_filter_design.py +459 -241
  348. scipy/signal/_fir_filter_design.py +262 -90
  349. scipy/signal/_lti_conversion.py +3 -2
  350. scipy/signal/_ltisys.py +118 -91
  351. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  352. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  353. scipy/signal/_polyutils.py +172 -0
  354. scipy/signal/_short_time_fft.py +553 -76
  355. scipy/signal/_signal_api.py +30 -0
  356. scipy/signal/_signaltools.py +719 -396
  357. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  358. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  359. scipy/signal/_spectral_py.py +230 -50
  360. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  361. scipy/signal/_spline_filters.py +108 -68
  362. scipy/signal/_support_alternative_backends.py +73 -0
  363. scipy/signal/_upfirdn.py +4 -1
  364. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  365. scipy/signal/_waveforms.py +2 -11
  366. scipy/signal/_wavelets.py +1 -1
  367. scipy/signal/fir_filter_design.py +1 -0
  368. scipy/signal/spline.py +4 -11
  369. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  370. scipy/signal/tests/test_bsplines.py +114 -79
  371. scipy/signal/tests/test_cont2discrete.py +9 -2
  372. scipy/signal/tests/test_filter_design.py +721 -481
  373. scipy/signal/tests/test_fir_filter_design.py +332 -140
  374. scipy/signal/tests/test_savitzky_golay.py +4 -3
  375. scipy/signal/tests/test_short_time_fft.py +231 -5
  376. scipy/signal/tests/test_signaltools.py +2150 -1349
  377. scipy/signal/tests/test_spectral.py +50 -6
  378. scipy/signal/tests/test_splines.py +161 -96
  379. scipy/signal/tests/test_upfirdn.py +84 -50
  380. scipy/signal/tests/test_waveforms.py +20 -0
  381. scipy/signal/tests/test_windows.py +607 -466
  382. scipy/signal/windows/_windows.py +287 -148
  383. scipy/sparse/__init__.py +23 -4
  384. scipy/sparse/_base.py +269 -120
  385. scipy/sparse/_bsr.py +7 -4
  386. scipy/sparse/_compressed.py +59 -234
  387. scipy/sparse/_construct.py +90 -38
  388. scipy/sparse/_coo.py +115 -181
  389. scipy/sparse/_csc.py +4 -4
  390. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  391. scipy/sparse/_csr.py +2 -2
  392. scipy/sparse/_data.py +48 -48
  393. scipy/sparse/_dia.py +105 -21
  394. scipy/sparse/_dok.py +0 -23
  395. scipy/sparse/_index.py +4 -4
  396. scipy/sparse/_matrix.py +23 -0
  397. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  398. scipy/sparse/_sputils.py +37 -22
  399. scipy/sparse/base.py +0 -9
  400. scipy/sparse/bsr.py +0 -14
  401. scipy/sparse/compressed.py +0 -23
  402. scipy/sparse/construct.py +0 -6
  403. scipy/sparse/coo.py +0 -14
  404. scipy/sparse/csc.py +0 -3
  405. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  406. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  407. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  408. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  409. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  410. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  411. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  412. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  413. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  414. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  415. scipy/sparse/csr.py +0 -5
  416. scipy/sparse/data.py +1 -6
  417. scipy/sparse/dia.py +0 -7
  418. scipy/sparse/dok.py +0 -10
  419. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  420. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  421. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  422. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  423. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  424. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  425. scipy/sparse/linalg/_expm_multiply.py +8 -3
  426. scipy/sparse/linalg/_interface.py +29 -26
  427. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  428. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  429. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  430. scipy/sparse/linalg/_isolve/minres.py +5 -5
  431. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  432. scipy/sparse/linalg/_isolve/utils.py +2 -8
  433. scipy/sparse/linalg/_matfuncs.py +1 -1
  434. scipy/sparse/linalg/_norm.py +1 -1
  435. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  436. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  437. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  438. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  439. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  440. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  441. scipy/sparse/linalg/tests/test_interface.py +35 -0
  442. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  443. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  444. scipy/sparse/tests/test_base.py +224 -40
  445. scipy/sparse/tests/test_common1d.py +17 -12
  446. scipy/sparse/tests/test_construct.py +1 -1
  447. scipy/sparse/tests/test_coo.py +272 -4
  448. scipy/sparse/tests/test_sparsetools.py +5 -0
  449. scipy/sparse/tests/test_sputils.py +36 -7
  450. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  451. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  452. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  453. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  454. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  455. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  456. scipy/spatial/distance.py +49 -42
  457. scipy/spatial/tests/test_distance.py +15 -1
  458. scipy/spatial/tests/test_kdtree.py +1 -0
  459. scipy/spatial/tests/test_qhull.py +106 -2
  460. scipy/spatial/transform/__init__.py +5 -3
  461. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  462. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  463. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  464. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  465. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  466. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  467. scipy/special/__init__.py +1 -47
  468. scipy/special/_add_newdocs.py +34 -772
  469. scipy/special/_basic.py +22 -25
  470. scipy/special/_comb.cpython-312-darwin.so +0 -0
  471. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  472. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  473. scipy/special/_logsumexp.py +83 -69
  474. scipy/special/_orthogonal.pyi +1 -1
  475. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  476. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  477. scipy/special/_spherical_bessel.py +4 -4
  478. scipy/special/_support_alternative_backends.py +212 -119
  479. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  480. scipy/special/_testutils.py +4 -4
  481. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  482. scipy/special/_ufuncs.pyi +1 -0
  483. scipy/special/_ufuncs.pyx +215 -1400
  484. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  485. scipy/special/_ufuncs_cxx.pxd +2 -15
  486. scipy/special/_ufuncs_cxx.pyx +5 -44
  487. scipy/special/_ufuncs_cxx_defs.h +2 -16
  488. scipy/special/_ufuncs_defs.h +0 -8
  489. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  490. scipy/special/cython_special.pxd +1 -1
  491. scipy/special/tests/_cython_examples/meson.build +10 -1
  492. scipy/special/tests/test_basic.py +153 -20
  493. scipy/special/tests/test_boost_ufuncs.py +3 -0
  494. scipy/special/tests/test_cdflib.py +35 -11
  495. scipy/special/tests/test_gammainc.py +16 -0
  496. scipy/special/tests/test_hyp2f1.py +23 -2
  497. scipy/special/tests/test_log1mexp.py +85 -0
  498. scipy/special/tests/test_logsumexp.py +220 -64
  499. scipy/special/tests/test_mpmath.py +1 -0
  500. scipy/special/tests/test_nan_inputs.py +1 -1
  501. scipy/special/tests/test_orthogonal.py +17 -18
  502. scipy/special/tests/test_sf_error.py +3 -2
  503. scipy/special/tests/test_sph_harm.py +6 -7
  504. scipy/special/tests/test_support_alternative_backends.py +211 -76
  505. scipy/stats/__init__.py +4 -1
  506. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  507. scipy/stats/_axis_nan_policy.py +5 -12
  508. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  509. scipy/stats/_continued_fraction.py +387 -0
  510. scipy/stats/_continuous_distns.py +296 -319
  511. scipy/stats/_correlation.py +1 -1
  512. scipy/stats/_covariance.py +6 -3
  513. scipy/stats/_discrete_distns.py +39 -32
  514. scipy/stats/_distn_infrastructure.py +39 -12
  515. scipy/stats/_distribution_infrastructure.py +920 -238
  516. scipy/stats/_entropy.py +9 -10
  517. scipy/{_lib → stats}/_finite_differences.py +1 -1
  518. scipy/stats/_hypotests.py +83 -50
  519. scipy/stats/_kde.py +53 -49
  520. scipy/stats/_ksstats.py +1 -1
  521. scipy/stats/_levy_stable/__init__.py +7 -15
  522. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  523. scipy/stats/_morestats.py +118 -73
  524. scipy/stats/_mstats_basic.py +13 -17
  525. scipy/stats/_mstats_extras.py +8 -8
  526. scipy/stats/_multivariate.py +89 -113
  527. scipy/stats/_new_distributions.py +97 -20
  528. scipy/stats/_page_trend_test.py +12 -5
  529. scipy/stats/_probability_distribution.py +265 -43
  530. scipy/stats/_qmc.py +14 -9
  531. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  532. scipy/stats/_qmvnt.py +16 -95
  533. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  534. scipy/stats/_quantile.py +335 -0
  535. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  536. scipy/stats/_resampling.py +5 -30
  537. scipy/stats/_sampling.py +1 -1
  538. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  539. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  540. scipy/stats/_stats_mstats_common.py +21 -2
  541. scipy/stats/_stats_py.py +551 -477
  542. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  543. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  544. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  545. scipy/stats/_variation.py +6 -8
  546. scipy/stats/_wilcoxon.py +13 -7
  547. scipy/stats/tests/common_tests.py +6 -4
  548. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  549. scipy/stats/tests/test_continued_fraction.py +173 -0
  550. scipy/stats/tests/test_continuous.py +379 -60
  551. scipy/stats/tests/test_continuous_basic.py +18 -12
  552. scipy/stats/tests/test_discrete_basic.py +14 -8
  553. scipy/stats/tests/test_discrete_distns.py +16 -16
  554. scipy/stats/tests/test_distributions.py +117 -75
  555. scipy/stats/tests/test_entropy.py +40 -48
  556. scipy/stats/tests/test_fit.py +4 -3
  557. scipy/stats/tests/test_hypotests.py +153 -24
  558. scipy/stats/tests/test_kdeoth.py +109 -41
  559. scipy/stats/tests/test_marray.py +289 -0
  560. scipy/stats/tests/test_morestats.py +81 -49
  561. scipy/stats/tests/test_mstats_basic.py +3 -3
  562. scipy/stats/tests/test_multivariate.py +434 -83
  563. scipy/stats/tests/test_qmc.py +13 -10
  564. scipy/stats/tests/test_quantile.py +199 -0
  565. scipy/stats/tests/test_rank.py +119 -112
  566. scipy/stats/tests/test_resampling.py +47 -56
  567. scipy/stats/tests/test_sampling.py +9 -4
  568. scipy/stats/tests/test_stats.py +799 -939
  569. scipy/stats/tests/test_variation.py +8 -6
  570. scipy/version.py +2 -2
  571. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  572. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/METADATA +12 -12
  573. {scipy-1.15.2.dist-info → scipy-1.16.0.dist-info}/RECORD +574 -581
  574. scipy-1.16.0.dist-info/WHEEL +6 -0
  575. scipy/_lib/array_api_extra/_funcs.py +0 -484
  576. scipy/_lib/array_api_extra/_typing.py +0 -8
  577. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  578. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  579. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  580. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  581. scipy/spatial/qhull_src/COPYING.txt +0 -38
  582. scipy/special/libsf_error_state.dylib +0 -0
  583. scipy/special/tests/test_log_softmax.py +0 -109
  584. scipy/special/tests/test_xsf_cuda.py +0 -114
  585. scipy/special/xsf/binom.h +0 -89
  586. scipy/special/xsf/cdflib.h +0 -100
  587. scipy/special/xsf/cephes/airy.h +0 -307
  588. scipy/special/xsf/cephes/besselpoly.h +0 -51
  589. scipy/special/xsf/cephes/beta.h +0 -257
  590. scipy/special/xsf/cephes/cbrt.h +0 -131
  591. scipy/special/xsf/cephes/chbevl.h +0 -85
  592. scipy/special/xsf/cephes/chdtr.h +0 -193
  593. scipy/special/xsf/cephes/const.h +0 -87
  594. scipy/special/xsf/cephes/ellie.h +0 -293
  595. scipy/special/xsf/cephes/ellik.h +0 -251
  596. scipy/special/xsf/cephes/ellpe.h +0 -107
  597. scipy/special/xsf/cephes/ellpk.h +0 -117
  598. scipy/special/xsf/cephes/expn.h +0 -260
  599. scipy/special/xsf/cephes/gamma.h +0 -398
  600. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  601. scipy/special/xsf/cephes/hyperg.h +0 -361
  602. scipy/special/xsf/cephes/i0.h +0 -149
  603. scipy/special/xsf/cephes/i1.h +0 -158
  604. scipy/special/xsf/cephes/igam.h +0 -421
  605. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  606. scipy/special/xsf/cephes/igami.h +0 -313
  607. scipy/special/xsf/cephes/j0.h +0 -225
  608. scipy/special/xsf/cephes/j1.h +0 -198
  609. scipy/special/xsf/cephes/jv.h +0 -715
  610. scipy/special/xsf/cephes/k0.h +0 -164
  611. scipy/special/xsf/cephes/k1.h +0 -163
  612. scipy/special/xsf/cephes/kn.h +0 -243
  613. scipy/special/xsf/cephes/lanczos.h +0 -112
  614. scipy/special/xsf/cephes/ndtr.h +0 -275
  615. scipy/special/xsf/cephes/poch.h +0 -85
  616. scipy/special/xsf/cephes/polevl.h +0 -167
  617. scipy/special/xsf/cephes/psi.h +0 -194
  618. scipy/special/xsf/cephes/rgamma.h +0 -111
  619. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  620. scipy/special/xsf/cephes/shichi.h +0 -248
  621. scipy/special/xsf/cephes/sici.h +0 -224
  622. scipy/special/xsf/cephes/sindg.h +0 -221
  623. scipy/special/xsf/cephes/tandg.h +0 -139
  624. scipy/special/xsf/cephes/trig.h +0 -58
  625. scipy/special/xsf/cephes/unity.h +0 -186
  626. scipy/special/xsf/cephes/zeta.h +0 -172
  627. scipy/special/xsf/config.h +0 -304
  628. scipy/special/xsf/digamma.h +0 -205
  629. scipy/special/xsf/error.h +0 -57
  630. scipy/special/xsf/evalpoly.h +0 -47
  631. scipy/special/xsf/expint.h +0 -266
  632. scipy/special/xsf/hyp2f1.h +0 -694
  633. scipy/special/xsf/iv_ratio.h +0 -173
  634. scipy/special/xsf/lambertw.h +0 -150
  635. scipy/special/xsf/loggamma.h +0 -163
  636. scipy/special/xsf/sici.h +0 -200
  637. scipy/special/xsf/tools.h +0 -427
  638. scipy/special/xsf/trig.h +0 -164
  639. scipy/special/xsf/wright_bessel.h +0 -843
  640. scipy/special/xsf/zlog1.h +0 -35
  641. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  642. scipy-1.15.2.dist-info/WHEEL +0 -4
scipy/sparse/__init__.py CHANGED
@@ -32,6 +32,9 @@ SciPy 2-D sparse array package for numeric data.
32
32
  - Sparse arrays use array style *slicing* operations, returning scalars,
33
33
  1D, or 2D sparse arrays. If you need 2D results, use an appropriate index.
34
34
  E.g. ``A[:, i, None]`` or ``A[:, [i]]``.
35
+ - All index arrays for a given sparse array should be of same dtype.
36
+ For example, for CSR format, ``indices`` and ``indptr`` should have
37
+ the same dtype. For COO, each array in `coords` should have same dtype.
35
38
 
36
39
  The construction utilities (`eye`, `kron`, `random`, `diags`, etc.)
37
40
  have appropriate replacements (see :ref:`sparse-construction-functions`).
@@ -253,7 +256,7 @@ is the same:
253
256
  Now we can compute norm of the error with:
254
257
 
255
258
  >>> err = norm(x-x_)
256
- >>> err < 1e-10
259
+ >>> err < 1e-9
257
260
  True
258
261
 
259
262
  It should be small :)
@@ -296,6 +299,7 @@ sorted indices are required (e.g., when passing data to other libraries).
296
299
  # Nathan Bell, and Jake Vanderplas.
297
300
 
298
301
  import warnings as _warnings
302
+ import importlib as _importlib
299
303
 
300
304
  from ._base import *
301
305
  from ._csr import *
@@ -311,8 +315,6 @@ from ._matrix import spmatrix
311
315
  from ._matrix_io import *
312
316
  from ._sputils import get_index_dtype, safely_cast_index_arrays
313
317
 
314
- # For backward compatibility with v0.19.
315
- from . import csgraph
316
318
 
317
319
  # Deprecated namespaces, to be removed in v2.0.0
318
320
  from . import (
@@ -320,12 +322,29 @@ from . import (
320
322
  lil, sparsetools, sputils
321
323
  )
322
324
 
323
- __all__ = [s for s in dir() if not s.startswith('_')]
325
+ _submodules = ["csgraph", "linalg"]
326
+
327
+ __all__ = [s for s in dir() if not s.startswith('_')] + _submodules
324
328
 
325
329
  # Filter PendingDeprecationWarning for np.matrix introduced with numpy 1.15
326
330
  msg = 'the matrix subclass is not the recommended way'
327
331
  _warnings.filterwarnings('ignore', message=msg)
328
332
 
333
+ def __dir__():
334
+ return __all__
335
+
336
+
337
+ def __getattr__(name):
338
+ if name in _submodules:
339
+ return _importlib.import_module(f'scipy.sparse.{name}')
340
+ else:
341
+ try:
342
+ return globals()[name]
343
+ except KeyError:
344
+ raise AttributeError(
345
+ f"Module 'scipy.sparse' has no attribute '{name}'"
346
+ )
347
+
329
348
  from scipy._lib._testutils import PytestTester
330
349
  test = PytestTester(__name__)
331
350
  del PytestTester
scipy/sparse/_base.py CHANGED
@@ -1,10 +1,14 @@
1
1
  """Base class for sparse matrices"""
2
2
 
3
+ from warnings import warn
4
+ import math
3
5
  import numpy as np
6
+ import operator
4
7
 
5
8
  from ._sputils import (asmatrix, check_reshape_kwargs, check_shape,
6
- get_sum_dtype, isdense, isscalarlike,
7
- matrix, validateaxis, getdtype)
9
+ get_sum_dtype, isdense, isscalarlike, _todata,
10
+ matrix, validateaxis, getdtype, is_pydata_spmatrix)
11
+ from scipy._lib._sparse import SparseABC, issparse
8
12
 
9
13
  from ._matrix import spmatrix
10
14
 
@@ -13,6 +17,7 @@ __all__ = ['isspmatrix', 'issparse', 'sparray',
13
17
 
14
18
 
15
19
  class SparseWarning(Warning):
20
+ """General warning for :mod:`scipy.sparse`."""
16
21
  pass
17
22
 
18
23
 
@@ -21,6 +26,9 @@ class SparseFormatWarning(SparseWarning):
21
26
 
22
27
 
23
28
  class SparseEfficiencyWarning(SparseWarning):
29
+ """The warning emitted when the operation is
30
+ inefficient for sparse matrices.
31
+ """
24
32
  pass
25
33
 
26
34
 
@@ -58,7 +66,23 @@ _ufuncs_with_fixed_point_at_zero = frozenset([
58
66
  MAXPRINT = 50
59
67
 
60
68
 
61
- class _spbase:
69
+ # helper dicts to manipulate comparison operators
70
+ # We negate operators (with warning) when all implicit values would be True
71
+ op_neg = {operator.eq: operator.ne, operator.ne: operator.eq,
72
+ operator.lt: operator.ge, operator.ge: operator.lt,
73
+ operator.gt: operator.le, operator.le: operator.gt}
74
+
75
+
76
+ # We use symbolic version of operators in warning messages.
77
+ op_sym = {operator.eq: '==', operator.ge: '>=', operator.le: '<=',
78
+ operator.ne: '!=', operator.gt: '>', operator.lt: '<'}
79
+
80
+
81
+ # `_spbase` is a subclass of `SparseABC`.
82
+ # This allows other submodules to check for instances of sparse subclasses
83
+ # via `scipy._lib._sparse.issparse`, without introducing
84
+ # an import dependency on `scipy.sparse`.
85
+ class _spbase(SparseABC):
62
86
  """ This class provides a base class for all sparse arrays. It
63
87
  cannot be instantiated. Most of the work is provided by subclasses.
64
88
  """
@@ -133,7 +157,7 @@ class _spbase:
133
157
 
134
158
  Parameters
135
159
  ----------
136
- shape : length-2 tuple of ints
160
+ shape : tuple of ints
137
161
  The new shape should be compatible with the original shape.
138
162
  order : {'C', 'F'}, optional
139
163
  Read the elements using this index order. 'C' means to read and
@@ -465,18 +489,94 @@ class _spbase:
465
489
  ####################################################################
466
490
 
467
491
  def multiply(self, other):
468
- """Point-wise multiplication by another array/matrix."""
492
+ """Element-wise multiplication by another array/matrix."""
469
493
  if isscalarlike(other):
470
494
  return self._mul_scalar(other)
471
- return self.tocsr().multiply(other)
495
+
496
+ if self.ndim < 3:
497
+ return self.tocsr()._multiply_2d_with_broadcasting(other)
498
+
499
+ if not (issparse(other) or isdense(other)):
500
+ # If it's a list or whatever, treat it like an array
501
+ other_a = np.asanyarray(other)
502
+ if other_a.ndim == 0 and other_a.dtype == np.object_:
503
+ # numpy creates a 0d object array if all else fails.
504
+ # Not interpretable as an array; return NotImplemented so
505
+ # other's __rmul__ can kick in if that's implemented.
506
+ return NotImplemented
507
+ # Allow custom sparse class indicated by attr sparse gh-6520
508
+ try:
509
+ other.shape
510
+ except AttributeError:
511
+ other = other_a
512
+
513
+ if self.shape != other.shape:
514
+ raise ValueError("inconsistent shapes: >2D multiply() does not yet "
515
+ "support broadcasting")
516
+
517
+ # self is >2D so must be COO
518
+ if isdense(other):
519
+ data = np.multiply(self.data, other[self.coords])
520
+ result = self.copy()
521
+ result.data = data.view(np.ndarray).ravel()
522
+ return result
523
+
524
+ elif issparse(other):
525
+ csr_self = self.reshape(1, -1).tocsr()
526
+ csr_other = other.reshape(1, -1).tocsr()
527
+ return csr_self._binopt(csr_other, '_elmul_').reshape(self.shape)
528
+
529
+ else:
530
+ # Not scalar, dense or sparse. Return NotImplemented so that
531
+ # other's __rmul__ can kick in if that's implemented.
532
+ return NotImplemented
533
+
534
+ def _maximum_minimum(self, other, np_op):
535
+ if not (issparse(other) or isdense(other) or isscalarlike(other)):
536
+ # If it's a list or whatever, treat it like an array
537
+ other_a = np.asanyarray(other)
538
+ if other_a.ndim == 0 and other_a.dtype == np.object_:
539
+ # numpy creates a 0d object array if all else fails.
540
+ # We don't know how to handle it either.
541
+ raise NotImplementedError('maximum or minimum with an unrecognized '
542
+ 'array type is not supported')
543
+ # Allow custom sparse class indicated by attr sparse gh-6520
544
+ try:
545
+ other.shape
546
+ except AttributeError:
547
+ other = other_a
548
+
549
+ if isscalarlike(other):
550
+ if np_op(0, other):
551
+ pos_neg = 'positive' if np_op == np.maximum else 'negative'
552
+ warn(f"Taking {np_op.__name__} with a {pos_neg} number results in a"
553
+ " dense matrix.", SparseEfficiencyWarning, stacklevel=3)
554
+ return self.__class__(np_op(self.toarray(), other))
555
+ else:
556
+ csr_self = (self if self.ndim < 3 else self.reshape(1, -1)).tocsr()
557
+ result = csr_self._scalar_binopt(other, np_op)
558
+ return result if self.ndim < 3 else result.tocoo().reshape(self.shape)
559
+ elif isdense(other):
560
+ return np_op(self.todense(), other)
561
+ elif issparse(other):
562
+ if self.shape != other.shape:
563
+ raise ValueError(f"inconsistent shapes {self.shape=} {other.shape=}")
564
+ if self.ndim < 3: # shape is same so other.ndim < 3
565
+ return self.tocsr()._binopt(other, f'_{np_op.__name__}_')
566
+ csr_self = self.reshape(1, -1).tocsr()
567
+ csr_other = other.reshape(1, -1).tocsr()
568
+ result = csr_self._binopt(csr_other, f'_{np_op.__name__}_')
569
+ return result.tocoo().reshape(self.shape)
570
+ else:
571
+ raise ValueError("Operands not compatible.")
472
572
 
473
573
  def maximum(self, other):
474
574
  """Element-wise maximum between this and another array/matrix."""
475
- return self.tocsr().maximum(other)
575
+ return self._maximum_minimum(other, np.maximum)
476
576
 
477
577
  def minimum(self, other):
478
578
  """Element-wise minimum between this and another array/matrix."""
479
- return self.tocsr().minimum(other)
579
+ return self._maximum_minimum(other, np.minimum)
480
580
 
481
581
  def dot(self, other):
482
582
  """Ordinary dot product
@@ -506,23 +606,96 @@ class _spbase:
506
606
  else:
507
607
  return self.tocsr()._broadcast_to(shape, copy)
508
608
 
609
+ def _comparison(self, other, op):
610
+ # We convert to CSR format and use methods _binopt or _scalar_binopt
611
+ # If ndim>2 we reshape to 2D, compare and then reshape back to nD
612
+ if not (issparse(other) or isdense(other) or isscalarlike(other)):
613
+ if is_pydata_spmatrix(other):
614
+ # cannot compare with pydata other, but it might compare with us.
615
+ return NotImplemented
616
+ # If it's a list or whatever, treat it like an array
617
+ other_a = np.asanyarray(other)
618
+ if other_a.ndim == 0 and other_a.dtype == np.object_:
619
+ # numpy creates a 0d object array if all else fails.
620
+ # Not interpretable as an array; return NotImplemented so
621
+ # other's dunder methods can kick in if implemented.
622
+ return NotImplemented
623
+ # Allow custom sparse class indicated by attr sparse gh-6520
624
+ try:
625
+ other.shape
626
+ except AttributeError:
627
+ other = other_a
628
+
629
+ if isscalarlike(other):
630
+ if not op(0, other):
631
+ if np.isnan(other): # op is not `ne`, so results are all False.
632
+ return self.__class__(self.shape, dtype=np.bool_)
633
+ else:
634
+ csr_self = (self if self.ndim < 3 else self.reshape(1, -1)).tocsr()
635
+ res = csr_self._scalar_binopt(other, op)
636
+ return res if self.ndim < 3 else res.tocoo().reshape(self.shape)
637
+ else:
638
+ warn(f"Comparing a sparse matrix with {other} using {op_sym[op]} "
639
+ f"is inefficient. Try using {op_sym[op_neg[op]]} instead.",
640
+ SparseEfficiencyWarning, stacklevel=3)
641
+ if np.isnan(other):
642
+ # op is `ne` cuz op(0, other) and isnan(other). Return all True.
643
+ return self.__class__(np.ones(self.shape, dtype=np.bool_))
644
+
645
+ # op is eq, le, or ge. Use negated op and then negate.
646
+ csr_self = (self if self.ndim < 3 else self.reshape(1, -1)).tocsr()
647
+ inv = csr_self._scalar_binopt(other, op_neg[op])
648
+ all_true = csr_self.__class__(np.ones(csr_self.shape, dtype=np.bool_))
649
+ result = all_true - inv
650
+ return result if self.ndim < 3 else result.tocoo().reshape(self.shape)
651
+
652
+ elif isdense(other):
653
+ return op(self.todense(), other)
654
+
655
+ elif issparse(other):
656
+ # TODO sparse broadcasting
657
+ if self.shape != other.shape:
658
+ # eq and ne return True or False instead of an array when the shapes
659
+ # don't match. Numpy doesn't do this. Is this what we want?
660
+ if op in (operator.eq, operator.ne):
661
+ return op is operator.ne
662
+ raise ValueError("inconsistent shape")
663
+
664
+ csr_self = (self if self.ndim < 3 else self.reshape(1, -1)).tocsr()
665
+ csr_other = (other if other.ndim < 3 else other.reshape(1, -1)).tocsr()
666
+ if not op(0, 0):
667
+ result = csr_self._binopt(csr_other, f'_{op.__name__}_')
668
+ return result if self.ndim < 3 else result.tocoo().reshape(self.shape)
669
+ else:
670
+ # result will not be sparse. Use negated op and then negate.
671
+ warn(f"Comparing two sparse matrices using {op_sym[op]} "
672
+ f"is inefficient. Try using {op_sym[op_neg[op]]} instead.",
673
+ SparseEfficiencyWarning, stacklevel=3)
674
+ inv = csr_self._binopt(csr_other, f'_{op_neg[op].__name__}_')
675
+ all_true = csr_self.__class__(np.ones(csr_self.shape, dtype=np.bool_))
676
+ result = all_true - inv
677
+ return result if self.ndim < 3 else result.tocoo().reshape(self.shape)
678
+ else:
679
+ # cannot compare with other, but it might compare with us.
680
+ return NotImplemented
681
+
509
682
  def __eq__(self, other):
510
- return self.tocsr().__eq__(other)
683
+ return self._comparison(other, operator.eq)
511
684
 
512
685
  def __ne__(self, other):
513
- return self.tocsr().__ne__(other)
686
+ return self._comparison(other, operator.ne)
514
687
 
515
688
  def __lt__(self, other):
516
- return self.tocsr().__lt__(other)
689
+ return self._comparison(other, operator.lt)
517
690
 
518
691
  def __gt__(self, other):
519
- return self.tocsr().__gt__(other)
692
+ return self._comparison(other, operator.gt)
520
693
 
521
694
  def __le__(self, other):
522
- return self.tocsr().__le__(other)
695
+ return self._comparison(other, operator.le)
523
696
 
524
697
  def __ge__(self, other):
525
- return self.tocsr().__ge__(other)
698
+ return self._comparison(other, operator.ge)
526
699
 
527
700
  def __abs__(self):
528
701
  return abs(self.tocsr())
@@ -637,12 +810,12 @@ class _spbase:
637
810
 
638
811
  # If it's a list or whatever, treat it like an array
639
812
  other_a = np.asanyarray(other)
640
-
641
813
  if other_a.ndim == 0 and other_a.dtype == np.object_:
814
+ # numpy creates a 0d object array if all else fails.
642
815
  # Not interpretable as an array; return NotImplemented so that
643
816
  # other's __rmatmul__ can kick in if that's implemented.
644
817
  return NotImplemented
645
-
818
+ # Allow custom sparse class indicated by attr sparse gh-6520
646
819
  try:
647
820
  other.shape
648
821
  except AttributeError:
@@ -742,6 +915,21 @@ class _spbase:
742
915
  ####################
743
916
 
744
917
  def _divide(self, other, true_divide=False, rdivide=False):
918
+ # Do we need to continue to support true_divide and divide?
919
+ if not (issparse(other) or isdense(other) or isscalarlike(other)):
920
+ # If it's a list or whatever, treat it like an array
921
+ other_a = np.asanyarray(other)
922
+ if other_a.ndim == 0 and other_a.dtype == np.object_:
923
+ # numpy creates a 0d object array if all else fails.
924
+ # Not interpretable as an array; return NotImplemented so that
925
+ # other's __rdiv__ can kick in if that's implemented.
926
+ return NotImplemented
927
+ # Allow custom sparse class indicated by attr sparse gh-6520
928
+ try:
929
+ other.shape
930
+ except AttributeError:
931
+ other = other_a
932
+
745
933
  if isscalarlike(other):
746
934
  if rdivide:
747
935
  if true_divide:
@@ -777,12 +965,16 @@ class _spbase:
777
965
  if rdivide:
778
966
  return other._divide(self, true_divide, rdivide=False)
779
967
 
780
- self_csr = self.tocsr()
968
+ csr_self = (self if self.ndim < 3 else self.reshape(1, -1)).tocsr()
969
+ csr_other = (other if self.ndim < 3 else other.reshape(1, -1)).tocsr()
781
970
  if true_divide and np.can_cast(self.dtype, np.float64):
782
- return self_csr.astype(np.float64)._divide_sparse(other)
971
+ result = csr_self.astype(np.float64)._divide_sparse(csr_other)
783
972
  else:
784
- return self_csr._divide_sparse(other)
973
+ result = csr_self._divide_sparse(csr_other)
974
+ return result if self.ndim < 3 else result.reshape(self.shape)
785
975
  else:
976
+ # not scalar, dense or sparse. Return NotImplemented so
977
+ # other's __rdiv__ can kick in if that's implemented.
786
978
  return NotImplemented
787
979
 
788
980
  def __truediv__(self, other):
@@ -1133,57 +1325,44 @@ class _spbase:
1133
1325
  numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
1134
1326
 
1135
1327
  """
1136
- validateaxis(axis)
1328
+ axis = validateaxis(axis, ndim=self.ndim)
1137
1329
 
1138
1330
  # Mimic numpy's casting.
1139
1331
  res_dtype = get_sum_dtype(self.dtype)
1140
1332
 
1141
- if self.ndim == 1:
1142
- if axis not in (None, -1, 0):
1143
- raise ValueError("axis must be None, -1 or 0")
1144
- ret = (self @ np.ones(self.shape, dtype=res_dtype)).astype(dtype)
1145
-
1146
- if out is not None:
1147
- if any(dim != 1 for dim in out.shape):
1148
- raise ValueError("dimensions do not match")
1149
- out[...] = ret
1150
- return ret
1151
-
1152
- # We use multiplication by a matrix of ones to achieve this.
1153
- # For some sparse array formats more efficient methods are
1154
- # possible -- these should override this function.
1155
- M, N = self.shape
1156
-
1333
+ # Note: all valid 1D axis values are canonically `None`.
1157
1334
  if axis is None:
1158
- # sum over rows and columns
1159
- return (
1160
- self @ self._ascontainer(np.ones((N, 1), dtype=res_dtype))
1161
- ).sum(dtype=dtype, out=out)
1162
-
1163
- if axis < 0:
1164
- axis += 2
1165
-
1166
- # axis = 0 or 1 now
1167
- if axis == 0:
1168
- # sum over columns
1169
- ret = self._ascontainer(
1170
- np.ones((1, M), dtype=res_dtype)
1171
- ) @ self
1335
+ if self.nnz == 0:
1336
+ return np.sum(self._ascontainer([0]), dtype=dtype or res_dtype, out=out)
1337
+ return np.sum(self._ascontainer(_todata(self)), dtype=dtype, out=out)
1338
+ elif isspmatrix(self):
1339
+ # Ensure spmatrix sums stay 2D
1340
+ new_shape = (1, self.shape[1]) if axis == (0,) else (self.shape[0], 1)
1172
1341
  else:
1173
- # sum over rows
1174
- ret = self @ self._ascontainer(
1175
- np.ones((N, 1), dtype=res_dtype)
1176
- )
1342
+ new_shape = tuple(self.shape[i] for i in range(self.ndim) if i not in axis)
1177
1343
 
1178
- if out is not None:
1179
- if isinstance(self, sparray):
1180
- ret_shape = ret.shape[:axis] + ret.shape[axis + 1:]
1181
- else:
1182
- ret_shape = ret.shape
1183
- if out.shape != ret_shape:
1184
- raise ValueError("dimensions do not match")
1344
+ if out is None:
1345
+ # create out array with desired dtype
1346
+ out = self._ascontainer(np.zeros(new_shape, dtype=dtype or res_dtype))
1347
+ else:
1348
+ if out.shape != new_shape:
1349
+ raise ValueError("out dimensions do not match shape")
1185
1350
 
1186
- return ret.sum(axis=axis, dtype=dtype, out=out)
1351
+ if self.ndim > 2:
1352
+ return self._sum_nd(axis, res_dtype, out)
1353
+
1354
+ # We use multiplication by a matrix of ones to sum.
1355
+ # For some sparse array formats more efficient methods are
1356
+ # possible -- these should override this function.
1357
+ if axis == (0,):
1358
+ ones = self._ascontainer(np.ones((1, self.shape[0]), dtype=res_dtype))
1359
+ # sets dtype while loading into out
1360
+ out[...] = (ones @ self).reshape(new_shape)
1361
+ else: # axis == (1,)
1362
+ ones = self._ascontainer(np.ones((self.shape[1], 1), dtype=res_dtype))
1363
+ # sets dtype while loading into out
1364
+ out[...] = (self @ ones).reshape(new_shape)
1365
+ return out
1187
1366
 
1188
1367
  def mean(self, axis=None, dtype=None, out=None):
1189
1368
  """
@@ -1222,43 +1401,24 @@ class _spbase:
1222
1401
  numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
1223
1402
 
1224
1403
  """
1225
- validateaxis(axis)
1404
+ axis = validateaxis(axis, ndim=self.ndim)
1226
1405
 
1227
- res_dtype = self.dtype.type
1228
1406
  integral = (np.issubdtype(self.dtype, np.integer) or
1229
1407
  np.issubdtype(self.dtype, np.bool_))
1230
1408
 
1231
- # output dtype
1232
- if dtype is None:
1233
- if integral:
1234
- res_dtype = np.float64
1235
- else:
1236
- res_dtype = np.dtype(dtype).type
1237
-
1238
1409
  # intermediate dtype for summation
1239
- inter_dtype = np.float64 if integral else res_dtype
1410
+ inter_dtype = np.float64 if integral else self.dtype
1240
1411
  inter_self = self.astype(inter_dtype)
1241
1412
 
1242
- if self.ndim == 1:
1243
- if axis not in (None, -1, 0):
1244
- raise ValueError("axis must be None, -1 or 0")
1245
- res = inter_self / self.shape[-1]
1246
- return res.sum(dtype=res_dtype, out=out)
1247
-
1248
1413
  if axis is None:
1249
- return (inter_self / (self.shape[0] * self.shape[1]))\
1250
- .sum(dtype=res_dtype, out=out)
1251
-
1252
- if axis < 0:
1253
- axis += 2
1254
-
1255
- # axis = 0 or 1 now
1256
- if axis == 0:
1257
- return (inter_self * (1.0 / self.shape[0])).sum(
1258
- axis=0, dtype=res_dtype, out=out)
1414
+ denom = math.prod(self.shape)
1259
1415
  else:
1260
- return (inter_self * (1.0 / self.shape[1])).sum(
1261
- axis=1, dtype=res_dtype, out=out)
1416
+ denom = math.prod(self.shape[ax] for ax in axis)
1417
+ res = (inter_self * (1.0 / denom)).sum(axis=axis, dtype=inter_dtype, out=out)
1418
+ if dtype is not None and out is None:
1419
+ return res.astype(dtype, copy=False)
1420
+ return res
1421
+
1262
1422
 
1263
1423
  def diagonal(self, k=0):
1264
1424
  """Returns the kth diagonal of the array/matrix.
@@ -1394,42 +1554,31 @@ class _spbase:
1394
1554
  class sparray:
1395
1555
  """A namespace class to separate sparray from spmatrix"""
1396
1556
 
1557
+ @classmethod
1558
+ def __class_getitem__(cls, arg, /):
1559
+ """
1560
+ Return a parametrized wrapper around the `~scipy.sparse.sparray` type.
1397
1561
 
1398
- sparray.__doc__ = _spbase.__doc__
1399
-
1562
+ .. versionadded:: 1.16.0
1400
1563
 
1401
- def issparse(x):
1402
- """Is `x` of a sparse array or sparse matrix type?
1564
+ Returns
1565
+ -------
1566
+ alias : types.GenericAlias
1567
+ A parametrized `~scipy.sparse.sparray` type.
1403
1568
 
1404
- Parameters
1405
- ----------
1406
- x
1407
- object to check for being a sparse array or sparse matrix
1569
+ Examples
1570
+ --------
1571
+ >>> import numpy as np
1572
+ >>> from scipy.sparse import coo_array
1408
1573
 
1409
- Returns
1410
- -------
1411
- bool
1412
- True if `x` is a sparse array or a sparse matrix, False otherwise
1574
+ >>> coo_array[np.int8, tuple[int]]
1575
+ scipy.sparse._coo.coo_array[numpy.int8, tuple[int]]
1576
+ """
1577
+ from types import GenericAlias
1578
+ return GenericAlias(cls, arg)
1413
1579
 
1414
- Notes
1415
- -----
1416
- Use `isinstance(x, sp.sparse.sparray)` to check between an array or matrix.
1417
- Use `a.format` to check the sparse format, e.g. `a.format == 'csr'`.
1418
1580
 
1419
- Examples
1420
- --------
1421
- >>> import numpy as np
1422
- >>> from scipy.sparse import csr_array, csr_matrix, issparse
1423
- >>> issparse(csr_matrix([[5]]))
1424
- True
1425
- >>> issparse(csr_array([[5]]))
1426
- True
1427
- >>> issparse(np.array([[5]]))
1428
- False
1429
- >>> issparse(5)
1430
- False
1431
- """
1432
- return isinstance(x, _spbase)
1581
+ sparray.__doc__ = _spbase.__doc__
1433
1582
 
1434
1583
 
1435
1584
  def isspmatrix(x):
scipy/sparse/_bsr.py CHANGED
@@ -172,8 +172,9 @@ class _bsr_base(_cs_matrix, _minmax_mixin):
172
172
 
173
173
  # check index pointer
174
174
  if (len(self.indptr) != M//R + 1):
175
- raise ValueError("index pointer size (%d) should be (%d)" %
176
- (len(self.indptr), M//R + 1))
175
+ raise ValueError(
176
+ f"index pointer size ({len(self.indptr)}) should be ({M//R + 1})"
177
+ )
177
178
  if (self.indptr[0] != 0):
178
179
  raise ValueError("index pointer should start with 0")
179
180
 
@@ -190,8 +191,10 @@ class _bsr_base(_cs_matrix, _minmax_mixin):
190
191
  # check format validity (more expensive)
191
192
  if self.nnz > 0:
192
193
  if self.indices.max() >= N//C:
193
- raise ValueError("column index values must be < %d (now max %d)"
194
- % (N//C, self.indices.max()))
194
+ raise ValueError(
195
+ f"column index values must be < {N//C}"
196
+ f" (now max {self.indices.max()})"
197
+ )
195
198
  if self.indices.min() < 0:
196
199
  raise ValueError("column index values must be >= 0")
197
200
  if np.diff(self.indptr).min() < 0: