scipy 1.15.2__cp312-cp312-win_amd64.whl → 1.15.3__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. scipy/__config__.py +6 -6
  2. scipy/__init__.py +3 -3
  3. scipy/_lib/_array_api.py +11 -0
  4. scipy/_lib/_ccallback_c.cp312-win_amd64.dll.a +0 -0
  5. scipy/_lib/_ccallback_c.cp312-win_amd64.pyd +0 -0
  6. scipy/_lib/_fpumode.cp312-win_amd64.dll.a +0 -0
  7. scipy/_lib/_fpumode.cp312-win_amd64.pyd +0 -0
  8. scipy/_lib/_test_ccallback.cp312-win_amd64.dll.a +0 -0
  9. scipy/_lib/_test_ccallback.cp312-win_amd64.pyd +0 -0
  10. scipy/_lib/_test_deprecation_call.cp312-win_amd64.dll.a +0 -0
  11. scipy/_lib/_test_deprecation_call.cp312-win_amd64.pyd +0 -0
  12. scipy/_lib/_test_deprecation_def.cp312-win_amd64.dll.a +0 -0
  13. scipy/_lib/_test_deprecation_def.cp312-win_amd64.pyd +0 -0
  14. scipy/_lib/_uarray/_uarray.cp312-win_amd64.dll.a +0 -0
  15. scipy/_lib/_uarray/_uarray.cp312-win_amd64.pyd +0 -0
  16. scipy/_lib/messagestream.cp312-win_amd64.dll.a +0 -0
  17. scipy/_lib/messagestream.cp312-win_amd64.pyd +0 -0
  18. scipy/_lib/tests/test_array_api.py +5 -1
  19. scipy/cluster/_hierarchy.cp312-win_amd64.dll.a +0 -0
  20. scipy/cluster/_hierarchy.cp312-win_amd64.pyd +0 -0
  21. scipy/cluster/_optimal_leaf_ordering.cp312-win_amd64.dll.a +0 -0
  22. scipy/cluster/_optimal_leaf_ordering.cp312-win_amd64.pyd +0 -0
  23. scipy/cluster/_vq.cp312-win_amd64.dll.a +0 -0
  24. scipy/cluster/_vq.cp312-win_amd64.pyd +0 -0
  25. scipy/fft/_pocketfft/pypocketfft.cp312-win_amd64.dll.a +0 -0
  26. scipy/fft/_pocketfft/pypocketfft.cp312-win_amd64.pyd +0 -0
  27. scipy/fftpack/convolve.cp312-win_amd64.dll.a +0 -0
  28. scipy/fftpack/convolve.cp312-win_amd64.pyd +0 -0
  29. scipy/integrate/_dop.cp312-win_amd64.dll.a +0 -0
  30. scipy/integrate/_dop.cp312-win_amd64.pyd +0 -0
  31. scipy/integrate/_ivp/common.py +3 -3
  32. scipy/integrate/_ivp/ivp.py +9 -2
  33. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  34. scipy/integrate/_lsoda.cp312-win_amd64.dll.a +0 -0
  35. scipy/integrate/_lsoda.cp312-win_amd64.pyd +0 -0
  36. scipy/integrate/_odepack.cp312-win_amd64.dll.a +0 -0
  37. scipy/integrate/_odepack.cp312-win_amd64.pyd +0 -0
  38. scipy/integrate/_quadpack.cp312-win_amd64.dll.a +0 -0
  39. scipy/integrate/_quadpack.cp312-win_amd64.pyd +0 -0
  40. scipy/integrate/_tanhsinh.py +14 -12
  41. scipy/integrate/_test_multivariate.cp312-win_amd64.dll.a +0 -0
  42. scipy/integrate/_test_multivariate.cp312-win_amd64.pyd +0 -0
  43. scipy/integrate/_test_odeint_banded.cp312-win_amd64.dll.a +0 -0
  44. scipy/integrate/_test_odeint_banded.cp312-win_amd64.pyd +0 -0
  45. scipy/integrate/_vode.cp312-win_amd64.dll.a +0 -0
  46. scipy/integrate/_vode.cp312-win_amd64.pyd +0 -0
  47. scipy/integrate/tests/test_tanhsinh.py +10 -0
  48. scipy/interpolate/_bspl.cp312-win_amd64.dll.a +0 -0
  49. scipy/interpolate/_bspl.cp312-win_amd64.pyd +0 -0
  50. scipy/interpolate/_dfitpack.cp312-win_amd64.dll.a +0 -0
  51. scipy/interpolate/_dfitpack.cp312-win_amd64.pyd +0 -0
  52. scipy/interpolate/_dierckx.cp312-win_amd64.dll.a +0 -0
  53. scipy/interpolate/_dierckx.cp312-win_amd64.pyd +0 -0
  54. scipy/interpolate/_fitpack.cp312-win_amd64.dll.a +0 -0
  55. scipy/interpolate/_fitpack.cp312-win_amd64.pyd +0 -0
  56. scipy/interpolate/_interpnd.cp312-win_amd64.dll.a +0 -0
  57. scipy/interpolate/_interpnd.cp312-win_amd64.pyd +0 -0
  58. scipy/interpolate/_ppoly.cp312-win_amd64.dll.a +0 -0
  59. scipy/interpolate/_ppoly.cp312-win_amd64.pyd +0 -0
  60. scipy/interpolate/_rbfinterp_pythran.cp312-win_amd64.dll.a +0 -0
  61. scipy/interpolate/_rbfinterp_pythran.cp312-win_amd64.pyd +0 -0
  62. scipy/interpolate/_rgi_cython.cp312-win_amd64.dll.a +0 -0
  63. scipy/interpolate/_rgi_cython.cp312-win_amd64.pyd +0 -0
  64. scipy/io/_fast_matrix_market/_fmm_core.cp312-win_amd64.dll.a +0 -0
  65. scipy/io/_fast_matrix_market/_fmm_core.cp312-win_amd64.pyd +0 -0
  66. scipy/io/_test_fortran.cp312-win_amd64.dll.a +0 -0
  67. scipy/io/_test_fortran.cp312-win_amd64.pyd +0 -0
  68. scipy/io/matlab/_mio5_utils.cp312-win_amd64.dll.a +0 -0
  69. scipy/io/matlab/_mio5_utils.cp312-win_amd64.pyd +0 -0
  70. scipy/io/matlab/_mio_utils.cp312-win_amd64.dll.a +0 -0
  71. scipy/io/matlab/_mio_utils.cp312-win_amd64.pyd +0 -0
  72. scipy/io/matlab/_streams.cp312-win_amd64.dll.a +0 -0
  73. scipy/io/matlab/_streams.cp312-win_amd64.pyd +0 -0
  74. scipy/linalg/_cythonized_array_utils.cp312-win_amd64.dll.a +0 -0
  75. scipy/linalg/_cythonized_array_utils.cp312-win_amd64.pyd +0 -0
  76. scipy/linalg/_decomp_interpolative.cp312-win_amd64.dll.a +0 -0
  77. scipy/linalg/_decomp_interpolative.cp312-win_amd64.pyd +0 -0
  78. scipy/linalg/_decomp_lu_cython.cp312-win_amd64.dll.a +0 -0
  79. scipy/linalg/_decomp_lu_cython.cp312-win_amd64.pyd +0 -0
  80. scipy/linalg/_decomp_update.cp312-win_amd64.dll.a +0 -0
  81. scipy/linalg/_decomp_update.cp312-win_amd64.pyd +0 -0
  82. scipy/linalg/_fblas.cp312-win_amd64.dll.a +0 -0
  83. scipy/linalg/_fblas.cp312-win_amd64.pyd +0 -0
  84. scipy/linalg/_flapack.cp312-win_amd64.dll.a +0 -0
  85. scipy/linalg/_flapack.cp312-win_amd64.pyd +0 -0
  86. scipy/linalg/_linalg_pythran.cp312-win_amd64.dll.a +0 -0
  87. scipy/linalg/_linalg_pythran.cp312-win_amd64.pyd +0 -0
  88. scipy/linalg/_matfuncs_expm.cp312-win_amd64.dll.a +0 -0
  89. scipy/linalg/_matfuncs_expm.cp312-win_amd64.pyd +0 -0
  90. scipy/linalg/_matfuncs_sqrtm_triu.cp312-win_amd64.dll.a +0 -0
  91. scipy/linalg/_matfuncs_sqrtm_triu.cp312-win_amd64.pyd +0 -0
  92. scipy/linalg/_solve_toeplitz.cp312-win_amd64.dll.a +0 -0
  93. scipy/linalg/_solve_toeplitz.cp312-win_amd64.pyd +0 -0
  94. scipy/linalg/cython_blas.cp312-win_amd64.dll.a +0 -0
  95. scipy/linalg/cython_blas.cp312-win_amd64.pyd +0 -0
  96. scipy/linalg/cython_lapack.cp312-win_amd64.dll.a +0 -0
  97. scipy/linalg/cython_lapack.cp312-win_amd64.pyd +0 -0
  98. scipy/linalg/tests/test_interpolative.py +17 -0
  99. scipy/ndimage/_ctest.cp312-win_amd64.dll.a +0 -0
  100. scipy/ndimage/_ctest.cp312-win_amd64.pyd +0 -0
  101. scipy/ndimage/_cytest.cp312-win_amd64.dll.a +0 -0
  102. scipy/ndimage/_cytest.cp312-win_amd64.pyd +0 -0
  103. scipy/ndimage/_nd_image.cp312-win_amd64.dll.a +0 -0
  104. scipy/ndimage/_nd_image.cp312-win_amd64.pyd +0 -0
  105. scipy/ndimage/_ndimage_api.py +2 -1
  106. scipy/ndimage/_ni_label.cp312-win_amd64.dll.a +0 -0
  107. scipy/ndimage/_ni_label.cp312-win_amd64.pyd +0 -0
  108. scipy/ndimage/_rank_filter_1d.cp312-win_amd64.dll.a +0 -0
  109. scipy/ndimage/_rank_filter_1d.cp312-win_amd64.pyd +0 -0
  110. scipy/ndimage/tests/test_filters.py +14 -0
  111. scipy/odr/__odrpack.cp312-win_amd64.dll.a +0 -0
  112. scipy/odr/__odrpack.cp312-win_amd64.pyd +0 -0
  113. scipy/optimize/_bglu_dense.cp312-win_amd64.dll.a +0 -0
  114. scipy/optimize/_bglu_dense.cp312-win_amd64.pyd +0 -0
  115. scipy/optimize/_bracket.py +35 -8
  116. scipy/optimize/_cobyla.cp312-win_amd64.dll.a +0 -0
  117. scipy/optimize/_cobyla.cp312-win_amd64.pyd +0 -0
  118. scipy/optimize/_cython_nnls.cp312-win_amd64.dll.a +0 -0
  119. scipy/optimize/_cython_nnls.cp312-win_amd64.pyd +0 -0
  120. scipy/optimize/_direct.cp312-win_amd64.dll.a +0 -0
  121. scipy/optimize/_direct.cp312-win_amd64.pyd +0 -0
  122. scipy/optimize/_group_columns.cp312-win_amd64.dll.a +0 -0
  123. scipy/optimize/_group_columns.cp312-win_amd64.pyd +0 -0
  124. scipy/optimize/_highspy/_core.cp312-win_amd64.dll.a +0 -0
  125. scipy/optimize/_highspy/_core.cp312-win_amd64.pyd +0 -0
  126. scipy/optimize/_highspy/_highs_options.cp312-win_amd64.dll.a +0 -0
  127. scipy/optimize/_highspy/_highs_options.cp312-win_amd64.pyd +0 -0
  128. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  129. scipy/optimize/_lbfgsb.cp312-win_amd64.dll.a +0 -0
  130. scipy/optimize/_lbfgsb.cp312-win_amd64.pyd +0 -0
  131. scipy/optimize/_linprog_highs.py +9 -9
  132. scipy/optimize/_linprog_util.py +4 -3
  133. scipy/optimize/_lsap.cp312-win_amd64.dll.a +0 -0
  134. scipy/optimize/_lsap.cp312-win_amd64.pyd +0 -0
  135. scipy/optimize/_lsq/givens_elimination.cp312-win_amd64.dll.a +0 -0
  136. scipy/optimize/_lsq/givens_elimination.cp312-win_amd64.pyd +0 -0
  137. scipy/optimize/_minpack.cp312-win_amd64.dll.a +0 -0
  138. scipy/optimize/_minpack.cp312-win_amd64.pyd +0 -0
  139. scipy/optimize/_moduleTNC.cp312-win_amd64.dll.a +0 -0
  140. scipy/optimize/_moduleTNC.cp312-win_amd64.pyd +0 -0
  141. scipy/optimize/_pava_pybind.cp312-win_amd64.dll.a +0 -0
  142. scipy/optimize/_pava_pybind.cp312-win_amd64.pyd +0 -0
  143. scipy/optimize/_slsqp.cp312-win_amd64.dll.a +0 -0
  144. scipy/optimize/_slsqp.cp312-win_amd64.pyd +0 -0
  145. scipy/optimize/_trlib/_trlib.cp312-win_amd64.dll.a +0 -0
  146. scipy/optimize/_trlib/_trlib.cp312-win_amd64.pyd +0 -0
  147. scipy/optimize/_zeros.cp312-win_amd64.dll.a +0 -0
  148. scipy/optimize/_zeros.cp312-win_amd64.pyd +0 -0
  149. scipy/optimize/cython_optimize/_zeros.cp312-win_amd64.dll.a +0 -0
  150. scipy/optimize/cython_optimize/_zeros.cp312-win_amd64.pyd +0 -0
  151. scipy/optimize/tests/test_bracket.py +35 -0
  152. scipy/signal/_max_len_seq_inner.cp312-win_amd64.dll.a +0 -0
  153. scipy/signal/_max_len_seq_inner.cp312-win_amd64.pyd +0 -0
  154. scipy/signal/_peak_finding_utils.cp312-win_amd64.dll.a +0 -0
  155. scipy/signal/_peak_finding_utils.cp312-win_amd64.pyd +0 -0
  156. scipy/signal/_short_time_fft.py +34 -6
  157. scipy/signal/_signaltools.py +4 -1
  158. scipy/signal/_sigtools.cp312-win_amd64.dll.a +0 -0
  159. scipy/signal/_sigtools.cp312-win_amd64.pyd +0 -0
  160. scipy/signal/_sosfilt.cp312-win_amd64.dll.a +0 -0
  161. scipy/signal/_sosfilt.cp312-win_amd64.pyd +0 -0
  162. scipy/signal/_spline.cp312-win_amd64.dll.a +0 -0
  163. scipy/signal/_spline.cp312-win_amd64.pyd +0 -0
  164. scipy/signal/_upfirdn_apply.cp312-win_amd64.dll.a +0 -0
  165. scipy/signal/_upfirdn_apply.cp312-win_amd64.pyd +0 -0
  166. scipy/signal/tests/_scipy_spectral_test_shim.py +3 -11
  167. scipy/signal/tests/test_short_time_fft.py +10 -2
  168. scipy/signal/tests/test_signaltools.py +5 -0
  169. scipy/sparse/_base.py +2 -15
  170. scipy/sparse/_compressed.py +0 -3
  171. scipy/sparse/_csparsetools.cp312-win_amd64.dll.a +0 -0
  172. scipy/sparse/_csparsetools.cp312-win_amd64.pyd +0 -0
  173. scipy/sparse/_dia.py +0 -3
  174. scipy/sparse/_sparsetools.cp312-win_amd64.dll.a +0 -0
  175. scipy/sparse/_sparsetools.cp312-win_amd64.pyd +0 -0
  176. scipy/sparse/csgraph/_flow.cp312-win_amd64.dll.a +0 -0
  177. scipy/sparse/csgraph/_flow.cp312-win_amd64.pyd +0 -0
  178. scipy/sparse/csgraph/_matching.cp312-win_amd64.dll.a +0 -0
  179. scipy/sparse/csgraph/_matching.cp312-win_amd64.pyd +0 -0
  180. scipy/sparse/csgraph/_min_spanning_tree.cp312-win_amd64.dll.a +0 -0
  181. scipy/sparse/csgraph/_min_spanning_tree.cp312-win_amd64.pyd +0 -0
  182. scipy/sparse/csgraph/_reordering.cp312-win_amd64.dll.a +0 -0
  183. scipy/sparse/csgraph/_reordering.cp312-win_amd64.pyd +0 -0
  184. scipy/sparse/csgraph/_shortest_path.cp312-win_amd64.dll.a +0 -0
  185. scipy/sparse/csgraph/_shortest_path.cp312-win_amd64.pyd +0 -0
  186. scipy/sparse/csgraph/_tools.cp312-win_amd64.dll.a +0 -0
  187. scipy/sparse/csgraph/_tools.cp312-win_amd64.pyd +0 -0
  188. scipy/sparse/csgraph/_traversal.cp312-win_amd64.dll.a +0 -0
  189. scipy/sparse/csgraph/_traversal.cp312-win_amd64.pyd +0 -0
  190. scipy/sparse/linalg/_dsolve/_superlu.cp312-win_amd64.dll.a +0 -0
  191. scipy/sparse/linalg/_dsolve/_superlu.cp312-win_amd64.pyd +0 -0
  192. scipy/sparse/linalg/_eigen/arpack/_arpack.cp312-win_amd64.dll.a +0 -0
  193. scipy/sparse/linalg/_eigen/arpack/_arpack.cp312-win_amd64.pyd +0 -0
  194. scipy/sparse/linalg/_eigen/arpack/arpack.py +5 -3
  195. scipy/sparse/linalg/_expm_multiply.py +8 -3
  196. scipy/sparse/linalg/_interface.py +12 -8
  197. scipy/sparse/linalg/_isolve/_gcrotmk.py +2 -1
  198. scipy/sparse/linalg/_propack/_cpropack.cp312-win_amd64.dll.a +0 -0
  199. scipy/sparse/linalg/_propack/_cpropack.cp312-win_amd64.pyd +0 -0
  200. scipy/sparse/linalg/_propack/_dpropack.cp312-win_amd64.dll.a +0 -0
  201. scipy/sparse/linalg/_propack/_dpropack.cp312-win_amd64.pyd +0 -0
  202. scipy/sparse/linalg/_propack/_spropack.cp312-win_amd64.dll.a +0 -0
  203. scipy/sparse/linalg/_propack/_spropack.cp312-win_amd64.pyd +0 -0
  204. scipy/sparse/linalg/_propack/_zpropack.cp312-win_amd64.dll.a +0 -0
  205. scipy/sparse/linalg/_propack/_zpropack.cp312-win_amd64.pyd +0 -0
  206. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  207. scipy/sparse/linalg/tests/test_interface.py +35 -0
  208. scipy/sparse/linalg/tests/test_pydata_sparse.py +4 -0
  209. scipy/sparse/tests/test_base.py +12 -0
  210. scipy/sparse/tests/test_common1d.py +11 -6
  211. scipy/spatial/_ckdtree.cp312-win_amd64.dll.a +0 -0
  212. scipy/spatial/_ckdtree.cp312-win_amd64.pyd +0 -0
  213. scipy/spatial/_distance_pybind.cp312-win_amd64.dll.a +0 -0
  214. scipy/spatial/_distance_pybind.cp312-win_amd64.pyd +0 -0
  215. scipy/spatial/_distance_wrap.cp312-win_amd64.dll.a +0 -0
  216. scipy/spatial/_distance_wrap.cp312-win_amd64.pyd +0 -0
  217. scipy/spatial/_hausdorff.cp312-win_amd64.dll.a +0 -0
  218. scipy/spatial/_hausdorff.cp312-win_amd64.pyd +0 -0
  219. scipy/spatial/_qhull.cp312-win_amd64.dll.a +0 -0
  220. scipy/spatial/_qhull.cp312-win_amd64.pyd +0 -0
  221. scipy/spatial/_voronoi.cp312-win_amd64.dll.a +0 -0
  222. scipy/spatial/_voronoi.cp312-win_amd64.pyd +0 -0
  223. scipy/spatial/tests/test_qhull.py +99 -0
  224. scipy/spatial/transform/_rotation.cp312-win_amd64.dll.a +0 -0
  225. scipy/spatial/transform/_rotation.cp312-win_amd64.pyd +0 -0
  226. scipy/spatial/transform/tests/test_rotation.py +181 -10
  227. scipy/special/_comb.cp312-win_amd64.dll.a +0 -0
  228. scipy/special/_comb.cp312-win_amd64.pyd +0 -0
  229. scipy/special/_ellip_harm_2.cp312-win_amd64.dll.a +0 -0
  230. scipy/special/_ellip_harm_2.cp312-win_amd64.pyd +0 -0
  231. scipy/special/_gufuncs.cp312-win_amd64.dll.a +0 -0
  232. scipy/special/_gufuncs.cp312-win_amd64.pyd +0 -0
  233. scipy/special/_logsumexp.py +21 -16
  234. scipy/special/_specfun.cp312-win_amd64.dll.a +0 -0
  235. scipy/special/_specfun.cp312-win_amd64.pyd +0 -0
  236. scipy/special/_special_ufuncs.cp312-win_amd64.dll.a +0 -0
  237. scipy/special/_special_ufuncs.cp312-win_amd64.pyd +0 -0
  238. scipy/special/_test_internal.cp312-win_amd64.dll.a +0 -0
  239. scipy/special/_test_internal.cp312-win_amd64.pyd +0 -0
  240. scipy/special/_ufuncs.cp312-win_amd64.dll.a +0 -0
  241. scipy/special/_ufuncs.cp312-win_amd64.pyd +0 -0
  242. scipy/special/_ufuncs_cxx.cp312-win_amd64.dll.a +0 -0
  243. scipy/special/_ufuncs_cxx.cp312-win_amd64.pyd +0 -0
  244. scipy/special/cython_special.cp312-win_amd64.dll.a +0 -0
  245. scipy/special/cython_special.cp312-win_amd64.pyd +0 -0
  246. scipy/special/libsf_error_state.dll +0 -0
  247. scipy/special/libsf_error_state.dll.a +0 -0
  248. scipy/special/tests/test_hyp2f1.py +21 -0
  249. scipy/special/tests/test_logsumexp.py +14 -0
  250. scipy/special/xsf/hyp2f1.h +3 -3
  251. scipy/stats/_ansari_swilk_statistics.cp312-win_amd64.dll.a +0 -0
  252. scipy/stats/_ansari_swilk_statistics.cp312-win_amd64.pyd +0 -0
  253. scipy/stats/_biasedurn.cp312-win_amd64.dll.a +0 -0
  254. scipy/stats/_biasedurn.cp312-win_amd64.pyd +0 -0
  255. scipy/stats/_continuous_distns.py +25 -15
  256. scipy/stats/_levy_stable/levyst.cp312-win_amd64.dll.a +0 -0
  257. scipy/stats/_levy_stable/levyst.cp312-win_amd64.pyd +0 -0
  258. scipy/stats/_mvn.cp312-win_amd64.dll.a +0 -0
  259. scipy/stats/_mvn.cp312-win_amd64.pyd +0 -0
  260. scipy/stats/_qmc_cy.cp312-win_amd64.dll.a +0 -0
  261. scipy/stats/_qmc_cy.cp312-win_amd64.pyd +0 -0
  262. scipy/stats/_rcont/rcont.cp312-win_amd64.dll.a +0 -0
  263. scipy/stats/_rcont/rcont.cp312-win_amd64.pyd +0 -0
  264. scipy/stats/_sobol.cp312-win_amd64.dll.a +0 -0
  265. scipy/stats/_sobol.cp312-win_amd64.pyd +0 -0
  266. scipy/stats/_stats.cp312-win_amd64.dll.a +0 -0
  267. scipy/stats/_stats.cp312-win_amd64.pyd +0 -0
  268. scipy/stats/_stats_pythran.cp312-win_amd64.dll.a +0 -0
  269. scipy/stats/_stats_pythran.cp312-win_amd64.pyd +0 -0
  270. scipy/stats/_unuran/unuran_wrapper.cp312-win_amd64.dll.a +0 -0
  271. scipy/stats/_unuran/unuran_wrapper.cp312-win_amd64.pyd +0 -0
  272. scipy/stats/tests/test_distributions.py +22 -0
  273. scipy/version.py +2 -2
  274. scipy-1.15.3.dist-info/DELVEWHEEL +2 -0
  275. {scipy-1.15.2.dist-info → scipy-1.15.3.dist-info}/METADATA +2 -2
  276. {scipy-1.15.2.dist-info → scipy-1.15.3.dist-info}/RECORD +279 -279
  277. scipy-1.15.2.dist-info/DELVEWHEEL +0 -2
  278. /scipy-1.15.2-cp312-cp312-win_amd64.whl → /scipy-1.15.3-cp312-cp312-win_amd64.whl +0 -0
  279. {scipy-1.15.2.dist-info → scipy-1.15.3.dist-info}/LICENSE.txt +0 -0
  280. {scipy-1.15.2.dist-info → scipy-1.15.3.dist-info}/WHEEL +0 -0
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
  import scipy._lib._elementwise_iterative_method as eim
