scipy 1.15.3__cp313-cp313-macosx_12_0_arm64.whl → 1.16.0__cp313-cp313-macosx_12_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (630) hide show
  1. scipy/.dylibs/libscipy_openblas.dylib +0 -0
  2. scipy/__config__.py +8 -8
  3. scipy/__init__.py +3 -6
  4. scipy/_cyutility.cpython-313-darwin.so +0 -0
  5. scipy/_lib/_array_api.py +486 -161
  6. scipy/_lib/_array_api_compat_vendor.py +9 -0
  7. scipy/_lib/_bunch.py +4 -0
  8. scipy/_lib/_ccallback_c.cpython-313-darwin.so +0 -0
  9. scipy/_lib/_docscrape.py +1 -1
  10. scipy/_lib/_elementwise_iterative_method.py +15 -26
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_deprecation_call.cpython-313-darwin.so +0 -0
  13. scipy/_lib/_test_deprecation_def.cpython-313-darwin.so +0 -0
  14. scipy/_lib/_testutils.py +6 -2
  15. scipy/_lib/_util.py +222 -125
  16. scipy/_lib/array_api_compat/__init__.py +4 -4
  17. scipy/_lib/array_api_compat/_internal.py +19 -6
  18. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  19. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  20. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  21. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  22. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  23. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  24. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  25. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  26. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  27. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  28. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  29. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  30. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  31. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  32. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  33. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  34. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  35. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  36. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  37. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  38. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  39. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  40. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  41. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  42. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  43. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  44. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  45. scipy/_lib/array_api_extra/__init__.py +26 -3
  46. scipy/_lib/array_api_extra/_delegation.py +171 -0
  47. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  48. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  49. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  50. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  51. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  52. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  59. scipy/_lib/array_api_extra/testing.py +359 -0
  60. scipy/_lib/decorator.py +2 -2
  61. scipy/_lib/doccer.py +1 -7
  62. scipy/_lib/messagestream.cpython-313-darwin.so +0 -0
  63. scipy/_lib/pyprima/__init__.py +212 -0
  64. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  65. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  66. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  67. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  68. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  69. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  70. scipy/_lib/pyprima/cobyla/update.py +289 -0
  71. scipy/_lib/pyprima/common/__init__.py +0 -0
  72. scipy/_lib/pyprima/common/_bounds.py +34 -0
  73. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  74. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  75. scipy/_lib/pyprima/common/_project.py +173 -0
  76. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  77. scipy/_lib/pyprima/common/consts.py +47 -0
  78. scipy/_lib/pyprima/common/evaluate.py +99 -0
  79. scipy/_lib/pyprima/common/history.py +38 -0
  80. scipy/_lib/pyprima/common/infos.py +30 -0
  81. scipy/_lib/pyprima/common/linalg.py +435 -0
  82. scipy/_lib/pyprima/common/message.py +290 -0
  83. scipy/_lib/pyprima/common/powalg.py +131 -0
  84. scipy/_lib/pyprima/common/preproc.py +277 -0
  85. scipy/_lib/pyprima/common/present.py +5 -0
  86. scipy/_lib/pyprima/common/ratio.py +54 -0
  87. scipy/_lib/pyprima/common/redrho.py +47 -0
  88. scipy/_lib/pyprima/common/selectx.py +296 -0
  89. scipy/_lib/tests/test__util.py +105 -121
  90. scipy/_lib/tests/test_array_api.py +166 -35
  91. scipy/_lib/tests/test_bunch.py +7 -0
  92. scipy/_lib/tests/test_ccallback.py +2 -10
  93. scipy/_lib/tests/test_public_api.py +13 -0
  94. scipy/cluster/_hierarchy.cpython-313-darwin.so +0 -0
  95. scipy/cluster/_optimal_leaf_ordering.cpython-313-darwin.so +0 -0
  96. scipy/cluster/_vq.cpython-313-darwin.so +0 -0
  97. scipy/cluster/hierarchy.py +393 -223
  98. scipy/cluster/tests/test_hierarchy.py +273 -335
  99. scipy/cluster/tests/test_vq.py +45 -61
  100. scipy/cluster/vq.py +39 -35
  101. scipy/conftest.py +282 -151
  102. scipy/constants/_constants.py +4 -1
  103. scipy/constants/tests/test_codata.py +2 -2
  104. scipy/constants/tests/test_constants.py +11 -18
  105. scipy/datasets/_download_all.py +15 -1
  106. scipy/datasets/_fetchers.py +7 -1
  107. scipy/datasets/_utils.py +1 -1
  108. scipy/differentiate/_differentiate.py +25 -25
  109. scipy/differentiate/tests/test_differentiate.py +24 -25
  110. scipy/fft/_basic.py +20 -0
  111. scipy/fft/_helper.py +3 -34
  112. scipy/fft/_pocketfft/helper.py +29 -1
  113. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  114. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  115. scipy/fft/_realtransforms.py +13 -0
  116. scipy/fft/tests/test_basic.py +27 -25
  117. scipy/fft/tests/test_fftlog.py +16 -7
  118. scipy/fft/tests/test_helper.py +18 -34
  119. scipy/fft/tests/test_real_transforms.py +8 -10
  120. scipy/fftpack/convolve.cpython-313-darwin.so +0 -0
  121. scipy/fftpack/tests/test_basic.py +2 -4
  122. scipy/fftpack/tests/test_real_transforms.py +8 -9
  123. scipy/integrate/_bvp.py +9 -3
  124. scipy/integrate/_cubature.py +3 -2
  125. scipy/integrate/_dop.cpython-313-darwin.so +0 -0
  126. scipy/integrate/_lsoda.cpython-313-darwin.so +0 -0
  127. scipy/integrate/_ode.py +9 -2
  128. scipy/integrate/_odepack.cpython-313-darwin.so +0 -0
  129. scipy/integrate/_quad_vec.py +21 -29
  130. scipy/integrate/_quadpack.cpython-313-darwin.so +0 -0
  131. scipy/integrate/_quadpack_py.py +11 -7
  132. scipy/integrate/_quadrature.py +3 -3
  133. scipy/integrate/_rules/_base.py +2 -2
  134. scipy/integrate/_tanhsinh.py +48 -47
  135. scipy/integrate/_test_odeint_banded.cpython-313-darwin.so +0 -0
  136. scipy/integrate/_vode.cpython-313-darwin.so +0 -0
  137. scipy/integrate/tests/test__quad_vec.py +0 -6
  138. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  139. scipy/integrate/tests/test_cubature.py +21 -35
  140. scipy/integrate/tests/test_quadrature.py +6 -8
  141. scipy/integrate/tests/test_tanhsinh.py +56 -48
  142. scipy/interpolate/__init__.py +70 -58
  143. scipy/interpolate/_bary_rational.py +22 -22
  144. scipy/interpolate/_bsplines.py +119 -66
  145. scipy/interpolate/_cubic.py +65 -50
  146. scipy/interpolate/_dfitpack.cpython-313-darwin.so +0 -0
  147. scipy/interpolate/_dierckx.cpython-313-darwin.so +0 -0
  148. scipy/interpolate/_fitpack.cpython-313-darwin.so +0 -0
  149. scipy/interpolate/_fitpack2.py +9 -6
  150. scipy/interpolate/_fitpack_impl.py +32 -26
  151. scipy/interpolate/_fitpack_repro.py +23 -19
  152. scipy/interpolate/_interpnd.cpython-313-darwin.so +0 -0
  153. scipy/interpolate/_interpolate.py +30 -12
  154. scipy/interpolate/_ndbspline.py +13 -18
  155. scipy/interpolate/_ndgriddata.py +5 -8
  156. scipy/interpolate/_polyint.py +95 -31
  157. scipy/interpolate/_ppoly.cpython-313-darwin.so +0 -0
  158. scipy/interpolate/_rbf.py +2 -2
  159. scipy/interpolate/_rbfinterp.py +1 -1
  160. scipy/interpolate/_rbfinterp_pythran.cpython-313-darwin.so +0 -0
  161. scipy/interpolate/_rgi.py +31 -26
  162. scipy/interpolate/_rgi_cython.cpython-313-darwin.so +0 -0
  163. scipy/interpolate/dfitpack.py +0 -20
  164. scipy/interpolate/interpnd.py +1 -2
  165. scipy/interpolate/tests/test_bary_rational.py +2 -2
  166. scipy/interpolate/tests/test_bsplines.py +97 -1
  167. scipy/interpolate/tests/test_fitpack2.py +39 -1
  168. scipy/interpolate/tests/test_interpnd.py +32 -20
  169. scipy/interpolate/tests/test_interpolate.py +48 -4
  170. scipy/interpolate/tests/test_rgi.py +2 -1
  171. scipy/io/_fast_matrix_market/__init__.py +2 -0
  172. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  173. scipy/io/_harwell_boeing/hb.py +7 -11
  174. scipy/io/_idl.py +5 -7
  175. scipy/io/_netcdf.py +15 -5
  176. scipy/io/_test_fortran.cpython-313-darwin.so +0 -0
  177. scipy/io/arff/tests/test_arffread.py +3 -3
  178. scipy/io/matlab/__init__.py +5 -3
  179. scipy/io/matlab/_mio.py +4 -1
  180. scipy/io/matlab/_mio5.py +19 -13
  181. scipy/io/matlab/_mio5_utils.cpython-313-darwin.so +0 -0
  182. scipy/io/matlab/_mio_utils.cpython-313-darwin.so +0 -0
  183. scipy/io/matlab/_miobase.py +4 -1
  184. scipy/io/matlab/_streams.cpython-313-darwin.so +0 -0
  185. scipy/io/matlab/tests/test_mio.py +46 -18
  186. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  187. scipy/io/tests/test_mmio.py +7 -1
  188. scipy/io/tests/test_wavfile.py +41 -0
  189. scipy/io/wavfile.py +57 -10
  190. scipy/linalg/_basic.py +113 -86
  191. scipy/linalg/_cythonized_array_utils.cpython-313-darwin.so +0 -0
  192. scipy/linalg/_decomp.py +22 -9
  193. scipy/linalg/_decomp_cholesky.py +28 -13
  194. scipy/linalg/_decomp_cossin.py +45 -30
  195. scipy/linalg/_decomp_interpolative.cpython-313-darwin.so +0 -0
  196. scipy/linalg/_decomp_ldl.py +4 -1
  197. scipy/linalg/_decomp_lu.py +18 -6
  198. scipy/linalg/_decomp_lu_cython.cpython-313-darwin.so +0 -0
  199. scipy/linalg/_decomp_polar.py +2 -0
  200. scipy/linalg/_decomp_qr.py +6 -2
  201. scipy/linalg/_decomp_qz.py +3 -0
  202. scipy/linalg/_decomp_schur.py +3 -1
  203. scipy/linalg/_decomp_svd.py +13 -2
  204. scipy/linalg/_decomp_update.cpython-313-darwin.so +0 -0
  205. scipy/linalg/_expm_frechet.py +4 -0
  206. scipy/linalg/_fblas.cpython-313-darwin.so +0 -0
  207. scipy/linalg/_flapack.cpython-313-darwin.so +0 -0
  208. scipy/linalg/_linalg_pythran.cpython-313-darwin.so +0 -0
  209. scipy/linalg/_matfuncs.py +187 -4
  210. scipy/linalg/_matfuncs_expm.cpython-313-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-darwin.so +0 -0
  212. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  213. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-darwin.so +0 -0
  214. scipy/linalg/_procrustes.py +2 -0
  215. scipy/linalg/_sketches.py +17 -6
  216. scipy/linalg/_solve_toeplitz.cpython-313-darwin.so +0 -0
  217. scipy/linalg/_solvers.py +7 -2
  218. scipy/linalg/_special_matrices.py +26 -36
  219. scipy/linalg/blas.py +35 -24
  220. scipy/linalg/cython_blas.cpython-313-darwin.so +0 -0
  221. scipy/linalg/cython_lapack.cpython-313-darwin.so +0 -0
  222. scipy/linalg/lapack.py +22 -2
  223. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  224. scipy/linalg/tests/test_basic.py +31 -16
  225. scipy/linalg/tests/test_batch.py +588 -0
  226. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  227. scipy/linalg/tests/test_decomp.py +40 -3
  228. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  229. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  230. scipy/linalg/tests/test_lapack.py +115 -7
  231. scipy/linalg/tests/test_matfuncs.py +157 -102
  232. scipy/linalg/tests/test_procrustes.py +0 -7
  233. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  234. scipy/linalg/tests/test_special_matrices.py +1 -5
  235. scipy/ndimage/__init__.py +1 -0
  236. scipy/ndimage/_cytest.cpython-313-darwin.so +0 -0
  237. scipy/ndimage/_delegators.py +8 -2
  238. scipy/ndimage/_filters.py +453 -5
  239. scipy/ndimage/_interpolation.py +36 -6
  240. scipy/ndimage/_measurements.py +4 -2
  241. scipy/ndimage/_morphology.py +5 -0
  242. scipy/ndimage/_nd_image.cpython-313-darwin.so +0 -0
  243. scipy/ndimage/_ni_docstrings.py +5 -1
  244. scipy/ndimage/_ni_label.cpython-313-darwin.so +0 -0
  245. scipy/ndimage/_ni_support.py +1 -5
  246. scipy/ndimage/_rank_filter_1d.cpython-313-darwin.so +0 -0
  247. scipy/ndimage/_support_alternative_backends.py +18 -6
  248. scipy/ndimage/tests/test_filters.py +370 -259
  249. scipy/ndimage/tests/test_fourier.py +7 -9
  250. scipy/ndimage/tests/test_interpolation.py +68 -61
  251. scipy/ndimage/tests/test_measurements.py +18 -35
  252. scipy/ndimage/tests/test_morphology.py +143 -131
  253. scipy/ndimage/tests/test_splines.py +1 -3
  254. scipy/odr/__odrpack.cpython-313-darwin.so +0 -0
  255. scipy/optimize/_basinhopping.py +13 -7
  256. scipy/optimize/_bglu_dense.cpython-313-darwin.so +0 -0
  257. scipy/optimize/_bracket.py +17 -24
  258. scipy/optimize/_chandrupatla.py +9 -10
  259. scipy/optimize/_cobyla_py.py +104 -123
  260. scipy/optimize/_constraints.py +14 -10
  261. scipy/optimize/_differentiable_functions.py +371 -230
  262. scipy/optimize/_differentialevolution.py +4 -3
  263. scipy/optimize/_direct.cpython-313-darwin.so +0 -0
  264. scipy/optimize/_dual_annealing.py +1 -1
  265. scipy/optimize/_elementwise.py +1 -4
  266. scipy/optimize/_group_columns.cpython-313-darwin.so +0 -0
  267. scipy/optimize/_lbfgsb.cpython-313-darwin.so +0 -0
  268. scipy/optimize/_lbfgsb_py.py +80 -24
  269. scipy/optimize/_linprog_doc.py +2 -2
  270. scipy/optimize/_linprog_highs.py +2 -2
  271. scipy/optimize/_linprog_ip.py +25 -10
  272. scipy/optimize/_linprog_util.py +14 -16
  273. scipy/optimize/_lsap.cpython-313-darwin.so +0 -0
  274. scipy/optimize/_lsq/common.py +3 -3
  275. scipy/optimize/_lsq/dogbox.py +16 -2
  276. scipy/optimize/_lsq/givens_elimination.cpython-313-darwin.so +0 -0
  277. scipy/optimize/_lsq/least_squares.py +198 -126
  278. scipy/optimize/_lsq/lsq_linear.py +6 -6
  279. scipy/optimize/_lsq/trf.py +35 -8
  280. scipy/optimize/_milp.py +3 -1
  281. scipy/optimize/_minimize.py +105 -36
  282. scipy/optimize/_minpack.cpython-313-darwin.so +0 -0
  283. scipy/optimize/_minpack_py.py +21 -14
  284. scipy/optimize/_moduleTNC.cpython-313-darwin.so +0 -0
  285. scipy/optimize/_nnls.py +20 -21
  286. scipy/optimize/_nonlin.py +34 -3
  287. scipy/optimize/_numdiff.py +288 -110
  288. scipy/optimize/_optimize.py +86 -48
  289. scipy/optimize/_pava_pybind.cpython-313-darwin.so +0 -0
  290. scipy/optimize/_remove_redundancy.py +5 -5
  291. scipy/optimize/_root_scalar.py +1 -1
  292. scipy/optimize/_shgo.py +6 -0
  293. scipy/optimize/_shgo_lib/_complex.py +1 -1
  294. scipy/optimize/_slsqp_py.py +216 -124
  295. scipy/optimize/_slsqplib.cpython-313-darwin.so +0 -0
  296. scipy/optimize/_spectral.py +1 -1
  297. scipy/optimize/_tnc.py +8 -1
  298. scipy/optimize/_trlib/_trlib.cpython-313-darwin.so +0 -0
  299. scipy/optimize/_trustregion.py +20 -6
  300. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  301. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  302. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  303. scipy/optimize/_trustregion_constr/projections.py +12 -8
  304. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  305. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  306. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  307. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  308. scipy/optimize/_trustregion_exact.py +0 -1
  309. scipy/optimize/_zeros.cpython-313-darwin.so +0 -0
  310. scipy/optimize/_zeros_py.py +97 -17
  311. scipy/optimize/cython_optimize/_zeros.cpython-313-darwin.so +0 -0
  312. scipy/optimize/slsqp.py +0 -1
  313. scipy/optimize/tests/test__basinhopping.py +1 -1
  314. scipy/optimize/tests/test__differential_evolution.py +4 -4
  315. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  316. scipy/optimize/tests/test__numdiff.py +66 -22
  317. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  318. scipy/optimize/tests/test__shgo.py +9 -1
  319. scipy/optimize/tests/test_bracket.py +36 -46
  320. scipy/optimize/tests/test_chandrupatla.py +133 -135
  321. scipy/optimize/tests/test_cobyla.py +74 -45
  322. scipy/optimize/tests/test_constraints.py +1 -1
  323. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  324. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  325. scipy/optimize/tests/test_least_squares.py +125 -13
  326. scipy/optimize/tests/test_linear_assignment.py +3 -3
  327. scipy/optimize/tests/test_linprog.py +3 -3
  328. scipy/optimize/tests/test_lsq_linear.py +6 -6
  329. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  330. scipy/optimize/tests/test_minpack.py +4 -4
  331. scipy/optimize/tests/test_nnls.py +43 -3
  332. scipy/optimize/tests/test_nonlin.py +36 -0
  333. scipy/optimize/tests/test_optimize.py +98 -20
  334. scipy/optimize/tests/test_slsqp.py +36 -4
  335. scipy/optimize/tests/test_zeros.py +34 -1
  336. scipy/signal/__init__.py +12 -23
  337. scipy/signal/_delegators.py +568 -0
  338. scipy/signal/_filter_design.py +459 -241
  339. scipy/signal/_fir_filter_design.py +262 -90
  340. scipy/signal/_lti_conversion.py +3 -2
  341. scipy/signal/_ltisys.py +118 -91
  342. scipy/signal/_max_len_seq_inner.cpython-313-darwin.so +0 -0
  343. scipy/signal/_peak_finding_utils.cpython-313-darwin.so +0 -0
  344. scipy/signal/_polyutils.py +172 -0
  345. scipy/signal/_short_time_fft.py +519 -70
  346. scipy/signal/_signal_api.py +30 -0
  347. scipy/signal/_signaltools.py +719 -399
  348. scipy/signal/_sigtools.cpython-313-darwin.so +0 -0
  349. scipy/signal/_sosfilt.cpython-313-darwin.so +0 -0
  350. scipy/signal/_spectral_py.py +230 -50
  351. scipy/signal/_spline.cpython-313-darwin.so +0 -0
  352. scipy/signal/_spline_filters.py +108 -68
  353. scipy/signal/_support_alternative_backends.py +73 -0
  354. scipy/signal/_upfirdn.py +4 -1
  355. scipy/signal/_upfirdn_apply.cpython-313-darwin.so +0 -0
  356. scipy/signal/_waveforms.py +2 -11
  357. scipy/signal/_wavelets.py +1 -1
  358. scipy/signal/fir_filter_design.py +1 -0
  359. scipy/signal/spline.py +4 -11
  360. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  361. scipy/signal/tests/test_bsplines.py +114 -79
  362. scipy/signal/tests/test_cont2discrete.py +9 -2
  363. scipy/signal/tests/test_filter_design.py +721 -481
  364. scipy/signal/tests/test_fir_filter_design.py +332 -140
  365. scipy/signal/tests/test_savitzky_golay.py +4 -3
  366. scipy/signal/tests/test_short_time_fft.py +221 -3
  367. scipy/signal/tests/test_signaltools.py +2145 -1349
  368. scipy/signal/tests/test_spectral.py +50 -6
  369. scipy/signal/tests/test_splines.py +161 -96
  370. scipy/signal/tests/test_upfirdn.py +84 -50
  371. scipy/signal/tests/test_waveforms.py +20 -0
  372. scipy/signal/tests/test_windows.py +607 -466
  373. scipy/signal/windows/_windows.py +287 -148
  374. scipy/sparse/__init__.py +23 -4
  375. scipy/sparse/_base.py +270 -108
  376. scipy/sparse/_bsr.py +7 -4
  377. scipy/sparse/_compressed.py +59 -231
  378. scipy/sparse/_construct.py +90 -38
  379. scipy/sparse/_coo.py +115 -181
  380. scipy/sparse/_csc.py +4 -4
  381. scipy/sparse/_csparsetools.cpython-313-darwin.so +0 -0
  382. scipy/sparse/_csr.py +2 -2
  383. scipy/sparse/_data.py +48 -48
  384. scipy/sparse/_dia.py +105 -18
  385. scipy/sparse/_dok.py +0 -23
  386. scipy/sparse/_index.py +4 -4
  387. scipy/sparse/_matrix.py +23 -0
  388. scipy/sparse/_sparsetools.cpython-313-darwin.so +0 -0
  389. scipy/sparse/_sputils.py +37 -22
  390. scipy/sparse/base.py +0 -9
  391. scipy/sparse/bsr.py +0 -14
  392. scipy/sparse/compressed.py +0 -23
  393. scipy/sparse/construct.py +0 -6
  394. scipy/sparse/coo.py +0 -14
  395. scipy/sparse/csc.py +0 -3
  396. scipy/sparse/csgraph/_flow.cpython-313-darwin.so +0 -0
  397. scipy/sparse/csgraph/_matching.cpython-313-darwin.so +0 -0
  398. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-darwin.so +0 -0
  399. scipy/sparse/csgraph/_reordering.cpython-313-darwin.so +0 -0
  400. scipy/sparse/csgraph/_shortest_path.cpython-313-darwin.so +0 -0
  401. scipy/sparse/csgraph/_tools.cpython-313-darwin.so +0 -0
  402. scipy/sparse/csgraph/_traversal.cpython-313-darwin.so +0 -0
  403. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  404. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  405. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  406. scipy/sparse/csr.py +0 -5
  407. scipy/sparse/data.py +1 -6
  408. scipy/sparse/dia.py +0 -7
  409. scipy/sparse/dok.py +0 -10
  410. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-darwin.so +0 -0
  411. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  412. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  413. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-darwin.so +0 -0
  414. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  415. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  416. scipy/sparse/linalg/_interface.py +17 -18
  417. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  418. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  419. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  420. scipy/sparse/linalg/_isolve/minres.py +5 -5
  421. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  422. scipy/sparse/linalg/_isolve/utils.py +2 -8
  423. scipy/sparse/linalg/_matfuncs.py +1 -1
  424. scipy/sparse/linalg/_norm.py +1 -1
  425. scipy/sparse/linalg/_propack/_cpropack.cpython-313-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_dpropack.cpython-313-darwin.so +0 -0
  427. scipy/sparse/linalg/_propack/_spropack.cpython-313-darwin.so +0 -0
  428. scipy/sparse/linalg/_propack/_zpropack.cpython-313-darwin.so +0 -0
  429. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  430. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  431. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  432. scipy/sparse/tests/test_base.py +214 -42
  433. scipy/sparse/tests/test_common1d.py +7 -7
  434. scipy/sparse/tests/test_construct.py +1 -1
  435. scipy/sparse/tests/test_coo.py +272 -4
  436. scipy/sparse/tests/test_sparsetools.py +5 -0
  437. scipy/sparse/tests/test_sputils.py +36 -7
  438. scipy/spatial/_ckdtree.cpython-313-darwin.so +0 -0
  439. scipy/spatial/_distance_pybind.cpython-313-darwin.so +0 -0
  440. scipy/spatial/_distance_wrap.cpython-313-darwin.so +0 -0
  441. scipy/spatial/_hausdorff.cpython-313-darwin.so +0 -0
  442. scipy/spatial/_qhull.cpython-313-darwin.so +0 -0
  443. scipy/spatial/_voronoi.cpython-313-darwin.so +0 -0
  444. scipy/spatial/distance.py +49 -42
  445. scipy/spatial/tests/test_distance.py +15 -1
  446. scipy/spatial/tests/test_kdtree.py +1 -0
  447. scipy/spatial/tests/test_qhull.py +7 -2
  448. scipy/spatial/transform/__init__.py +5 -3
  449. scipy/spatial/transform/_rigid_transform.cpython-313-darwin.so +0 -0
  450. scipy/spatial/transform/_rotation.cpython-313-darwin.so +0 -0
  451. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  452. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  453. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  454. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  455. scipy/special/__init__.py +1 -47
  456. scipy/special/_add_newdocs.py +34 -772
  457. scipy/special/_basic.py +22 -25
  458. scipy/special/_comb.cpython-313-darwin.so +0 -0
  459. scipy/special/_ellip_harm_2.cpython-313-darwin.so +0 -0
  460. scipy/special/_gufuncs.cpython-313-darwin.so +0 -0
  461. scipy/special/_logsumexp.py +67 -58
  462. scipy/special/_orthogonal.pyi +1 -1
  463. scipy/special/_specfun.cpython-313-darwin.so +0 -0
  464. scipy/special/_special_ufuncs.cpython-313-darwin.so +0 -0
  465. scipy/special/_spherical_bessel.py +4 -4
  466. scipy/special/_support_alternative_backends.py +212 -119
  467. scipy/special/_test_internal.cpython-313-darwin.so +0 -0
  468. scipy/special/_testutils.py +4 -4
  469. scipy/special/_ufuncs.cpython-313-darwin.so +0 -0
  470. scipy/special/_ufuncs.pyi +1 -0
  471. scipy/special/_ufuncs.pyx +215 -1400
  472. scipy/special/_ufuncs_cxx.cpython-313-darwin.so +0 -0
  473. scipy/special/_ufuncs_cxx.pxd +2 -15
  474. scipy/special/_ufuncs_cxx.pyx +5 -44
  475. scipy/special/_ufuncs_cxx_defs.h +2 -16
  476. scipy/special/_ufuncs_defs.h +0 -8
  477. scipy/special/cython_special.cpython-313-darwin.so +0 -0
  478. scipy/special/cython_special.pxd +1 -1
  479. scipy/special/tests/_cython_examples/meson.build +10 -1
  480. scipy/special/tests/test_basic.py +153 -20
  481. scipy/special/tests/test_boost_ufuncs.py +3 -0
  482. scipy/special/tests/test_cdflib.py +35 -11
  483. scipy/special/tests/test_gammainc.py +16 -0
  484. scipy/special/tests/test_hyp2f1.py +2 -2
  485. scipy/special/tests/test_log1mexp.py +85 -0
  486. scipy/special/tests/test_logsumexp.py +206 -64
  487. scipy/special/tests/test_mpmath.py +1 -0
  488. scipy/special/tests/test_nan_inputs.py +1 -1
  489. scipy/special/tests/test_orthogonal.py +17 -18
  490. scipy/special/tests/test_sf_error.py +3 -2
  491. scipy/special/tests/test_sph_harm.py +6 -7
  492. scipy/special/tests/test_support_alternative_backends.py +211 -76
  493. scipy/stats/__init__.py +4 -1
  494. scipy/stats/_ansari_swilk_statistics.cpython-313-darwin.so +0 -0
  495. scipy/stats/_axis_nan_policy.py +5 -12
  496. scipy/stats/_biasedurn.cpython-313-darwin.so +0 -0
  497. scipy/stats/_continued_fraction.py +387 -0
  498. scipy/stats/_continuous_distns.py +277 -310
  499. scipy/stats/_correlation.py +1 -1
  500. scipy/stats/_covariance.py +6 -3
  501. scipy/stats/_discrete_distns.py +39 -32
  502. scipy/stats/_distn_infrastructure.py +39 -12
  503. scipy/stats/_distribution_infrastructure.py +920 -238
  504. scipy/stats/_entropy.py +9 -10
  505. scipy/{_lib → stats}/_finite_differences.py +1 -1
  506. scipy/stats/_hypotests.py +83 -50
  507. scipy/stats/_kde.py +53 -49
  508. scipy/stats/_ksstats.py +1 -1
  509. scipy/stats/_levy_stable/__init__.py +7 -15
  510. scipy/stats/_levy_stable/levyst.cpython-313-darwin.so +0 -0
  511. scipy/stats/_morestats.py +118 -73
  512. scipy/stats/_mstats_basic.py +13 -17
  513. scipy/stats/_mstats_extras.py +8 -8
  514. scipy/stats/_multivariate.py +89 -113
  515. scipy/stats/_new_distributions.py +97 -20
  516. scipy/stats/_page_trend_test.py +12 -5
  517. scipy/stats/_probability_distribution.py +265 -43
  518. scipy/stats/_qmc.py +14 -9
  519. scipy/stats/_qmc_cy.cpython-313-darwin.so +0 -0
  520. scipy/stats/_qmvnt.py +16 -95
  521. scipy/stats/_qmvnt_cy.cpython-313-darwin.so +0 -0
  522. scipy/stats/_quantile.py +335 -0
  523. scipy/stats/_rcont/rcont.cpython-313-darwin.so +0 -0
  524. scipy/stats/_resampling.py +5 -30
  525. scipy/stats/_sampling.py +1 -1
  526. scipy/stats/_sobol.cpython-313-darwin.so +0 -0
  527. scipy/stats/_stats.cpython-313-darwin.so +0 -0
  528. scipy/stats/_stats_mstats_common.py +21 -2
  529. scipy/stats/_stats_py.py +551 -477
  530. scipy/stats/_stats_pythran.cpython-313-darwin.so +0 -0
  531. scipy/stats/_unuran/unuran_wrapper.cpython-313-darwin.so +0 -0
  532. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  533. scipy/stats/_variation.py +6 -8
  534. scipy/stats/_wilcoxon.py +13 -7
  535. scipy/stats/tests/common_tests.py +6 -4
  536. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  537. scipy/stats/tests/test_continued_fraction.py +173 -0
  538. scipy/stats/tests/test_continuous.py +379 -60
  539. scipy/stats/tests/test_continuous_basic.py +18 -12
  540. scipy/stats/tests/test_discrete_basic.py +14 -8
  541. scipy/stats/tests/test_discrete_distns.py +16 -16
  542. scipy/stats/tests/test_distributions.py +95 -75
  543. scipy/stats/tests/test_entropy.py +40 -48
  544. scipy/stats/tests/test_fit.py +4 -3
  545. scipy/stats/tests/test_hypotests.py +153 -24
  546. scipy/stats/tests/test_kdeoth.py +109 -41
  547. scipy/stats/tests/test_marray.py +289 -0
  548. scipy/stats/tests/test_morestats.py +81 -49
  549. scipy/stats/tests/test_mstats_basic.py +3 -3
  550. scipy/stats/tests/test_multivariate.py +434 -83
  551. scipy/stats/tests/test_qmc.py +13 -10
  552. scipy/stats/tests/test_quantile.py +199 -0
  553. scipy/stats/tests/test_rank.py +119 -112
  554. scipy/stats/tests/test_resampling.py +47 -56
  555. scipy/stats/tests/test_sampling.py +9 -4
  556. scipy/stats/tests/test_stats.py +799 -939
  557. scipy/stats/tests/test_variation.py +8 -6
  558. scipy/version.py +2 -2
  559. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
  560. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/METADATA +11 -11
  561. {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/RECORD +562 -569
  562. scipy-1.16.0.dist-info/WHEEL +6 -0
  563. scipy/_lib/array_api_extra/_funcs.py +0 -484
  564. scipy/_lib/array_api_extra/_typing.py +0 -8
  565. scipy/interpolate/_bspl.cpython-313-darwin.so +0 -0
  566. scipy/optimize/_cobyla.cpython-313-darwin.so +0 -0
  567. scipy/optimize/_cython_nnls.cpython-313-darwin.so +0 -0
  568. scipy/optimize/_slsqp.cpython-313-darwin.so +0 -0
  569. scipy/spatial/qhull_src/COPYING.txt +0 -38
  570. scipy/special/libsf_error_state.dylib +0 -0
  571. scipy/special/tests/test_log_softmax.py +0 -109
  572. scipy/special/tests/test_xsf_cuda.py +0 -114
  573. scipy/special/xsf/binom.h +0 -89
  574. scipy/special/xsf/cdflib.h +0 -100
  575. scipy/special/xsf/cephes/airy.h +0 -307
  576. scipy/special/xsf/cephes/besselpoly.h +0 -51
  577. scipy/special/xsf/cephes/beta.h +0 -257
  578. scipy/special/xsf/cephes/cbrt.h +0 -131
  579. scipy/special/xsf/cephes/chbevl.h +0 -85
  580. scipy/special/xsf/cephes/chdtr.h +0 -193
  581. scipy/special/xsf/cephes/const.h +0 -87
  582. scipy/special/xsf/cephes/ellie.h +0 -293
  583. scipy/special/xsf/cephes/ellik.h +0 -251
  584. scipy/special/xsf/cephes/ellpe.h +0 -107
  585. scipy/special/xsf/cephes/ellpk.h +0 -117
  586. scipy/special/xsf/cephes/expn.h +0 -260
  587. scipy/special/xsf/cephes/gamma.h +0 -398
  588. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  589. scipy/special/xsf/cephes/hyperg.h +0 -361
  590. scipy/special/xsf/cephes/i0.h +0 -149
  591. scipy/special/xsf/cephes/i1.h +0 -158
  592. scipy/special/xsf/cephes/igam.h +0 -421
  593. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  594. scipy/special/xsf/cephes/igami.h +0 -313
  595. scipy/special/xsf/cephes/j0.h +0 -225
  596. scipy/special/xsf/cephes/j1.h +0 -198
  597. scipy/special/xsf/cephes/jv.h +0 -715
  598. scipy/special/xsf/cephes/k0.h +0 -164
  599. scipy/special/xsf/cephes/k1.h +0 -163
  600. scipy/special/xsf/cephes/kn.h +0 -243
  601. scipy/special/xsf/cephes/lanczos.h +0 -112
  602. scipy/special/xsf/cephes/ndtr.h +0 -275
  603. scipy/special/xsf/cephes/poch.h +0 -85
  604. scipy/special/xsf/cephes/polevl.h +0 -167
  605. scipy/special/xsf/cephes/psi.h +0 -194
  606. scipy/special/xsf/cephes/rgamma.h +0 -111
  607. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  608. scipy/special/xsf/cephes/shichi.h +0 -248
  609. scipy/special/xsf/cephes/sici.h +0 -224
  610. scipy/special/xsf/cephes/sindg.h +0 -221
  611. scipy/special/xsf/cephes/tandg.h +0 -139
  612. scipy/special/xsf/cephes/trig.h +0 -58
  613. scipy/special/xsf/cephes/unity.h +0 -186
  614. scipy/special/xsf/cephes/zeta.h +0 -172
  615. scipy/special/xsf/config.h +0 -304
  616. scipy/special/xsf/digamma.h +0 -205
  617. scipy/special/xsf/error.h +0 -57
  618. scipy/special/xsf/evalpoly.h +0 -47
  619. scipy/special/xsf/expint.h +0 -266
  620. scipy/special/xsf/hyp2f1.h +0 -694
  621. scipy/special/xsf/iv_ratio.h +0 -173
  622. scipy/special/xsf/lambertw.h +0 -150
  623. scipy/special/xsf/loggamma.h +0 -163
  624. scipy/special/xsf/sici.h +0 -200
  625. scipy/special/xsf/tools.h +0 -427
  626. scipy/special/xsf/trig.h +0 -164
  627. scipy/special/xsf/wright_bessel.h +0 -843
  628. scipy/special/xsf/zlog1.h +0 -35
  629. scipy/stats/_mvn.cpython-313-darwin.so +0 -0
  630. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -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,13 +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`` or ``res.error < res.integral * rtol``. The error
102
- estimate is as described in [1]_ Section 5 but with a lower bound of
103
- ``eps * res.integral``. While not theoretically rigorous or
104
- conservative, it is said to work well in practice. Must be non-negative
105
- and finite if `log` is False, and must be expressed as the log of a
106
- 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``.
107
104
  preserve_shape : bool, default: False
108
105
  In the following, "arguments of `f`" refers to the array ``xi`` and
109
106
  any arrays within ``argsi``. Let ``shape`` be the broadcasted shape
@@ -128,7 +125,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
128
125
  An optional user-supplied function to be called before the first
129
126
  iteration and after each iteration.
130
127
  Called as ``callback(res)``, where ``res`` is a ``_RichResult``
131
- similar to that returned by `_differentiate` (but containing the
128
+ similar to that returned by `tanhsinh` (but containing the
132
129
  current iterate's values of all variables). If `callback` raises a
133
130
  ``StopIteration``, the algorithm will terminate immediately and
134
131
  `tanhsinh` will return a result object. `callback` must not mutate
@@ -175,6 +172,12 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
175
172
  finite-precision arithmetic, including some described by [2]_ and [3]_. The
176
173
  tanh-sinh scheme was originally introduced in [4]_.
177
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
+
178
181
  Due to floating-point error in the abscissae, the function may be evaluated
179
182
  at the endpoints of the interval during iterations, but the values returned by
180
183
  the function at the endpoints will be ignored.
@@ -364,7 +367,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
364
367
  aerr = xp_ravel(xp.full(shape, xp.nan, dtype=dtype)) # absolute error
365
368
  status = xp_ravel(xp.full(shape, eim._EINPROGRESS, dtype=xp.int32))
366
369
  h0 = _get_base_step(dtype, xp)
367
- h0 = xp_real(h0) # base step
370
+ h0 = xp.real(h0) # base step
368
371
 
369
372
  # For term `d4` of error estimate ([1] Section 5), we need to keep the
370
373
  # most extreme abscissae and corresponding `fj`s, `wj`s in Euler-Maclaurin
@@ -403,8 +406,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
403
406
 
404
407
  # Perform abscissae substitutions for infinite limits of integration
405
408
  xj = xp_copy(work.xj)
406
- # use xp_real here to avoid cupy/cupy#8434
407
- 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)
408
410
  xj[work.binf] = 1/xj[work.binf] - 1 + work.a0[work.binf]
409
411
  xj[work.ainf] *= -1
410
412
  return xj
@@ -454,7 +456,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
454
456
 
455
457
  # Terminate if integral estimate becomes invalid
456
458
  if log:
457
- Sn_real = xp_real(work.Sn)
459
+ Sn_real = xp.real(work.Sn)
458
460
  Sn_pos_inf = xp.isinf(Sn_real) & (Sn_real > 0)
459
461
  i = (Sn_pos_inf | xp.isnan(work.Sn)) & ~stop
460
462
  else:
@@ -473,10 +475,7 @@ def tanhsinh(f, a, b, *, args=(), log=False, maxlevel=None, minlevel=2,
473
475
  # If the integration limits were such that b < a, we reversed them
474
476
  # to perform the calculation, and the final result needs to be negated.
475
477
  if log and xp.any(negative):
476
- dtype = res['integral'].dtype
477
- pi = xp.asarray(xp.pi, dtype=dtype)[()]
478
- j = xp.asarray(1j, dtype=xp.complex64)[()] # minimum complex type
479
- res['integral'] = res['integral'] + negative*pi*j
478
+ res['integral'] = res['integral'] + negative * xp.pi * 1.0j
480
479
  else:
481
480
  res['integral'][negative] *= -1
482
481
 
@@ -615,7 +614,7 @@ def _transform_to_limits(xjc, wj, a, b, xp):
615
614
  # these points; however, we can't easily filter out points since this
616
615
  # function is vectorized. Instead, zero the weights.
617
616
  # Note: values may have complex dtype, but have zero imaginary part
618
- 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)
619
618
  invalid = (xj_real <= a_real) | (xj_real >= b_real)
620
619
  wj[invalid] = 0
621
620
  return xj, wj
@@ -646,16 +645,16 @@ def _euler_maclaurin_sum(fj, work, xp):
646
645
 
647
646
  # integer index of the maximum abscissa at this level
648
647
  xr[invalid_r] = -xp.inf
649
- ir = xp.argmax(xp_real(xr), axis=0, keepdims=True)
648
+ ir = xp.argmax(xp.real(xr), axis=0, keepdims=True)
650
649
  # abscissa, function value, and weight at this index
651
650
  ### Not Array API Compatible... yet ###
652
- xr_max = xp_take_along_axis(xr, ir, axis=0)[0]
653
- fr_max = xp_take_along_axis(fr, ir, axis=0)[0]
654
- 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]
655
654
  # boolean indices at which maximum abscissa at this level exceeds
656
655
  # the incumbent maximum abscissa (from all previous levels)
657
656
  # note: abscissa may have complex dtype, but will have zero imaginary part
658
- j = xp_real(xr_max) > xp_real(xr0)
657
+ j = xp.real(xr_max) > xp.real(xr0)
659
658
  # Update record of the incumbent abscissa, function value, and weight
660
659
  xr0[j] = xr_max[j]
661
660
  fr0[j] = fr_max[j]
@@ -663,15 +662,15 @@ def _euler_maclaurin_sum(fj, work, xp):
663
662
 
664
663
  # integer index of the minimum abscissa at this level
665
664
  xl[invalid_l] = xp.inf
666
- il = xp.argmin(xp_real(xl), axis=0, keepdims=True)
665
+ il = xp.argmin(xp.real(xl), axis=0, keepdims=True)
667
666
  # abscissa, function value, and weight at this index
668
- xl_min = xp_take_along_axis(xl, il, axis=0)[0]
669
- fl_min = xp_take_along_axis(fl, il, axis=0)[0]
670
- 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]
671
670
  # boolean indices at which minimum abscissa at this level is less than
