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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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-313t-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-313t-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-313t-darwin.so +0 -0
  15. scipy/_lib/_test_deprecation_call.cpython-313t-darwin.so +0 -0
  16. scipy/_lib/_test_deprecation_def.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  98. scipy/cluster/_optimal_leaf_ordering.cpython-313t-darwin.so +0 -0
  99. scipy/cluster/_vq.cpython-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-313t-darwin.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-313t-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-313t-darwin.so +0 -0
  142. scipy/integrate/_vode.cpython-313t-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-313t-darwin.so +0 -0
  153. scipy/interpolate/_dierckx.cpython-313t-darwin.so +0 -0
  154. scipy/interpolate/_fitpack.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  164. scipy/interpolate/_rbf.py +2 -2
  165. scipy/interpolate/_rbfinterp.py +1 -1
  166. scipy/interpolate/_rbfinterp_pythran.cpython-313t-darwin.so +0 -0
  167. scipy/interpolate/_rgi.py +31 -26
  168. scipy/interpolate/_rgi_cython.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  188. scipy/io/matlab/_mio_utils.cpython-313t-darwin.so +0 -0
  189. scipy/io/matlab/_miobase.py +4 -1
  190. scipy/io/matlab/_streams.cpython-313t-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-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  211. scipy/linalg/_expm_frechet.py +4 -0
  212. scipy/linalg/_fblas.cpython-313t-darwin.so +0 -0
  213. scipy/linalg/_flapack.cpython-313t-darwin.so +0 -0
  214. scipy/linalg/_linalg_pythran.cpython-313t-darwin.so +0 -0
  215. scipy/linalg/_matfuncs.py +187 -4
  216. scipy/linalg/_matfuncs_expm.cpython-313t-darwin.so +0 -0
  217. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313t-darwin.so +0 -0
  218. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  219. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313t-darwin.so +0 -0
  220. scipy/linalg/_procrustes.py +2 -0
  221. scipy/linalg/_sketches.py +17 -6
  222. scipy/linalg/_solve_toeplitz.cpython-313t-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-313t-darwin.so +0 -0
  227. scipy/linalg/cython_lapack.cpython-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  253. scipy/ndimage/_ni_support.py +1 -5
  254. scipy/ndimage/_rank_filter_1d.cpython-313t-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-313t-darwin.so +0 -0
  263. scipy/optimize/_basinhopping.py +13 -7
  264. scipy/optimize/_bglu_dense.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  275. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  276. scipy/optimize/_lbfgsb.cpython-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  292. scipy/optimize/_minpack_py.py +21 -14
  293. scipy/optimize/_moduleTNC.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  305. scipy/optimize/_spectral.py +1 -1
  306. scipy/optimize/_tnc.py +8 -1
  307. scipy/optimize/_trlib/_trlib.cpython-313t-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-313t-darwin.so +0 -0
  319. scipy/optimize/_zeros_py.py +97 -17
  320. scipy/optimize/cython_optimize/_zeros.cpython-313t-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-313t-darwin.so +0 -0
  352. scipy/signal/_peak_finding_utils.cpython-313t-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-313t-darwin.so +0 -0
  358. scipy/signal/_sosfilt.cpython-313t-darwin.so +0 -0
  359. scipy/signal/_spectral_py.py +230 -50
  360. scipy/signal/_spline.cpython-313t-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-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  406. scipy/sparse/csgraph/_matching.cpython-313t-darwin.so +0 -0
  407. scipy/sparse/csgraph/_min_spanning_tree.cpython-313t-darwin.so +0 -0
  408. scipy/sparse/csgraph/_reordering.cpython-313t-darwin.so +0 -0
  409. scipy/sparse/csgraph/_shortest_path.cpython-313t-darwin.so +0 -0
  410. scipy/sparse/csgraph/_tools.cpython-313t-darwin.so +0 -0
  411. scipy/sparse/csgraph/_traversal.cpython-313t-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-313t-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-313t-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-313t-darwin.so +0 -0
  436. scipy/sparse/linalg/_propack/_dpropack.cpython-313t-darwin.so +0 -0
  437. scipy/sparse/linalg/_propack/_spropack.cpython-313t-darwin.so +0 -0
  438. scipy/sparse/linalg/_propack/_zpropack.cpython-313t-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-313t-darwin.so +0 -0
  451. scipy/spatial/_distance_pybind.cpython-313t-darwin.so +0 -0
  452. scipy/spatial/_distance_wrap.cpython-313t-darwin.so +0 -0
  453. scipy/spatial/_hausdorff.cpython-313t-darwin.so +0 -0
  454. scipy/spatial/_qhull.cpython-313t-darwin.so +0 -0
  455. scipy/spatial/_voronoi.cpython-313t-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-313t-darwin.so +0 -0
  462. scipy/spatial/transform/_rotation.cpython-313t-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-313t-darwin.so +0 -0
  471. scipy/special/_ellip_harm_2.cpython-313t-darwin.so +0 -0
  472. scipy/special/_gufuncs.cpython-313t-darwin.so +0 -0
  473. scipy/special/_logsumexp.py +83 -69
  474. scipy/special/_orthogonal.pyi +1 -1
  475. scipy/special/_specfun.cpython-313t-darwin.so +0 -0
  476. scipy/special/_special_ufuncs.cpython-313t-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-313t-darwin.so +0 -0
  480. scipy/special/_testutils.py +4 -4
  481. scipy/special/_ufuncs.cpython-313t-darwin.so +0 -0
  482. scipy/special/_ufuncs.pyi +1 -0
  483. scipy/special/_ufuncs.pyx +215 -1400
  484. scipy/special/_ufuncs_cxx.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  507. scipy/stats/_axis_nan_policy.py +5 -12
  508. scipy/stats/_biasedurn.cpython-313t-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-313t-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-313t-darwin.so +0 -0
  532. scipy/stats/_qmvnt.py +16 -95
  533. scipy/stats/_qmvnt_cy.cpython-313t-darwin.so +0 -0
  534. scipy/stats/_quantile.py +335 -0
  535. scipy/stats/_rcont/rcont.cpython-313t-darwin.so +0 -0
  536. scipy/stats/_resampling.py +5 -30
  537. scipy/stats/_sampling.py +1 -1
  538. scipy/stats/_sobol.cpython-313t-darwin.so +0 -0
  539. scipy/stats/_stats.cpython-313t-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-313t-darwin.so +0 -0
  543. scipy/stats/_unuran/unuran_wrapper.cpython-313t-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-313t-darwin.so +0 -0
  578. scipy/optimize/_cobyla.cpython-313t-darwin.so +0 -0
  579. scipy/optimize/_cython_nnls.cpython-313t-darwin.so +0 -0
  580. scipy/optimize/_slsqp.cpython-313t-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-313t-darwin.so +0 -0
  642. scipy-1.15.2.dist-info/WHEEL +0 -4