3
3
  from scipy._lib._util import _RichResult
4
- from scipy._lib._array_api import array_namespace, xp_ravel
4
+ from scipy._lib._array_api import array_namespace, xp_ravel, xp_default_dtype
5
5
 
6
6
  _ELIMITS = -1 # used in _bracket_root
7
7
  _ESTOPONESIDE = 2 # used in _bracket_root
@@ -19,8 +19,17 @@ def _bracket_root_iv(func, xl0, xr0, xmin, xmax, factor, args, maxiter):
19
19
  if (not xp.isdtype(xl0.dtype, "numeric")
20
20
  or xp.isdtype(xl0.dtype, "complex floating")):
21
21
  raise ValueError('`xl0` must be numeric and real.')
22
+ if not xp.isdtype(xl0.dtype, "real floating"):
23
+ xl0 = xp.asarray(xl0, dtype=xp_default_dtype(xp))
24
+
25
+ # If xr0 is not supplied, fill with a dummy value for the sake of
26
+ # broadcasting. We need to wait until xmax has been validated to
27
+ # compute the default value.
28
+ xr0_not_supplied = False
29
+ if xr0 is None:
30
+ xr0 = xp.nan
31
+ xr0_not_supplied = True
22
32
 
23
- xr0 = xl0 + 1 if xr0 is None else xr0
24
33
  xmin = -xp.inf if xmin is None else xmin