672
671
  # the incumbent minimum abscissa (from all previous levels)
673
672
  # note: abscissa may have complex dtype, but will have zero imaginary part
674
- j = xp_real(xl_min) < xp_real(xl0)
673
+ j = xp.real(xl_min) < xp.real(xl0)
675
674
  # Update record of the incumbent abscissa, function value, and weight
676
675
  xl0[j] = xl_min[j]
677
676
  fl0[j] = fl_min[j]
@@ -682,7 +681,7 @@ def _euler_maclaurin_sum(fj, work, xp):
682
681
  # rightmost term, whichever is greater.
683
682
  flwl0 = fl0 + xp.log(wl0) if work.log else fl0 * wl0 # leftmost term
684
683
  frwr0 = fr0 + xp.log(wr0) if work.log else fr0 * wr0 # rightmost term
685
- magnitude = xp_real if work.log else xp.abs
684
+ magnitude = xp.real if work.log else xp.abs
686
685
  work.d4 = xp.maximum(magnitude(flwl0), magnitude(frwr0))
687
686
 
688
687
  # There are two approaches to dealing with function values that are
@@ -769,14 +768,14 @@ def _estimate_error(work, xp):
769
768
  # complex values have imaginary part in increments of pi*j, which just
770
769
  # carries sign information of the original integral, so use of