scipy/integrate/_ode.py CHANGED
@@ -826,7 +826,7 @@ class IntegratorBase:
826
826
  # XXX: __str__ method for getting visual state of the integrator
827
827
 
828
828
 
829
- def _vode_banded_jac_wrapper(jacfunc, ml, jac_params):
829
+ def _banded_jac_wrapper(jacfunc, ml, jac_params):
830
830
  """
831
831
  Wrap a banded Jacobian function with a function that pads
832
832
  the Jacobian with `ml` rows of zeros.
@@ -1007,7 +1007,7 @@ class vode(IntegratorBase):
1007
1007
  # Banded Jacobian. Wrap the user-provided function with one
1008
1008
  # that pads the Jacobian array with the extra `self.ml` rows
1009
1009
  # required by the f2py-generated wrapper.
1010
- jac = _vode_banded_jac_wrapper(jac, self.ml, jac_params)
1010
+ jac = _banded_jac_wrapper(jac, self.ml, jac_params)
1011
1011
 
1012
1012
  args = ((f, jac, y0, t0, t1) + tuple(self.call_args) +
1013
1013
  (f_params, jac_params))
@@ -1351,6 +1351,13 @@ class lsoda(IntegratorBase):
1351
1351
  else:
1352
1352
  self.initialized = True
1353
1353
  self.acquire_new_handle()
1354
+
1355
+ if jac is not None and self.ml is not None and self.ml > 0:
1356
+ # Banded Jacobian. Wrap the user-provided function with one
1357
+ # that pads the Jacobian array with the extra `self.ml` rows
1358
+ # required by the f2py-generated wrapper.
1359
+ jac = _banded_jac_wrapper(jac, self.ml, jac_params)
1360
+
1354
1361
  args = [f, y0, t0, t1] + self.call_args[:-1] + \
1355
1362
  [jac, self.call_args[-1], f_params, 0, jac_params]
1356
1363
 
@@ -3,7 +3,6 @@ import copy
3
3
  import heapq
4
4
  import collections
5
5
  import functools
6
- import warnings
7
6
 
8
7
  import numpy as np
9
8
 
@@ -144,9 +143,9 @@ def quad_vec(f, a, b, epsabs=1e-200, epsrel=1e-8, norm='2', cache_size=100e6,
144
143
  Options: 'gk21' (Gauss-Kronrod 21-point rule),
145
144
  'gk15' (Gauss-Kronrod 15-point rule),
146
145
  'trapezoid' (composite trapezoid rule).
147
- Default: 'gk21' for finite intervals and 'gk15' for (semi-)infinite
146
+ Default: 'gk21' for finite intervals and 'gk15' for (semi-)infinite.
148
147
  full_output : bool, optional
149
- Return an additional ``info`` dictionary.
148
+ Return an additional ``info`` object.
150
149
  args : tuple, optional
151
150
  Extra arguments to pass to function, if any.
152
151
 
@@ -158,25 +157,25 @@ def quad_vec(f, a, b, epsabs=1e-200, epsrel=1e-8, norm='2', cache_size=100e6,
158
157
  Estimate for the result
159
158
  err : float
160
159
  Error estimate for the result in the given norm
161
- info : dict
160
+ info : object
162
161
  Returned only when ``full_output=True``.
163
- Info dictionary. Is an object with the attributes:
164
-
165
- success : bool
166
- Whether integration reached target precision.
167
- status : int
168
- Indicator for convergence, success (0),
169
- failure (1), and failure due to rounding error (2).
170
- neval : int
171
- Number of function evaluations.
172
- intervals : ndarray, shape (num_intervals, 2)
173
- Start and end points of subdivision intervals.
174
- integrals : ndarray, shape (num_intervals, ...)
175
- Integral for each interval.
176
- Note that at most ``cache_size`` values are recorded,
177
- and the array may contains *nan* for missing items.
178
- errors : ndarray, shape (num_intervals,)
179
- Estimated integration error for each interval.
162
+ Result object with the attributes:
163
+
164
+ success : bool
165
+ Whether integration reached target precision.
166
+ status : int
167
+ Indicator for convergence, success (0),
168
+ failure (1), and failure due to rounding error (2).
169
+ neval : int
170
+ Number of function evaluations.
171
+ intervals : ndarray, shape (num_intervals, 2)
172
+ Start and end points of subdivision intervals.
173
+ integrals : ndarray, shape (num_intervals, ...)
174
+ Integral for each interval.
175
+ Note that at most ``cache_size`` values are recorded,
176
+ and the array may contains *nan* for missing items.
177
+ errors : ndarray, shape (num_intervals,)
178
+ Estimated integration error for each interval.
180
179
 
181
180
  Notes
182
181
  -----
@@ -310,17 +309,10 @@ def quad_vec(f, a, b, epsabs=1e-200, epsrel=1e-8, norm='2', cache_size=100e6,
310
309
  _quadrature = {None: _quadrature_gk21,
311
310
  'gk21': _quadrature_gk21,
312
311
  'gk15': _quadrature_gk15,
313
- 'trapz': _quadrature_trapezoid, # alias for backcompat
314
312
  'trapezoid': _quadrature_trapezoid}[quadrature]
315
313
  except KeyError as e:
316
314
  raise ValueError(f"unknown quadrature {quadrature!r}") from e
317
315
 
318
- if quadrature == "trapz":
319
- msg = ("`quadrature='trapz'` is deprecated in favour of "
320
- "`quadrature='trapezoid' and will raise an error from SciPy 1.16.0 "
321
- "onwards.")
322
- warnings.warn(msg, DeprecationWarning, stacklevel=2)
323
-
324
316
  # Initial interval set
325
317
  if points is None:
326
318
  initial_intervals = [(a, b)]
@@ -347,7 +339,7 @@ def quad_vec(f, a, b, epsabs=1e-200, epsrel=1e-8, norm='2', cache_size=100e6,
347
339
  neval += _quadrature.num_eval
348
340
 
349
341
  if global_integral is None:
350
- if isinstance(ig, (float, complex)):
342
+ if isinstance(ig, float | complex):
351
343
  # Specialize for scalars
352
344
  if norm_func in (_max_norm, np.linalg.norm):
353
345
  norm_func = abs
@@ -211,9 +211,9 @@ def quad(func, a, b, args=(), full_output=0, epsabs=1.49e-8, epsrel=1.49e-8,
211
211
  For the 'cos' and 'sin' weighting, additional inputs and outputs are
212
212
  available.
213
213
 
214
- For finite integration limits, the integration is performed using a
215
- Clenshaw-Curtis method which uses Chebyshev moments. For repeated
216
- calculations, these moments are saved in the output dictionary:
214
+ For weighted integrals with finite integration limits, the integration
215
+ is performed using a Clenshaw-Curtis method, which uses Chebyshev moments.
216
+ For repeated calculations, these moments are saved in the output dictionary:
217
217
 
218
218
  'momcom'
219
219
  The maximum level of Chebyshev moments that have been computed,
@@ -284,7 +284,8 @@ def quad(func, a, b, args=(), full_output=0, epsabs=1.49e-8, epsrel=1.49e-8,
284
284
  is an integrator based on globally adaptive interval
285
285
  subdivision in connection with extrapolation, which will
286
286
  eliminate the effects of integrand singularities of
287
- several types.
287
+ several types. The integration is performed using a 21-point Gauss-Kronrod
288
+ quadrature within each subinterval.
288
289
  qagie
289
290
  handles integration over infinite intervals. The infinite range is
290
291
  mapped onto a finite interval and subsequently the same strategy as
@@ -745,7 +746,8 @@ def dblquad(func, a, b, gfun, hfun, args=(), epsabs=1.49e-8, epsrel=1.49e-8):
745
746
  is an integrator based on globally adaptive interval
746
747
  subdivision in connection with extrapolation, which will
747
748
  eliminate the effects of integrand singularities of
748
- several types.
749
+ several types. The integration is is performed using a 21-point Gauss-Kronrod
750
+ quadrature within each subinterval.
749
751
  qagie
750
752
  handles integration over infinite intervals. The infinite range is
751
753
  mapped onto a finite interval and subsequently the same strategy as
@@ -877,7 +879,8 @@ def tplquad(func, a, b, gfun, hfun, qfun, rfun, args=(), epsabs=1.49e-8,
877
879
  is an integrator based on globally adaptive interval
878
880
  subdivision in connection with extrapolation, which will
879
881
  eliminate the effects of integrand singularities of
880
- several types.
882
+ several types. The integration is is performed using a 21-point Gauss-Kronrod
883
+ quadrature within each subinterval.
881
884
  qagie
882
885
  handles integration over infinite intervals. The infinite range is
883
886
  mapped onto a finite interval and subsequently the same strategy as
@@ -1066,7 +1069,8 @@ def nquad(func, ranges, args=None, opts=None, full_output=False):
1066
1069
  is an integrator based on globally adaptive interval
1067
1070
  subdivision in connection with extrapolation, which will
1068
1071
  eliminate the effects of integrand singularities of
1069
- several types.
1072
+ several types. The integration is is performed using a 21-point Gauss-Kronrod
1073
+ quadrature within each subinterval.
1070
1074
  qagie
1071
1075
  handles integration over infinite intervals. The infinite range is
1072
1076
  mapped onto a finite interval and subsequently the same strategy as
@@ -8,7 +8,7 @@ from collections.abc import Callable
8
8
  from scipy.special import roots_legendre
9
9
  from scipy.special import gammaln, logsumexp
10
10
  from scipy._lib._util import _rng_spawn
11
- from scipy._lib._array_api import _asarray, array_namespace, xp_broadcast_promote
11
+ from scipy._lib._array_api import _asarray, array_namespace, xp_result_type
12
12
 
13
13
 
14
14
  __all__ = ['fixed_quad', 'romb',
@@ -124,7 +124,7 @@ def trapezoid(y, x=None, dx=1.0, axis=-1):
124
124
  # Cannot just use the broadcasted arrays that are returned
125
125
  # because trapezoid does not follow normal broadcasting rules
126
126
  # cf. https://github.com/scipy/scipy/pull/21524#issuecomment-2354105942
127
- result_dtype = xp_broadcast_promote(y, force_floating=True, xp=xp)[0].dtype
127
+ result_dtype = xp_result_type(y, force_floating=True, xp=xp)
128
128
  nd = y.ndim
129
129
  slice1 = [slice(None)]*nd
130
130
  slice2 = [slice(None)]*nd
@@ -894,7 +894,7 @@ def romb(y, dx=1.0, axis=-1, show=False):
894
894
  width = show[1]
895
895
  except (TypeError, IndexError):
896
896
  width = 8
897
- formstr = "%%%d.%df" % (width, precis)
897
+ formstr = f"%{width}.{precis}f"
898
898
 
899
899
  title = "Richardson Extrapolation Table for Romberg Integration"
900
900
  print(title, "=" * len(title), sep="\n", end="\n")
@@ -463,8 +463,8 @@ def _split_subregion(a, b, xp, split_at=None):
463
463
  if split_at is None:
464
464
  split_at = (a + b) / 2
465
465
 
466
- left = [xp.asarray([a[i], split_at[i]]) for i in range(a.shape[0])]
467
- right = [xp.asarray([split_at[i], b[i]]) for i in range(b.shape[0])]
466
+ left = [xp.stack((a[i], split_at[i])) for i in range(a.shape[0])]
467
+ right = [xp.stack((split_at[i], b[i])) for i in range(b.shape[0])]
468
468
 
469
469
  a_sub = _cartesian_product(left)
470
470
  b_sub = _cartesian_product(right)
@@ -5,7 +5,7 @@ from scipy import special
5
5
  import scipy._lib._elementwise_iterative_method as eim
6
6
  from scipy._lib._util import _RichResult
7
7
  from scipy._lib._array_api import (array_namespace, xp_copy, xp_ravel,
8
- xp_real, xp_take_along_axis)
8
+ xp_promote)
9
9
 
10
10
 
11
11
  __all__ = ['nsum']
@@ -97,12 +97,10 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
97
97
  atol, rtol : float, optional
98
98
  Absolute termination tolerance (default: 0) and relative termination
99
99
  tolerance (default: ``eps**0.75``, where ``eps`` is the precision of
100
- the result dtype), respectively. Iteration will stop when
101
- ``res.error < atol + rtol * abs(res.df)``. The error estimate is as
102
- described in [1]_ Section 5. While not theoretically rigorous or
103
- conservative, it is said to work well in practice. Must be non-negative
104
- and finite if `log` is False, and must be expressed as the log of a
105
- non-negative and finite number if `log` is True.
100
+ the result dtype), respectively. Must be non-negative and finite if
101
+ `log` is False, and must be expressed as the log of a non-negative and
102
+ finite number if `log` is True. Iteration will stop when
103
+ ``res.error < atol`` or ``res.error < res.integral * rtol``.
106
104
  preserve_shape : bool, default: False
107
105
  In the following, "arguments of `f`" refers to the array ``xi`` and
108
106
  any arrays within ``argsi``. Let ``shape`` be the broadcasted shape
@@ -127,7 +125,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
127
125
  An optional user-supplied function to be called before the first
128
126
  iteration and after each iteration.
129
127
  Called as ``callback(res)``, where ``res`` is a ``_RichResult``
130
- similar to that returned by `_differentiate` (but containing the
128
+ similar to that returned by `tanhsinh` (but containing the
131
129
  current iterate's values of all variables). If `callback` raises a
132
130
  ``StopIteration``, the algorithm will terminate immediately and
133
131
  `tanhsinh` will return a result object. `callback` must not mutate
@@ -174,6 +172,12 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
174
172
  finite-precision arithmetic, including some described by [2]_ and [3]_. The
175
173
  tanh-sinh scheme was originally introduced in [4]_.
176
174
 
175
+ Two error estimation schemes are described in [1]_ Section 5: one attempts to
176
+ detect and exploit quadratic convergence; the other simply compares the integral
177
+ estimates at successive levels. While neither is theoretically rigorous or
178
+ conservative, both work well in practice. Our error estimate uses the minimum of
179
+ these two schemes with a lower bound of ``eps * res.integral``.
180
+
177
181
  Due to floating-point error in the abscissae, the function may be evaluated
178
182
  at the endpoints of the interval during iterations, but the values returned by
179
183
  the function at the endpoints will be ignored.
@@ -363,7 +367,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
363
367
  aerr = xp_ravel(xp.full(shape, xp.nan, dtype=dtype)) # absolute error
364
368
  status = xp_ravel(xp.full(shape, eim._EINPROGRESS, dtype=xp.int32))
365
369
  h0 = _get_base_step(dtype, xp)
366
- h0 = xp_real(h0) # base step
370
+ h0 = xp.real(h0) # base step
367
371
 
368
372
  # For term `d4` of error estimate ([1] Section 5), we need to keep the
369
373
  # most extreme abscissae and corresponding `fj`s, `wj`s in Euler-Maclaurin
@@ -402,8 +406,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
402
406
 
403
407
  # Perform abscissae substitutions for infinite limits of integration
404
408
  xj = xp_copy(work.xj)
405
- # use xp_real here to avoid cupy/cupy#8434
406
- xj[work.abinf] = xj[work.abinf] / (1 - xp_real(xj[work.abinf])**2)
409
+ xj[work.abinf] = xj[work.abinf] / (1 - xp.real(xj[work.abinf])**2)
407
410
  xj[work.binf] = 1/xj[work.binf] - 1 + work.a0[work.binf]
408
411
  xj[work.ainf] *= -1
409
412
  return xj
@@ -445,15 +448,15 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
445
448
  stop[i] = True
446
449
  else:
447
450
  # Terminate if convergence criterion is met
448
- work.rerr, work.aerr = _estimate_error(work, xp)
449
- i = ((work.rerr < rtol) | (work.rerr + xp_real(work.Sn) < atol) if log
450
- else (work.rerr < rtol) | (work.rerr * xp.abs(work.Sn) < atol))
451
+ rerr, aerr = _estimate_error(work, xp)
452
+ i = (rerr < rtol) | (aerr < atol)
453
+ work.aerr = xp.reshape(xp.astype(aerr, work.dtype), work.Sn.shape)
451
454
  work.status[i] = eim._ECONVERGED
452
455
  stop[i] = True
453
456
 
454
457
  # Terminate if integral estimate becomes invalid
455
458
  if log:
456
- Sn_real = xp_real(work.Sn)
459
+ Sn_real = xp.real(work.Sn)
457
460
  Sn_pos_inf = xp.isinf(Sn_real) & (Sn_real > 0)
458
461
  i = (Sn_pos_inf | xp.isnan(work.Sn)) & ~stop
459
462
  else:
@@ -472,10 +475,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
472
475
  # If the integration limits were such that b < a, we reversed them
473
476
  # to perform the calculation, and the final result needs to be negated.
474
477
  if log and xp.any(negative):
475
- dtype = res['integral'].dtype
476
- pi = xp.asarray(xp.pi, dtype=dtype)[()]
477
- j = xp.asarray(1j, dtype=xp.complex64)[()] # minimum complex type
478
- res['integral'] = res['integral'] + negative*pi*j
478
+ res['integral'] = res['integral'] + negative * xp.pi * 1.0j
479
479
  else:
480
480
  res['integral'][negative] *= -1
481
481
 
@@ -614,7 +614,7 @@ def _transform_to_limits(xjc, wj, a, b, xp):
614
614
  # these points; however, we can't easily filter out points since this
615
615
  # function is vectorized. Instead, zero the weights.
616
616
  # Note: values may have complex dtype, but have zero imaginary part
617
- xj_real, a_real, b_real = xp_real(xj), xp_real(a), xp_real(b)
617
+ xj_real, a_real, b_real = xp.real(xj), xp.real(a), xp.real(b)
618
618
  invalid = (xj_real <= a_real) | (xj_real >= b_real)
619
619
  wj[invalid] = 0
620
620
  return xj, wj
@@ -645,16 +645,16 @@ def _euler_maclaurin_sum(fj, work, xp):
645
645
 
646
646
  # integer index of the maximum abscissa at this level
647
647
  xr[invalid_r] = -xp.inf
648
- ir = xp.argmax(xp_real(xr), axis=0, keepdims=True)
648
+ ir = xp.argmax(xp.real(xr), axis=0, keepdims=True)
649
649
  # abscissa, function value, and weight at this index
650
650
  ### Not Array API Compatible... yet ###
651
- xr_max = xp_take_along_axis(xr, ir, axis=0)[0]
652
- fr_max = xp_take_along_axis(fr, ir, axis=0)[0]
653
- wr_max = xp_take_along_axis(wr, ir, axis=0)[0]
651
+ xr_max = xp.take_along_axis(xr, ir, axis=0)[0]
652
+ fr_max = xp.take_along_axis(fr, ir, axis=0)[0]
653
+ wr_max = xp.take_along_axis(wr, ir, axis=0)[0]
654
654
  # boolean indices at which maximum abscissa at this level exceeds
655
655
  # the incumbent maximum abscissa (from all previous levels)
656
656
  # note: abscissa may have complex dtype, but will have zero imaginary part
657
- j = xp_real(xr_max) > xp_real(xr0)
657
+ j = xp.real(xr_max) > xp.real(xr0)
658
658
  # Update record of the incumbent abscissa, function value, and weight
659
659
  xr0[j] = xr_max[j]
660
660
  fr0[j] = fr_max[j]
@@ -662,15 +662,15 @@ def _euler_maclaurin_sum(fj, work, xp):
662
662
 
663
663
  # integer index of the minimum abscissa at this level
664
664
  xl[invalid_l] = xp.inf
665
- il = xp.argmin(xp_real(xl), axis=0, keepdims=True)
665
+ il = xp.argmin(xp.real(xl), axis=0, keepdims=True)
666
666
  # abscissa, function value, and weight at this index
667
- xl_min = xp_take_along_axis(xl, il, axis=0)[0]
668
- fl_min = xp_take_along_axis(fl, il, axis=0)[0]
669
- wl_min = xp_take_along_axis(wl, il, axis=0)[0]
667
+ xl_min = xp.take_along_axis(xl, il, axis=0)[0]
668
+ fl_min = xp.take_along_axis(fl, il, axis=0)[0]
669
+ wl_min = xp.take_along_axis(wl, il, axis=0)[0]
670
670
  # boolean indices at which minimum abscissa at this level is less than
671
671
  # the incumbent minimum abscissa (from all previous levels)
672
672
  # note: abscissa may have complex dtype, but will have zero imaginary part
673
- j = xp_real(xl_min) < xp_real(xl0)
673
+ j = xp.real(xl_min) < xp.real(xl0)
674
674
  # Update record of the incumbent abscissa, function value, and weight
675
675
  xl0[j] = xl_min[j]
676
676
  fl0[j] = fl_min[j]
@@ -681,7 +681,7 @@ def _euler_maclaurin_sum(fj, work, xp):
681
681
  # rightmost term, whichever is greater.
682
682
  flwl0 = fl0 + xp.log(wl0) if work.log else fl0 * wl0 # leftmost term
683
683
  frwr0 = fr0 + xp.log(wr0) if work.log else fr0 * wr0 # rightmost term
684
- magnitude = xp_real if work.log else xp.abs
684
+ magnitude = xp.real if work.log else xp.abs
685
685
  work.d4 = xp.maximum(magnitude(flwl0), magnitude(frwr0))
686
686
 
687
687
  # There are two approaches to dealing with function values that are
@@ -768,26 +768,27 @@ def _estimate_error(work, xp):
768
768
  # complex values have imaginary part in increments of pi*j, which just
769
769
  # carries sign information of the original integral, so use of
770
770
  # `xp.real` here is equivalent to absolute value in real scale.
771
- d1 = xp_real(special.logsumexp(xp.stack([work.Sn, Snm1 + work.pi*1j]), axis=0))
772
- d2 = xp_real(special.logsumexp(xp.stack([work.Sn, Snm2 + work.pi*1j]), axis=0))
773
- d3 = log_e1 + xp.max(xp_real(work.fjwj), axis=-1)
771
+ d1 = xp.real(special.logsumexp(xp.stack([work.Sn, Snm1 + work.pi*1j]), axis=0))
772
+ d2 = xp.real(special.logsumexp(xp.stack([work.Sn, Snm2 + work.pi*1j]), axis=0))
773
+ d3 = log_e1 + xp.max(xp.real(work.fjwj), axis=-1)
774
774
  d4 = work.d4
775
- ds = xp.stack([d1 ** 2 / d2, 2 * d1, d3, d4])
776
- aerr = xp.max(ds, axis=0)
777
- rerr = xp.maximum(log_e1, aerr - xp_real(work.Sn))
775
+ d5 = log_e1 + xp.real(work.Sn)
776
+ temp = xp.where(d1 > -xp.inf, d1 ** 2 / d2, -xp.inf)
777
+ ds = xp.stack([temp, 2 * d1, d3, d4])
778
+ aerr = xp.clip(xp.max(ds, axis=0), d5, d1)
779
+ rerr = aerr - xp.real(work.Sn)
778
780
  else:
779
781
  # Note: explicit computation of log10 of each of these is unnecessary.
780
782
  d1 = xp.abs(work.Sn - Snm1)
781
783
  d2 = xp.abs(work.Sn - Snm2)
782
784
  d3 = e1 * xp.max(xp.abs(work.fjwj), axis=-1)
783
785
  d4 = work.d4
784
- # If `d1` is 0, no need to warn. This does the right thing.
785
- # with np.errstate(divide='ignore'):
786
- ds = xp.stack([d1**(xp.log(d1)/xp.log(d2)), d1**2, d3, d4])
787
- aerr = xp.max(ds, axis=0)
788
- rerr = xp.maximum(e1, aerr/xp.abs(work.Sn))
786
+ d5 = e1 * xp.abs(work.Sn)
787
+ temp = xp.where(d1 > 0, d1**(xp.log(d1)/xp.log(d2)), 0)
788
+ ds = xp.stack([temp, d1**2, d3, d4])
789
+ aerr = xp.clip(xp.max(ds, axis=0), d5, d1)
790
+ rerr = aerr/xp.abs(work.Sn)
789
791
 
790
- aerr = xp.reshape(xp.astype(aerr, work.dtype), work.Sn.shape)
791
792
  return rerr, aerr
792
793
 
793
794
 
@@ -802,7 +803,7 @@ def _transform_integrals(a, b, xp):
802
803
  a[ab_same], b[ab_same] = 1, 1
803
804
 
804
805
  # `a, b` may have complex dtype but have zero imaginary part
805
- negative = xp_real(b) < xp_real(a)
806
+ negative = xp.real(b) < xp.real(a)
806
807
  a[negative], b[negative] = b[negative], a[negative]
807
808
 
808
809
  abinf = xp.isinf(a) & xp.isinf(b)
@@ -823,14 +824,13 @@ def _tanhsinh_iv(f, a, b, log, maxfun, maxlevel, minlevel,
823
824
  # Input validation and standardization
824
825
 
825
826
  xp = array_namespace(a, b)
827
+ a, b = xp_promote(a, b, broadcast=True, force_floating=True, xp=xp)
826
828
 
827
829
  message = '`f` must be callable.'
828
830
  if not callable(f):
829
831
  raise ValueError(message)
830
832
 
831
833
  message = 'All elements of `a` and `b` must be real numbers.'
832
- a, b = xp.asarray(a), xp.asarray(b)
833
- a, b = xp.broadcast_arrays(a, b)
834
834
  if (xp.isdtype(a.dtype, 'complex floating')
835
835
  or xp.isdtype(b.dtype, 'complex floating')):
836
836
  raise ValueError(message)
@@ -899,16 +899,15 @@ def _tanhsinh_iv(f, a, b, log, maxfun, maxlevel, minlevel,
899
899
  def _nsum_iv(f, a, b, step, args, log, maxterms, tolerances):
900
900
  # Input validation and standardization
901
901
 
902
- xp = array_namespace(a, b)
902
+ xp = array_namespace(a, b, step)
903
+ a, b, step = xp_promote(a, b, step, broadcast=True, force_floating=True, xp=xp)
903
904
 
904
905
  message = '`f` must be callable.'
905
906
  if not callable(f):
906
907
  raise ValueError(message)
907
908
 
908
909
  message = 'All elements of `a`, `b`, and `step` must be real numbers.'
909
- a, b, step = xp.broadcast_arrays(xp.asarray(a), xp.asarray(b), xp.asarray(step))
910
- dtype = xp.result_type(a.dtype, b.dtype, step.dtype)
911
- if not xp.isdtype(dtype, 'numeric') or xp.isdtype(dtype, 'complex floating'):
910
+ if not xp.isdtype(a.dtype, ('integral', 'real floating')):
912
911
  raise ValueError(message)
913
912
 
914
913
  valid_b = b >= a # NaNs will be False
@@ -1181,6 +1180,7 @@ def nsum(f, a, b, *, step=1, args=(), log=False, maxterms=int(2**20), tolerances
1181
1180
 
1182
1181
  # Branch for direct sum evaluation / integral approximation / invalid input
1183
1182
  i0 = ~valid_abstep # invalid
1183
+ i0b = b < a # zero
1184
1184
  i1 = (nterms + 1 <= maxterms) & ~i0 # direct sum evaluation
1185
1185
  i2 = xp.isfinite(a) & ~i1 & ~i0 # infinite sum to the right
1186
1186
  i3 = xp.isfinite(b) & ~i2 & ~i1 & ~i0 # infinite sum to the left
@@ -1190,6 +1190,9 @@ def nsum(f, a, b, *, step=1, args=(), log=False, maxterms=int(2**20), tolerances
1190
1190
  S[i0], E[i0] = xp.nan, xp.nan
1191
1191
  status[i0] = -1
1192
1192
 
1193
+ S[i0b], E[i0b] = zero, zero
1194
+ status[i0b] = 0
1195
+
1193
1196
  if xp.any(i1):
1194
1197
  args_direct = [arg[i1] for arg in args]
1195
1198
  tmp = _direct(f, a[i1], b[i1], step[i1], args_direct, constants, xp)
@@ -1292,7 +1295,7 @@ def _direct(f, a, b, step, args, constants, xp, inclusive=True):
1292
1295
  nfev = max_steps - i_nan.sum(axis=-1)
1293
1296
  S = special.logsumexp(fs, axis=-1) if log else xp.sum(fs, axis=-1)
1294
1297
  # Rough, non-conservative error estimate. See gh-19667 for improvement ideas.
1295
- E = xp_real(S) + math.log(eps) if log else eps * abs(S)
1298
+ E = xp.real(S) + math.log(eps) if log else eps * abs(S)
1296
1299
  return S, E, nfev
1297
1300
 
1298
1301
 
@@ -1308,7 +1311,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1308
1311
  tol = special.logsumexp(xp.stack((tol, rtol + lb.integral)), axis=0)
1309
1312
  else:
1310
1313
  tol = tol + rtol*lb.integral
1311
- i_skip = lb.status < 0 # avoid unnecessary f_evals if integral is divergent
1314
+ i_skip = lb.status == -3 # avoid unnecessary f_evals if integral is divergent
1312
1315
  tol[i_skip] = xp.nan
1313
1316
  status = lb.status
1314
1317
 
@@ -1329,7 +1332,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1329
1332
  fksp1 = f(ks + step2, *args2) # check that the function is decreasing
1330
1333
  fk_insufficient = (fks > tol[:, xp.newaxis]) | (fksp1 > fks)
1331
1334
  n_fk_insufficient = xp.sum(fk_insufficient, axis=-1)
1332
- nt = xp.minimum(n_fk_insufficient, xp.asarray(n_steps.shape[-1]-1))
1335
+ nt = xp.minimum(n_fk_insufficient, n_steps.shape[-1]-1)
1333
1336
  n_steps = n_steps[nt]
1334
1337
 
1335
1338
  # If `maxterms` is insufficient (i.e. either the magnitude of the last term of the
@@ -1372,7 +1375,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1372
1375
  S_terms = (left, right.integral - log_step, fk - log2, fb - log2)
1373
1376
  S = special.logsumexp(xp.stack(S_terms), axis=0)
1374
1377
  E_terms = (left_error, right.error - log_step, fk-log2, fb-log2+xp.pi*1j)
1375
- E = xp_real(special.logsumexp(xp.stack(E_terms), axis=0))
1378
+ E = xp.real(special.logsumexp(xp.stack(E_terms), axis=0))
1376
1379
  else:
1377
1380
  S = left + right.integral/step + fk/2 + fb/2
1378
1381
  E = left_error + right.error/step + fk/2 - fb/2
@@ -209,9 +209,3 @@ def test_points(a, b):
209
209
  for p in interval_sets:
210
210
  j = np.searchsorted(sorted(points), tuple(p))
211
211
  assert np.all(j == j[0])
212
-
213
-
214
- @pytest.mark.thread_unsafe
215
- def test_trapz_deprecation():
216
- with pytest.deprecated_call(match="`quadrature='trapz'`"):
217
- quad_vec(lambda x: x, 0, 1, quadrature="trapz")
@@ -130,6 +130,9 @@ def test_banded_ode_solvers():
130
130
  # Test the "lsoda", "vode" and "zvode" solvers of the `ode` class
131
131
  # with a system that has a banded Jacobian matrix.
132
132
 
133
+ # This test does not test the Jacobian evaluation (banded or not)
134
+ # of "lsoda" due to the nonstiff nature of the equations.
135
+
133
136
  t_exact = np.linspace(0, 1.0, 5)
134
137
 
135
138
  # --- Real arrays for testing the "lsoda" and "vode" solvers ---
@@ -218,3 +221,85 @@ def test_banded_ode_solvers():
218
221
  [False, True]] # banded
219
222
  for meth, use_jac, with_jac, banded in itertools.product(*p):
220
223
  check_complex(idx, "zvode", meth, use_jac, with_jac, banded)
224
+
225
+ # lsoda requires a stiffer problem to switch to stiff solver
226
+ # Use the Robertson equation with surrounding trivial equations to make banded
227
+
228
+ def stiff_f(t, y):
229
+ return np.array([
230
+ y[0],
231
+ -0.04 * y[1] + 1e4 * y[2] * y[3],
232
+ 0.04 * y[1] - 1e4 * y[2] * y[3] - 3e7 * y[2]**2,
233
+ 3e7 * y[2]**2,
234
+ y[4]
235
+ ])
236
+
237
+ def stiff_jac(t, y):
238
+ return np.array([
239
+ [1, 0, 0, 0, 0],
240
+ [0, -0.04, 1e4*y[3], 1e4*y[2], 0],
241
+ [0, 0.04, -1e4 * y[3] - 3e7 * 2 * y[2], -1e4*y[2], 0],
242
+ [0, 0, 3e7*2*y[2], 0, 0],
243
+ [0, 0, 0, 0, 1]
244
+ ])
245
+
246
+ def banded_stiff_jac(t, y):
247
+ return np.array([
248
+ [0, 0, 0, 1e4*y[2], 0],
249
+ [0, 0, 1e4*y[3], -1e4*y[2], 0],
250
+ [1, -0.04, -1e4*y[3]-3e7*2*y[2], 0, 1],
251
+ [0, 0.04, 3e7*2*y[2], 0, 0]
252
+ ])
253
+
254
+ @pytest.mark.thread_unsafe
255
+ def test_banded_lsoda():
256
+ # expected solution is given by problem with full jacobian
257
+ tfull, yfull = _solve_robertson_lsoda(use_jac=True, banded=False)
258
+
259
+ for use_jac in [True, False]:
260
+ t, y = _solve_robertson_lsoda(use_jac, True)
261
+ assert_allclose(t, tfull)
262
+ assert_allclose(y, yfull)
263
+
264
+ def _solve_robertson_lsoda(use_jac, banded):
265
+
266
+ if use_jac:
267
+ if banded:
268
+ jac = banded_stiff_jac
269
+ else:
270
+ jac = stiff_jac
271
+ else:
272
+ jac = None
273
+
274
+ if banded:
275
+ lband = 1
276
+ uband = 2
277
+ else:
278
+ lband = None
279
+ uband = None
280
+
281
+ r = ode(stiff_f, jac)
282
+ r.set_integrator('lsoda',
283
+ lband=lband, uband=uband,
284
+ rtol=1e-9, atol=1e-10,
285
+ )
286
+ t0 = 0
287
+ dt = 1
288
+ tend = 10
289
+ y0 = np.array([1.0, 1.0, 0.0, 0.0, 1.0])
290
+ r.set_initial_value(y0, t0)
291
+
292
+ t = [t0]
293
+ y = [y0]
294
+ while r.successful() and r.t < tend:
295
+ r.integrate(r.t + dt)
296
+ t.append(r.t)
297
+ y.append(r.y)
298
+
299
+ # Ensure that the Jacobian was evaluated
300
+ # iwork[12] has the number of Jacobian evaluations.
301
+ assert r._integrator.iwork[12] > 0
302
+
303
+ t = np.array(t)
304
+ y = np.array(y)
305
+ return t, y