25
34
  xmax = xp.inf if xmax is None else xmax
26
35
  factor = 2. if factor is None else factor
@@ -45,6 +54,12 @@ def _bracket_root_iv(func, xl0, xr0, xmin, xmax, factor, args, maxiter):
45
54
  if not xp.all(factor > 1):
46
55
  raise ValueError('All elements of `factor` must be greater than 1.')
47
56
 
57
+ # Calculate the default value of xr0 if a value has not been supplied.
58
+ # Be careful to ensure xr0 is not larger than xmax.
59
+ if xr0_not_supplied:
60
+ xr0 = xl0 + xp.minimum((xmax - xl0)/ 8, xp.asarray(1.0))
61
+ xr0 = xp.astype(xr0, xl0.dtype, copy=False)
62
+
48
63
  maxiter = xp.asarray(maxiter)
49
64
  message = '`maxiter` must be a non-negative integer.'
50
65
  if (not xp.isdtype(maxiter.dtype, "numeric") or maxiter.shape != tuple()
@@ -281,14 +296,22 @@ def _bracket_root(func, xl0, xr0=None, *, xmin=None, xmax=None, factor=None,
281
296
  # `work.status`.
282
297
  # Get the integer indices of the elements that can also stop
283
298
  also_stop = (work.active[i] + work.n) % (2*work.n)
284
- # Check whether they are still active.
285
- # To start, we need to find out where in `work.active` they would
286
- # appear if they are indeed there.
299
+ # Check whether they are still active. We want to find the indices
300
+ # in work.active where the associated values in work.active are
301
+ # contained in also_stop. xp.searchsorted let's us take advantage
302
+ # of work.active being sorted, but requires some hackery because
303
+ # searchsorted solves the separate but related problem of finding
304
+ # the indices where the values in also_stop should be added to
305
+ # maintain sorted order.
287
306
  j = xp.searchsorted(work.active, also_stop)
288
307
  # If the location exceeds the length of the `work.active`, they are
289
- # not there.
290
- j = j[j < work.active.shape[0]]
291
- # Check whether they are still there.
308
+ # not there. This happens when a value in also_stop is larger than
309
+ # the greatest value in work.active. This case needs special handling
310
+ # because we cannot simply check that also_stop == work.active[j].
311
+ mask = j < work.active.shape[0]
312
+ # Note that we also have to use the mask to filter also_stop to ensure
313
+ # that also_stop and j will still have the same shape.
314
+ j, also_stop = j[mask], also_stop[mask]
292
315
  j = j[also_stop == work.active[j]]
293
316
  # Now convert these to boolean indices to use with `work.status`.
294
317
  i = xp.zeros_like(stop)
@@ -407,6 +430,8 @@ def _bracket_minimum_iv(func, xm0, xl0, xr0, xmin, xmax, factor, args, maxiter):
407
430
  if (not xp.isdtype(xm0.dtype, "numeric")
408
431
  or xp.isdtype(xm0.dtype, "complex floating")):
409
432
  raise ValueError('`xm0` must be numeric and real.')
433
+ if not xp.isdtype(xm0.dtype, "real floating"):
434
+ xm0 = xp.asarray(xm0, dtype=xp_default_dtype(xp))
410
435
 
411
436
  xmin = -xp.inf if xmin is None else xmin
412
437
  xmax = xp.inf if xmax is None else xmax
@@ -457,8 +482,10 @@ def _bracket_minimum_iv(func, xm0, xl0, xr0, xmin, xmax, factor, args, maxiter):
457
482
  # of (xmin, xmax).
458
483
  if xl0_not_supplied:
459
484
  xl0 = xm0 - xp.minimum((xm0 - xmin)/16, xp.asarray(0.5))
485
+ xl0 = xp.astype(xl0, xm0.dtype, copy=False)
460
486
  if xr0_not_supplied:
461
487
  xr0 = xm0 + xp.minimum((xmax - xm0)/16, xp.asarray(0.5))
488
+ xr0 = xp.astype(xr0, xm0.dtype, copy=False)
462
489
 
463
490
  maxiter = xp.asarray(maxiter)
464
491
  message = '`maxiter` must be a non-negative integer.'
Binary file
Binary file
@@ -264,11 +264,13 @@ def _highs_wrapper(c, indptr, indices, data, lhs, rhs, lb, ub, integrality, opti
264
264
 
265
265
  # Lagrangians for bounds based on column statuses
266
266
  marg_bnds = np.zeros((2, numcol))
267
+ basis_col_status = basis.col_status
268
+ solution_col_dual = solution.col_dual
267
269
  for ii in range(numcol):
268
- if basis.col_status[ii] == _h.HighsBasisStatus.kLower:
269
- marg_bnds[0, ii] = solution.col_dual[ii]
270
- elif basis.col_status[ii] == _h.HighsBasisStatus.kUpper:
271
- marg_bnds[1, ii] = solution.col_dual[ii]
270
+ if basis_col_status[ii] == _h.HighsBasisStatus.kLower:
271
+ marg_bnds[0, ii] = solution_col_dual[ii]
272
+ elif basis_col_status[ii] == _h.HighsBasisStatus.kUpper:
273
+ marg_bnds[1, ii] = solution_col_dual[ii]
272
274
 
273
275
  res.update(
274
276
  {
Binary file
@@ -23,13 +23,13 @@ from ._highspy._core import(
23
23
  HighsDebugLevel,
24
24
  ObjSense,
25
25
  HighsModelStatus,
26
- )
27
- from ._highspy._core.simplex_constants import (
28
- SimplexStrategy,
29
- SimplexEdgeWeightStrategy,
26
+ simplex_constants as s_c, # [1]
30
27
  )
31
28
  from scipy.sparse import csc_matrix, vstack, issparse
32
29
 
30
+ # [1]: Directly importing from "._highspy._core.simplex_constants"
31
+ # causes problems when reloading.
32
+ # See https://github.com/scipy/scipy/pull/22869 for details.
33
33
 
34
34
  def _highs_to_scipy_status_message(highs_status, highs_message):
35
35
  """Converts HiGHS status number/message to SciPy status number/message"""
@@ -293,13 +293,13 @@ def _linprog_highs(lp, solver, time_limit=None, presolve=True,
293
293
  simplex_dual_edge_weight_strategy,
294
294
  'simplex_dual_edge_weight_strategy',
295
295
  choices={'dantzig': \
296
- SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyDantzig,
296
+ s_c.SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyDantzig,
297
297
  'devex': \
298
- SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyDevex,
298
+ s_c.SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyDevex,
299
299
  'steepest-devex': \
300
- SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyChoose,
300
+ s_c.SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategyChoose,
301
301
  'steepest': \
302
- SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategySteepestEdge,
302
+ s_c.SimplexEdgeWeightStrategy.kSimplexEdgeWeightStrategySteepestEdge,
303
303
  None: None})
304
304
 
305
305
  c, A_ub, b_ub, A_eq, b_eq, bounds, x0, integrality = lp
@@ -334,7 +334,7 @@ def _linprog_highs(lp, solver, time_limit=None, presolve=True,
334
334
  'primal_feasibility_tolerance': primal_feasibility_tolerance,
335
335
  'simplex_dual_edge_weight_strategy':
336
336
  simplex_dual_edge_weight_strategy_enum,
337
- 'simplex_strategy': SimplexStrategy.kSimplexStrategyDual,
337
+ 'simplex_strategy': s_c.SimplexStrategy.kSimplexStrategyDual,
338
338
  'ipm_iteration_limit': maxiter,
339
339
  'simplex_iteration_limit': maxiter,
340
340
  'mip_rel_gap': mip_rel_gap,
@@ -1409,9 +1409,10 @@ def _postsolve(x, postsolve_args, complete=False):
1409
1409
  x = rev(x)
1410
1410
 
1411
1411
  fun = x.dot(c)
1412
- slack = b_ub - A_ub.dot(x) # report slack for ORIGINAL UB constraints
1413
- # report residuals of ORIGINAL EQ constraints
1414
- con = b_eq - A_eq.dot(x)
1412
+ with np.errstate(invalid="ignore"):
1413
+ slack = b_ub - A_ub.dot(x) # report slack for ORIGINAL UB constraints
1414
+ # report residuals of ORIGINAL EQ constraints
1415
+ con = b_eq - A_eq.dot(x)
1415
1416
 
1416
1417
  return x, fun, slack, con
1417
1418
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -352,6 +352,41 @@ class TestBracketRoot:
352
352
  xmin=1)
353
353
  assert not res.success
354
354
 
355
+ def test_bug_fixes(self):
356
+ # 1. Bug in double sided bracket search.
357
+ # Happened in some cases where there are terminations on one side
358
+ # after corresponding searches on other side failed due to reaching the
359
+ # boundary.
360
+
361
+ # https://github.com/scipy/scipy/pull/22560#discussion_r1962853839
362
+ def f(x, p):
363
+ return np.exp(x) - p
364
+
365
+ p = np.asarray([0.29, 0.35])
366
+ res = _bracket_root(f, xl0=-1, xmin=-np.inf, xmax=0, args=(p, ))
367
+
368
+ # https://github.com/scipy/scipy/pull/22560/files#r1962952517
369
+ def f(x, p, c):
370
+ return np.exp(x*c) - p
371
+
372
+ p = [0.32061201, 0.39175242, 0.40047535, 0.50527218, 0.55654373,
373
+ 0.11911647, 0.37507896, 0.66554191]
374
+ c = [1., -1., 1., 1., -1., 1., 1., 1.]
375
+ xl0 = [-7.63108551, 3.27840947, -8.36968526, -1.78124372,
376
+ 0.92201295, -2.48930123, -0.66733533, -0.44606749]
377
+ xr0 = [-6.63108551, 4.27840947, -7.36968526, -0.78124372,
378
+ 1.92201295, -1.48930123, 0., 0.]
379
+ xmin = [-np.inf, 0., -np.inf, -np.inf, 0., -np.inf, -np.inf,
380
+ -np.inf]
381
+ xmax = [0., np.inf, 0., 0., np.inf, 0., 0., 0.]
382
+
383
+ res = _bracket_root(f, xl0=xl0, xr0=xr0, xmin=xmin, xmax=xmax, args=(p, c))
384
+
385
+ # 2. Default xl0 + 1 for xr0 exceeds xmax.
386
+ # https://github.com/scipy/scipy/pull/22560#discussion_r1962947434
387
+ res = _bracket_root(lambda x: x + 0.25, xl0=-0.5, xmin=-np.inf, xmax=0)
388
+ assert res.success
389
+
355
390
 
356
391
  @pytest.mark.skip_xp_backends('array_api_strict', reason=array_api_strict_skip_reason)
357
392
  @pytest.mark.skip_xp_backends('jax.numpy', reason=jax_skip_reason)
@@ -206,14 +206,14 @@ class ShortTimeFFT:
206
206
 
207
207
  It is possible to calculate the SFT of signal parts:
208
208
 
209
- >>> p_q = SFT.nearest_k_p(N // 2)
210
- >>> Sx0 = SFT.stft(x[:p_q])
211
- >>> Sx1 = SFT.stft(x[p_q:])
209
+ >>> N2 = SFT.nearest_k_p(N // 2)
210
+ >>> Sx0 = SFT.stft(x[:N2])
211
+ >>> Sx1 = SFT.stft(x[N2:])
212
212
 
213
213
  When assembling sequential STFT parts together, the overlap needs to be
214
214
  considered:
215
215
 
216
- >>> p0_ub = SFT.upper_border_begin(p_q)[1] - SFT.p_min
216
+ >>> p0_ub = SFT.upper_border_begin(N2)[1] - SFT.p_min
217
217
  >>> p1_le = SFT.lower_border_end[1] - SFT.p_min
218
218
  >>> Sx01 = np.hstack((Sx0[:, :p0_ub],
219
219
  ... Sx0[:, p0_ub:] + Sx1[:, :p1_le],
@@ -1226,7 +1226,15 @@ class ShortTimeFFT:
1226
1226
 
1227
1227
  @lru_cache(maxsize=256)
1228
1228
  def _post_padding(self, n: int) -> tuple[int, int]:
1229
- """Largest signal index and slice index due to padding."""
1229
+ """Largest signal index and slice index due to padding.
1230
+
1231
+ Parameters
1232
+ ----------
1233
+ n : int
1234
+ Number of samples of input signal (must be ≥ half of the window length).
1235
+ """
1236
+ if not (n >= (m2p := self.m_num - self.m_num_mid)):
1237
+ raise ValueError(f"Parameter n must be >= ceil(m_num/2) = {m2p}!")
1230
1238
  w2 = self.win.real**2 + self.win.imag**2
1231
1239
  # move window to the right until the overlap for t < t[n] vanishes:
1232
1240
  q1 = n // self.hop # last slice index with t[p1] <= t[n]
@@ -1247,6 +1255,11 @@ class ShortTimeFFT:
1247
1255
  A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
1248
1256
  section of the :ref:`user_guide`.
1249
1257
 
1258
+ Parameters
1259
+ ----------
1260
+ n : int
1261
+ Number of samples of input signal (must be ≥ half of the window length).
1262
+
1250
1263
  See Also
1251
1264
  --------
1252
1265
  k_min: The smallest possible signal index.
@@ -1348,6 +1361,19 @@ class ShortTimeFFT:
1348
1361
  A detailed example is given :ref:`tutorial_stft_sliding_win` section
1349
1362
  of the :ref:`user_guide`.
1350
1363
 
1364
+ Parameters
1365
+ ----------
1366
+ n : int
1367
+ Number of samples of input signal (must be ≥ half of the window length).
1368
+
1369
+ Returns
1370
+ -------
1371
+ k_ub : int
1372
+ Lowest signal index, where a touching time slice sticks out past the
1373
+ signal end.
1374
+ p_ub : int
1375
+ Lowest index of time slice of which the end sticks out past the signal end.
1376
+
1351
1377
  See Also
1352
1378
  --------
1353
1379
  k_min: The smallest possible signal index.
@@ -1359,13 +1385,15 @@ class ShortTimeFFT:
1359
1385
  p_range: Determine and validate slice index range.
1360
1386
  ShortTimeFFT: Class this method belongs to.
1361
1387
  """
1388
+ if not (n >= (m2p := self.m_num - self.m_num_mid)):
1389
+ raise ValueError(f"Parameter n must be >= ceil(m_num/2) = {m2p}!")
1362
1390
  w2 = self.win.real**2 + self.win.imag**2
1363
1391
  q2 = n // self.hop + 1 # first t[q] >= t[n]
1364
1392
  q1 = max((n-self.m_num) // self.hop - 1, -1)
1365
1393
  # move window left until does not stick out to the right:
1366
1394
  for q_ in range(q2, q1, -1):
1367
1395
  k_ = q_ * self.hop + (self.m_num - self.m_num_mid)
1368
- if k_ < n or all(w2[n-k_:] == 0):
1396
+ if k_ <= n or all(w2[n-k_:] == 0):
1369
1397
  return (q_ + 1) * self.hop - self.m_num_mid, q_ + 1
1370
1398
  return 0, 0 # border starts at first slice
1371
1399
 
@@ -3703,7 +3703,10 @@ def resample_poly(x, up, down, axis=0, window=('kaiser', 5.0),
3703
3703
  max_rate = max(up, down)
3704
3704
  f_c = 1. / max_rate # cutoff of FIR filter (rel. to Nyquist)
3705
3705
  half_len = 10 * max_rate # reasonable cutoff for sinc-like function
3706
- if np.issubdtype(x.dtype, np.floating):
3706
+ if np.issubdtype(x.dtype, np.complexfloating):
3707
+ h = firwin(2 * half_len + 1, f_c,
3708
+ window=window).astype(x.dtype) # match dtype of x
3709
+ elif np.issubdtype(x.dtype, np.floating):
3707
3710
  h = firwin(2 * half_len + 1, f_c,
3708
3711
  window=window).astype(x.dtype) # match dtype of x
3709
3712
  else:
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -103,7 +103,7 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
103
103
  # This is an edge case where shortTimeFFT returns one more time slice
104
104
  # than the Scipy stft() shorten to remove last time slice:
105
105
  if n % 2 == 1 and nperseg % 2 == 1 and noverlap % 2 == 1:
106
- x = x[..., :axis - 1]
106
+ x = x[..., : -1]
107
107
 
108
108
  nadd = (-(x.shape[-1]-nperseg) % nstep) % nperseg
109
109
  zeros_shape = list(x.shape[:-1]) + [nadd]
@@ -124,11 +124,8 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
124
124
  k_off = nperseg // 2
125
125
  p0 = 0 # ST.lower_border_end[1] + 1
126
126
  nn = x.shape[axis] if padded else n+k_off+1
127
- p1 = ST.upper_border_begin(nn)[1] # ST.p_max(n) + 1
128
-
129
- # This is bad hack to pass the test test_roundtrip_boundary_extension():
130
- if padded is True and nperseg - noverlap == 1:
131
- p1 -= nperseg // 2 - 1 # the reasoning behind this is not clear to me
127
+ # number of frames akin to legacy stft computation
128
+ p1 = (x.shape[axis] - nperseg) // nstep + 1
132
129
 
133
130
  detr = None if detrend is False else detrend
134
131
  Sxx = ST.stft_detrend(x, detr, p0, p1, k_offset=k_off, axis=axis)
@@ -136,11 +133,6 @@ def _stft_wrapper(x, fs=1.0, window='hann', nperseg=256, noverlap=None,
136
133
  if x.dtype in (np.float32, np.complex64):
137
134
  Sxx = Sxx.astype(np.complex64)
138
135
 
139
- # workaround for test_average_all_segments() - seems to be buggy behavior:
140
- if boundary is None and padded is False:
141
- t, Sxx = t[1:-1], Sxx[..., :-2]
142
- t -= k_off / fs
143
-
144
136
  return ST.f, t, Sxx
145
137
 
146
138
 
@@ -332,7 +332,11 @@ def test_border_values():
332
332
  assert SFT.p_max(10) == 4
333
333
  assert SFT.k_max(10) == 16
334
334
  assert SFT.upper_border_begin(10) == (4, 2)
335
-
335
+ # Raise exceptions:
336
+ with pytest.raises(ValueError, match="^Parameter n must be"):
337
+ SFT.upper_border_begin(3)
338
+ with pytest.raises(ValueError, match="^Parameter n must be"):
339
+ SFT._post_padding(3)
336
340
 
337
341
  def test_border_values_exotic():
338
342
  """Ensure that the border calculations are correct for windows with
@@ -342,7 +346,11 @@ def test_border_values_exotic():
342
346
  assert SFT.lower_border_end == (0, 0)
343
347
 
344
348
  SFT = ShortTimeFFT(np.flip(w), hop=20, fs=1)
345
- assert SFT.upper_border_begin(4) == (0, 0)
349
+ assert SFT.upper_border_begin(4) == (16, 1)
350
+ assert SFT.upper_border_begin(5) == (16, 1)
351
+ assert SFT.upper_border_begin(23) == (36, 2)
352
+ assert SFT.upper_border_begin(24) == (36, 2)
353
+ assert SFT.upper_border_begin(25) == (36, 2)
346
354
 
347
355
  SFT._hop = -1 # provoke unreachable line
348
356
  with pytest.raises(RuntimeError):
@@ -3926,3 +3926,8 @@ class TestUniqueRoots:
3926
3926
  unique, multiplicity = unique_roots(p, 2)
3927
3927
  assert_almost_equal(unique, [np.min(p)], decimal=15)
3928
3928
  assert_equal(multiplicity, [100])
3929
+
3930
+
3931
+ def test_gh_22684():
3932
+ actual = signal.resample_poly(np.arange(2000, dtype=np.complex64), 6, 4)
3933
+ assert actual.dtype == np.complex64
scipy/sparse/_base.py CHANGED
@@ -1141,13 +1141,8 @@ class _spbase:
1141
1141
  if self.ndim == 1:
1142
1142
  if axis not in (None, -1, 0):
1143
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
1144
+ res = self @ np.ones(self.shape, dtype=res_dtype)
1145
+ return res.sum(dtype=dtype, out=out)
1151
1146
 
1152
1147
  # We use multiplication by a matrix of ones to achieve this.
1153
1148
  # For some sparse array formats more efficient methods are
@@ -1175,14 +1170,6 @@ class _spbase:
1175
1170
  np.ones((N, 1), dtype=res_dtype)
1176
1171
  )
1177
1172
 
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")
1185
-
1186
1173
  return ret.sum(axis=axis, dtype=dtype, out=out)
1187
1174
 
1188
1175
  def mean(self, axis=None, dtype=None, out=None):
@@ -677,9 +677,6 @@ class _cs_matrix(_data_matrix, _minmax_mixin, IndexMixin):
677
677
  if axis % 2 == 1:
678
678
  ret = ret.T
679
679
 
680
- if out is not None and out.shape != ret.shape:
681
- raise ValueError('dimensions do not match')
682
-
683
680
  return ret.sum(axis=(), dtype=dtype, out=out)
684
681
  else:
685
682
  # _spbase handles the situations when axis is in {None, -2, -1, 0, 1}
scipy/sparse/_dia.py CHANGED
@@ -174,9 +174,6 @@ class _dia_base(_data_matrix):
174
174
 
175
175
  ret = self._ascontainer(row_sums.sum(axis=axis))
176
176
 
177
- if out is not None and out.shape != ret.shape:
178
- raise ValueError("dimensions do not match")
179
-
180
177
  return ret.sum(axis=(), dtype=dtype, out=out)
181
178
 
182
179
  sum.__doc__ = _spbase.sum.__doc__
@@ -46,7 +46,6 @@ from scipy.sparse._sputils import (
46
46
  from scipy.sparse.linalg import gmres, splu
47
47
  from scipy._lib._util import _aligned_zeros
48
48
  from scipy._lib._threadsafety import ReentrancyLock
49
-
50
49
  from . import _arpack
51
50
  arpack_int = _arpack.timing.nbx.dtype
52
51
 
@@ -277,9 +276,12 @@ class ArpackError(RuntimeError):
277
276
  ARPACK error
278
277
  """
279
278
 
280
- def __init__(self, info, infodict=_NAUPD_ERRORS):
279
+ def __init__(self, info, infodict=None):
280
+ if infodict is None:
281
+ infodict = _NAUPD_ERRORS
282
+
281
283
  msg = infodict.get(info, "Unknown error")
282
- RuntimeError.__init__(self, "ARPACK error %d: %s" % (info, msg))
284
+ super().__init__(f"ARPACK error {info}: {msg}")
283
285
 
284
286
 
285
287
  class ArpackNoConvergence(ArpackError):