771
770
  # `xp.real` here is equivalent to absolute value in real scale.
772
- d1 = xp_real(special.logsumexp(xp.stack([work.Sn, Snm1 + work.pi*1j]), axis=0))
773
- d2 = xp_real(special.logsumexp(xp.stack([work.Sn, Snm2 + work.pi*1j]), axis=0))
774
- 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)
775
774
  d4 = work.d4
776
775
  d5 = log_e1 + xp.real(work.Sn)
777
776
  temp = xp.where(d1 > -xp.inf, d1 ** 2 / d2, -xp.inf)
778
- ds = xp.stack([temp, 2 * d1, d3, d4, d5])
779
- aerr = xp.max(ds, axis=0)
777
+ ds = xp.stack([temp, 2 * d1, d3, d4])
778
+ aerr = xp.clip(xp.max(ds, axis=0), d5, d1)
780
779
  rerr = aerr - xp.real(work.Sn)
781
780
  else:
782
781
  # Note: explicit computation of log10 of each of these is unnecessary.
@@ -786,8 +785,8 @@ def _estimate_error(work, xp):
786
785
  d4 = work.d4
787
786
  d5 = e1 * xp.abs(work.Sn)
788
787
  temp = xp.where(d1 > 0, d1**(xp.log(d1)/xp.log(d2)), 0)
789
- ds = xp.stack([temp, d1**2, d3, d4, d5])
790
- aerr = xp.max(ds, axis=0)
788
+ ds = xp.stack([temp, d1**2, d3, d4])
789
+ aerr = xp.clip(xp.max(ds, axis=0), d5, d1)
791
790
  rerr = aerr/xp.abs(work.Sn)
792
791
 
793
792
  return rerr, aerr
@@ -804,7 +803,7 @@ def _transform_integrals(a, b, xp):
804
803
  a[ab_same], b[ab_same] = 1, 1
805
804
 
806
805
  # `a, b` may have complex dtype but have zero imaginary part
807
- negative = xp_real(b) < xp_real(a)
806
+ negative = xp.real(b) < xp.real(a)
808
807
  a[negative], b[negative] = b[negative], a[negative]
809
808
 
810
809
  abinf = xp.isinf(a) & xp.isinf(b)
@@ -825,14 +824,13 @@ def _tanhsinh_iv(f, a, b, log, maxfun, maxlevel, minlevel,
825
824
  # Input validation and standardization
826
825
 
827
826
  xp = array_namespace(a, b)
827
+ a, b = xp_promote(a, b, broadcast=True, force_floating=True, xp=xp)
828
828
 
829
829
  message = '`f` must be callable.'
830
830
  if not callable(f):
831
831
  raise ValueError(message)
832
832
 
833
833
  message = 'All elements of `a` and `b` must be real numbers.'
834
- a, b = xp.asarray(a), xp.asarray(b)
835
- a, b = xp.broadcast_arrays(a, b)
836
834
  if (xp.isdtype(a.dtype, 'complex floating')
837
835
  or xp.isdtype(b.dtype, 'complex floating')):
838
836
  raise ValueError(message)
@@ -901,16 +899,15 @@ def _tanhsinh_iv(f, a, b, log, maxfun, maxlevel, minlevel,
901
899
  def _nsum_iv(f, a, b, step, args, log, maxterms, tolerances):
902
900
  # Input validation and standardization
903
901
 
904
- 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)
905
904
 
906
905
  message = '`f` must be callable.'
907
906
  if not callable(f):
908
907
  raise ValueError(message)
909
908
 
910
909
  message = 'All elements of `a`, `b`, and `step` must be real numbers.'
911
- a, b, step = xp.broadcast_arrays(xp.asarray(a), xp.asarray(b), xp.asarray(step))
912
- dtype = xp.result_type(a.dtype, b.dtype, step.dtype)
913
- if not xp.isdtype(dtype, 'numeric') or xp.isdtype(dtype, 'complex floating'):
910
+ if not xp.isdtype(a.dtype, ('integral', 'real floating')):
914
911
  raise ValueError(message)
915
912
 
916
913
  valid_b = b >= a # NaNs will be False
@@ -1183,6 +1180,7 @@ def nsum(f, a, b, *, step=1, args=(), log=False, maxterms=int(2**20), tolerances
1183
1180
 
1184
1181
  # Branch for direct sum evaluation / integral approximation / invalid input
1185
1182
  i0 = ~valid_abstep # invalid
1183
+ i0b = b < a # zero
1186
1184
  i1 = (nterms + 1 <= maxterms) & ~i0 # direct sum evaluation
1187
1185
  i2 = xp.isfinite(a) & ~i1 & ~i0 # infinite sum to the right
1188
1186
  i3 = xp.isfinite(b) & ~i2 & ~i1 & ~i0 # infinite sum to the left
@@ -1192,6 +1190,9 @@ def nsum(f, a, b, *, step=1, args=(), log=False, maxterms=int(2**20), tolerances
1192
1190
  S[i0], E[i0] = xp.nan, xp.nan
1193
1191
  status[i0] = -1
1194
1192
 
1193
+ S[i0b], E[i0b] = zero, zero
1194
+ status[i0b] = 0
1195
+
1195
1196
  if xp.any(i1):
1196
1197
  args_direct = [arg[i1] for arg in args]
1197
1198
  tmp = _direct(f, a[i1], b[i1], step[i1], args_direct, constants, xp)
@@ -1294,7 +1295,7 @@ def _direct(f, a, b, step, args, constants, xp, inclusive=True):
1294
1295
  nfev = max_steps - i_nan.sum(axis=-1)
1295
1296
  S = special.logsumexp(fs, axis=-1) if log else xp.sum(fs, axis=-1)
1296
1297
  # Rough, non-conservative error estimate. See gh-19667 for improvement ideas.
1297
- 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)
1298
1299
  return S, E, nfev
1299
1300
 
1300
1301
 
@@ -1310,7 +1311,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1310
1311
  tol = special.logsumexp(xp.stack((tol, rtol + lb.integral)), axis=0)
1311
1312
  else:
1312
1313
  tol = tol + rtol*lb.integral
1313
- 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
1314
1315
  tol[i_skip] = xp.nan
1315
1316
  status = lb.status
1316
1317
 
@@ -1331,7 +1332,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1331
1332
  fksp1 = f(ks + step2, *args2) # check that the function is decreasing
1332
1333
  fk_insufficient = (fks > tol[:, xp.newaxis]) | (fksp1 > fks)
1333
1334
  n_fk_insufficient = xp.sum(fk_insufficient, axis=-1)
1334
- 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)
1335
1336
  n_steps = n_steps[nt]
1336
1337
 
1337
1338
  # If `maxterms` is insufficient (i.e. either the magnitude of the last term of the
@@ -1374,7 +1375,7 @@ def _integral_bound(f, a, b, step, args, constants, xp):
1374
1375
  S_terms = (left, right.integral - log_step, fk - log2, fb - log2)
1375
1376
  S = special.logsumexp(xp.stack(S_terms), axis=0)
1376
1377
  E_terms = (left_error, right.error - log_step, fk-log2, fb-log2+xp.pi*1j)
1377
- E = xp_real(special.logsumexp(xp.stack(E_terms), axis=0))
1378
+ E = xp.real(special.logsumexp(xp.stack(E_terms), axis=0))
1378
1379
  else:
1379
1380
  S = left + right.integral/step + fk/2 + fb/2
1380
1381
  E = left_error + right.error/step + fk/2 - fb/2
Binary file
@@ -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