scipy 1.15.3__cp313-cp313-macosx_12_0_arm64.whl → 1.16.0rc2__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 (629) 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 +263 -157
  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/cython_blas.cpython-313-darwin.so +0 -0
  220. scipy/linalg/cython_lapack.cpython-313-darwin.so +0 -0
  221. scipy/linalg/lapack.py +22 -2
  222. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  223. scipy/linalg/tests/test_basic.py +31 -16
  224. scipy/linalg/tests/test_batch.py +588 -0
  225. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  226. scipy/linalg/tests/test_decomp.py +40 -3
  227. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  228. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  229. scipy/linalg/tests/test_lapack.py +115 -7
  230. scipy/linalg/tests/test_matfuncs.py +157 -102
  231. scipy/linalg/tests/test_procrustes.py +0 -7
  232. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  233. scipy/linalg/tests/test_special_matrices.py +1 -5
  234. scipy/ndimage/__init__.py +1 -0
  235. scipy/ndimage/_cytest.cpython-313-darwin.so +0 -0
  236. scipy/ndimage/_delegators.py +8 -2
  237. scipy/ndimage/_filters.py +453 -5
  238. scipy/ndimage/_interpolation.py +36 -6
  239. scipy/ndimage/_measurements.py +4 -2
  240. scipy/ndimage/_morphology.py +5 -0
  241. scipy/ndimage/_nd_image.cpython-313-darwin.so +0 -0
  242. scipy/ndimage/_ni_docstrings.py +5 -1
  243. scipy/ndimage/_ni_label.cpython-313-darwin.so +0 -0
  244. scipy/ndimage/_ni_support.py +1 -5
  245. scipy/ndimage/_rank_filter_1d.cpython-313-darwin.so +0 -0
  246. scipy/ndimage/_support_alternative_backends.py +18 -6
  247. scipy/ndimage/tests/test_filters.py +370 -259
  248. scipy/ndimage/tests/test_fourier.py +7 -9
  249. scipy/ndimage/tests/test_interpolation.py +68 -61
  250. scipy/ndimage/tests/test_measurements.py +18 -35
  251. scipy/ndimage/tests/test_morphology.py +143 -131
  252. scipy/ndimage/tests/test_splines.py +1 -3
  253. scipy/odr/__odrpack.cpython-313-darwin.so +0 -0
  254. scipy/optimize/_basinhopping.py +13 -7
  255. scipy/optimize/_bglu_dense.cpython-313-darwin.so +0 -0
  256. scipy/optimize/_bracket.py +17 -24
  257. scipy/optimize/_chandrupatla.py +9 -10
  258. scipy/optimize/_cobyla_py.py +104 -123
  259. scipy/optimize/_constraints.py +14 -10
  260. scipy/optimize/_differentiable_functions.py +371 -230
  261. scipy/optimize/_differentialevolution.py +4 -3
  262. scipy/optimize/_direct.cpython-313-darwin.so +0 -0
  263. scipy/optimize/_dual_annealing.py +1 -1
  264. scipy/optimize/_elementwise.py +1 -4
  265. scipy/optimize/_group_columns.cpython-313-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb.cpython-313-darwin.so +0 -0
  267. scipy/optimize/_lbfgsb_py.py +57 -16
  268. scipy/optimize/_linprog_doc.py +2 -2
  269. scipy/optimize/_linprog_highs.py +2 -2
  270. scipy/optimize/_linprog_ip.py +25 -10
  271. scipy/optimize/_linprog_util.py +14 -16
  272. scipy/optimize/_lsap.cpython-313-darwin.so +0 -0
  273. scipy/optimize/_lsq/common.py +3 -3
  274. scipy/optimize/_lsq/dogbox.py +16 -2
  275. scipy/optimize/_lsq/givens_elimination.cpython-313-darwin.so +0 -0
  276. scipy/optimize/_lsq/least_squares.py +198 -126
  277. scipy/optimize/_lsq/lsq_linear.py +6 -6
  278. scipy/optimize/_lsq/trf.py +35 -8
  279. scipy/optimize/_milp.py +3 -1
  280. scipy/optimize/_minimize.py +105 -36
  281. scipy/optimize/_minpack.cpython-313-darwin.so +0 -0
  282. scipy/optimize/_minpack_py.py +21 -14
  283. scipy/optimize/_moduleTNC.cpython-313-darwin.so +0 -0
  284. scipy/optimize/_nnls.py +20 -21
  285. scipy/optimize/_nonlin.py +34 -3
  286. scipy/optimize/_numdiff.py +288 -110
  287. scipy/optimize/_optimize.py +86 -48
  288. scipy/optimize/_pava_pybind.cpython-313-darwin.so +0 -0
  289. scipy/optimize/_remove_redundancy.py +5 -5
  290. scipy/optimize/_root_scalar.py +1 -1
  291. scipy/optimize/_shgo.py +6 -0
  292. scipy/optimize/_shgo_lib/_complex.py +1 -1
  293. scipy/optimize/_slsqp_py.py +216 -124
  294. scipy/optimize/_slsqplib.cpython-313-darwin.so +0 -0
  295. scipy/optimize/_spectral.py +1 -1
  296. scipy/optimize/_tnc.py +8 -1
  297. scipy/optimize/_trlib/_trlib.cpython-313-darwin.so +0 -0
  298. scipy/optimize/_trustregion.py +20 -6
  299. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  300. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  301. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  302. scipy/optimize/_trustregion_constr/projections.py +12 -8
  303. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  304. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  305. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  306. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  307. scipy/optimize/_trustregion_exact.py +0 -1
  308. scipy/optimize/_zeros.cpython-313-darwin.so +0 -0
  309. scipy/optimize/_zeros_py.py +97 -17
  310. scipy/optimize/cython_optimize/_zeros.cpython-313-darwin.so +0 -0
  311. scipy/optimize/slsqp.py +0 -1
  312. scipy/optimize/tests/test__basinhopping.py +1 -1
  313. scipy/optimize/tests/test__differential_evolution.py +4 -4
  314. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  315. scipy/optimize/tests/test__numdiff.py +66 -22
  316. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  317. scipy/optimize/tests/test__shgo.py +9 -1
  318. scipy/optimize/tests/test_bracket.py +36 -46
  319. scipy/optimize/tests/test_chandrupatla.py +133 -135
  320. scipy/optimize/tests/test_cobyla.py +74 -45
  321. scipy/optimize/tests/test_constraints.py +1 -1
  322. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  323. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  324. scipy/optimize/tests/test_least_squares.py +125 -13
  325. scipy/optimize/tests/test_linear_assignment.py +3 -3
  326. scipy/optimize/tests/test_linprog.py +3 -3
  327. scipy/optimize/tests/test_lsq_linear.py +6 -6
  328. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  329. scipy/optimize/tests/test_minpack.py +4 -4
  330. scipy/optimize/tests/test_nnls.py +43 -3
  331. scipy/optimize/tests/test_nonlin.py +36 -0
  332. scipy/optimize/tests/test_optimize.py +95 -17
  333. scipy/optimize/tests/test_slsqp.py +36 -4
  334. scipy/optimize/tests/test_zeros.py +34 -1
  335. scipy/signal/__init__.py +12 -23
  336. scipy/signal/_delegators.py +568 -0
  337. scipy/signal/_filter_design.py +459 -241
  338. scipy/signal/_fir_filter_design.py +262 -90
  339. scipy/signal/_lti_conversion.py +3 -2
  340. scipy/signal/_ltisys.py +118 -91
  341. scipy/signal/_max_len_seq_inner.cpython-313-darwin.so +0 -0
  342. scipy/signal/_peak_finding_utils.cpython-313-darwin.so +0 -0
  343. scipy/signal/_polyutils.py +172 -0
  344. scipy/signal/_short_time_fft.py +519 -70
  345. scipy/signal/_signal_api.py +30 -0
  346. scipy/signal/_signaltools.py +719 -399
  347. scipy/signal/_sigtools.cpython-313-darwin.so +0 -0
  348. scipy/signal/_sosfilt.cpython-313-darwin.so +0 -0
  349. scipy/signal/_spectral_py.py +230 -50
  350. scipy/signal/_spline.cpython-313-darwin.so +0 -0
  351. scipy/signal/_spline_filters.py +108 -68
  352. scipy/signal/_support_alternative_backends.py +73 -0
  353. scipy/signal/_upfirdn.py +4 -1
  354. scipy/signal/_upfirdn_apply.cpython-313-darwin.so +0 -0
  355. scipy/signal/_waveforms.py +2 -11
  356. scipy/signal/_wavelets.py +1 -1
  357. scipy/signal/fir_filter_design.py +1 -0
  358. scipy/signal/spline.py +4 -11
  359. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  360. scipy/signal/tests/test_bsplines.py +114 -79
  361. scipy/signal/tests/test_cont2discrete.py +9 -2
  362. scipy/signal/tests/test_filter_design.py +721 -481
  363. scipy/signal/tests/test_fir_filter_design.py +332 -140
  364. scipy/signal/tests/test_savitzky_golay.py +4 -3
  365. scipy/signal/tests/test_short_time_fft.py +221 -3
  366. scipy/signal/tests/test_signaltools.py +2144 -1348
  367. scipy/signal/tests/test_spectral.py +50 -6
  368. scipy/signal/tests/test_splines.py +161 -96
  369. scipy/signal/tests/test_upfirdn.py +84 -50
  370. scipy/signal/tests/test_waveforms.py +20 -0
  371. scipy/signal/tests/test_windows.py +607 -466
  372. scipy/signal/windows/_windows.py +287 -148
  373. scipy/sparse/__init__.py +23 -4
  374. scipy/sparse/_base.py +270 -108
  375. scipy/sparse/_bsr.py +7 -4
  376. scipy/sparse/_compressed.py +59 -231
  377. scipy/sparse/_construct.py +90 -38
  378. scipy/sparse/_coo.py +115 -181
  379. scipy/sparse/_csc.py +4 -4
  380. scipy/sparse/_csparsetools.cpython-313-darwin.so +0 -0
  381. scipy/sparse/_csr.py +2 -2
  382. scipy/sparse/_data.py +48 -48
  383. scipy/sparse/_dia.py +105 -18
  384. scipy/sparse/_dok.py +0 -23
  385. scipy/sparse/_index.py +4 -4
  386. scipy/sparse/_matrix.py +23 -0
  387. scipy/sparse/_sparsetools.cpython-313-darwin.so +0 -0
  388. scipy/sparse/_sputils.py +37 -22
  389. scipy/sparse/base.py +0 -9
  390. scipy/sparse/bsr.py +0 -14
  391. scipy/sparse/compressed.py +0 -23
  392. scipy/sparse/construct.py +0 -6
  393. scipy/sparse/coo.py +0 -14
  394. scipy/sparse/csc.py +0 -3
  395. scipy/sparse/csgraph/_flow.cpython-313-darwin.so +0 -0
  396. scipy/sparse/csgraph/_matching.cpython-313-darwin.so +0 -0
  397. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-darwin.so +0 -0
  398. scipy/sparse/csgraph/_reordering.cpython-313-darwin.so +0 -0
  399. scipy/sparse/csgraph/_shortest_path.cpython-313-darwin.so +0 -0
  400. scipy/sparse/csgraph/_tools.cpython-313-darwin.so +0 -0
  401. scipy/sparse/csgraph/_traversal.cpython-313-darwin.so +0 -0
  402. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  403. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  404. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  405. scipy/sparse/csr.py +0 -5
  406. scipy/sparse/data.py +1 -6
  407. scipy/sparse/dia.py +0 -7
  408. scipy/sparse/dok.py +0 -10
  409. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-darwin.so +0 -0
  410. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  411. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  412. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-darwin.so +0 -0
  413. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  414. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  415. scipy/sparse/linalg/_interface.py +17 -18
  416. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  417. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  418. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  419. scipy/sparse/linalg/_isolve/minres.py +5 -5
  420. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  421. scipy/sparse/linalg/_isolve/utils.py +2 -8
  422. scipy/sparse/linalg/_matfuncs.py +1 -1
  423. scipy/sparse/linalg/_norm.py +1 -1
  424. scipy/sparse/linalg/_propack/_cpropack.cpython-313-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_dpropack.cpython-313-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_spropack.cpython-313-darwin.so +0 -0
  427. scipy/sparse/linalg/_propack/_zpropack.cpython-313-darwin.so +0 -0
  428. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  429. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  430. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  431. scipy/sparse/tests/test_base.py +214 -42
  432. scipy/sparse/tests/test_common1d.py +7 -7
  433. scipy/sparse/tests/test_construct.py +1 -1
  434. scipy/sparse/tests/test_coo.py +272 -4
  435. scipy/sparse/tests/test_sparsetools.py +5 -0
  436. scipy/sparse/tests/test_sputils.py +36 -7
  437. scipy/spatial/_ckdtree.cpython-313-darwin.so +0 -0
  438. scipy/spatial/_distance_pybind.cpython-313-darwin.so +0 -0
  439. scipy/spatial/_distance_wrap.cpython-313-darwin.so +0 -0
  440. scipy/spatial/_hausdorff.cpython-313-darwin.so +0 -0
  441. scipy/spatial/_qhull.cpython-313-darwin.so +0 -0
  442. scipy/spatial/_voronoi.cpython-313-darwin.so +0 -0
  443. scipy/spatial/distance.py +49 -42
  444. scipy/spatial/tests/test_distance.py +15 -1
  445. scipy/spatial/tests/test_kdtree.py +1 -0
  446. scipy/spatial/tests/test_qhull.py +7 -2
  447. scipy/spatial/transform/__init__.py +5 -3
  448. scipy/spatial/transform/_rigid_transform.cpython-313-darwin.so +0 -0
  449. scipy/spatial/transform/_rotation.cpython-313-darwin.so +0 -0
  450. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  451. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  452. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  453. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  454. scipy/special/__init__.py +1 -47
  455. scipy/special/_add_newdocs.py +34 -772
  456. scipy/special/_basic.py +22 -25
  457. scipy/special/_comb.cpython-313-darwin.so +0 -0
  458. scipy/special/_ellip_harm_2.cpython-313-darwin.so +0 -0
  459. scipy/special/_gufuncs.cpython-313-darwin.so +0 -0
  460. scipy/special/_logsumexp.py +67 -58
  461. scipy/special/_orthogonal.pyi +1 -1
  462. scipy/special/_specfun.cpython-313-darwin.so +0 -0
  463. scipy/special/_special_ufuncs.cpython-313-darwin.so +0 -0
  464. scipy/special/_spherical_bessel.py +4 -4
  465. scipy/special/_support_alternative_backends.py +212 -119
  466. scipy/special/_test_internal.cpython-313-darwin.so +0 -0
  467. scipy/special/_testutils.py +4 -4
  468. scipy/special/_ufuncs.cpython-313-darwin.so +0 -0
  469. scipy/special/_ufuncs.pyi +1 -0
  470. scipy/special/_ufuncs.pyx +215 -1400
  471. scipy/special/_ufuncs_cxx.cpython-313-darwin.so +0 -0
  472. scipy/special/_ufuncs_cxx.pxd +2 -15
  473. scipy/special/_ufuncs_cxx.pyx +5 -44
  474. scipy/special/_ufuncs_cxx_defs.h +2 -16
  475. scipy/special/_ufuncs_defs.h +0 -8
  476. scipy/special/cython_special.cpython-313-darwin.so +0 -0
  477. scipy/special/cython_special.pxd +1 -1
  478. scipy/special/tests/_cython_examples/meson.build +10 -1
  479. scipy/special/tests/test_basic.py +153 -20
  480. scipy/special/tests/test_boost_ufuncs.py +3 -0
  481. scipy/special/tests/test_cdflib.py +35 -11
  482. scipy/special/tests/test_gammainc.py +16 -0
  483. scipy/special/tests/test_hyp2f1.py +2 -2
  484. scipy/special/tests/test_log1mexp.py +85 -0
  485. scipy/special/tests/test_logsumexp.py +206 -64
  486. scipy/special/tests/test_mpmath.py +1 -0
  487. scipy/special/tests/test_nan_inputs.py +1 -1
  488. scipy/special/tests/test_orthogonal.py +17 -18
  489. scipy/special/tests/test_sf_error.py +3 -2
  490. scipy/special/tests/test_sph_harm.py +6 -7
  491. scipy/special/tests/test_support_alternative_backends.py +211 -76
  492. scipy/stats/__init__.py +4 -1
  493. scipy/stats/_ansari_swilk_statistics.cpython-313-darwin.so +0 -0
  494. scipy/stats/_axis_nan_policy.py +5 -12
  495. scipy/stats/_biasedurn.cpython-313-darwin.so +0 -0
  496. scipy/stats/_continued_fraction.py +387 -0
  497. scipy/stats/_continuous_distns.py +277 -310
  498. scipy/stats/_correlation.py +1 -1
  499. scipy/stats/_covariance.py +6 -3
  500. scipy/stats/_discrete_distns.py +39 -32
  501. scipy/stats/_distn_infrastructure.py +39 -12
  502. scipy/stats/_distribution_infrastructure.py +900 -238
  503. scipy/stats/_entropy.py +9 -10
  504. scipy/{_lib → stats}/_finite_differences.py +1 -1
  505. scipy/stats/_hypotests.py +83 -50
  506. scipy/stats/_kde.py +53 -49
  507. scipy/stats/_ksstats.py +1 -1
  508. scipy/stats/_levy_stable/__init__.py +7 -15
  509. scipy/stats/_levy_stable/levyst.cpython-313-darwin.so +0 -0
  510. scipy/stats/_morestats.py +118 -73
  511. scipy/stats/_mstats_basic.py +13 -17
  512. scipy/stats/_mstats_extras.py +8 -8
  513. scipy/stats/_multivariate.py +89 -113
  514. scipy/stats/_new_distributions.py +97 -20
  515. scipy/stats/_page_trend_test.py +12 -5
  516. scipy/stats/_probability_distribution.py +265 -43
  517. scipy/stats/_qmc.py +14 -9
  518. scipy/stats/_qmc_cy.cpython-313-darwin.so +0 -0
  519. scipy/stats/_qmvnt.py +16 -95
  520. scipy/stats/_qmvnt_cy.cpython-313-darwin.so +0 -0
  521. scipy/stats/_quantile.py +335 -0
  522. scipy/stats/_rcont/rcont.cpython-313-darwin.so +0 -0
  523. scipy/stats/_resampling.py +4 -29
  524. scipy/stats/_sampling.py +1 -1
  525. scipy/stats/_sobol.cpython-313-darwin.so +0 -0
  526. scipy/stats/_stats.cpython-313-darwin.so +0 -0
  527. scipy/stats/_stats_mstats_common.py +21 -2
  528. scipy/stats/_stats_py.py +550 -476
  529. scipy/stats/_stats_pythran.cpython-313-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.cpython-313-darwin.so +0 -0
  531. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  532. scipy/stats/_variation.py +6 -8
  533. scipy/stats/_wilcoxon.py +13 -7
  534. scipy/stats/tests/common_tests.py +6 -4
  535. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  536. scipy/stats/tests/test_continued_fraction.py +173 -0
  537. scipy/stats/tests/test_continuous.py +379 -60
  538. scipy/stats/tests/test_continuous_basic.py +18 -12
  539. scipy/stats/tests/test_discrete_basic.py +14 -8
  540. scipy/stats/tests/test_discrete_distns.py +16 -16
  541. scipy/stats/tests/test_distributions.py +95 -75
  542. scipy/stats/tests/test_entropy.py +40 -48
  543. scipy/stats/tests/test_fit.py +4 -3
  544. scipy/stats/tests/test_hypotests.py +153 -24
  545. scipy/stats/tests/test_kdeoth.py +109 -41
  546. scipy/stats/tests/test_marray.py +289 -0
  547. scipy/stats/tests/test_morestats.py +79 -47
  548. scipy/stats/tests/test_mstats_basic.py +3 -3
  549. scipy/stats/tests/test_multivariate.py +434 -83
  550. scipy/stats/tests/test_qmc.py +13 -10
  551. scipy/stats/tests/test_quantile.py +199 -0
  552. scipy/stats/tests/test_rank.py +119 -112
  553. scipy/stats/tests/test_resampling.py +47 -56
  554. scipy/stats/tests/test_sampling.py +9 -4
  555. scipy/stats/tests/test_stats.py +799 -939
  556. scipy/stats/tests/test_variation.py +8 -6
  557. scipy/version.py +2 -2
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  560. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +561 -568
  561. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  562. scipy/_lib/array_api_extra/_funcs.py +0 -484
  563. scipy/_lib/array_api_extra/_typing.py +0 -8
  564. scipy/interpolate/_bspl.cpython-313-darwin.so +0 -0
  565. scipy/optimize/_cobyla.cpython-313-darwin.so +0 -0
  566. scipy/optimize/_cython_nnls.cpython-313-darwin.so +0 -0
  567. scipy/optimize/_slsqp.cpython-313-darwin.so +0 -0
  568. scipy/spatial/qhull_src/COPYING.txt +0 -38
  569. scipy/special/libsf_error_state.dylib +0 -0
  570. scipy/special/tests/test_log_softmax.py +0 -109
  571. scipy/special/tests/test_xsf_cuda.py +0 -114
  572. scipy/special/xsf/binom.h +0 -89
  573. scipy/special/xsf/cdflib.h +0 -100
  574. scipy/special/xsf/cephes/airy.h +0 -307
  575. scipy/special/xsf/cephes/besselpoly.h +0 -51
  576. scipy/special/xsf/cephes/beta.h +0 -257
  577. scipy/special/xsf/cephes/cbrt.h +0 -131
  578. scipy/special/xsf/cephes/chbevl.h +0 -85
  579. scipy/special/xsf/cephes/chdtr.h +0 -193
  580. scipy/special/xsf/cephes/const.h +0 -87
  581. scipy/special/xsf/cephes/ellie.h +0 -293
  582. scipy/special/xsf/cephes/ellik.h +0 -251
  583. scipy/special/xsf/cephes/ellpe.h +0 -107
  584. scipy/special/xsf/cephes/ellpk.h +0 -117
  585. scipy/special/xsf/cephes/expn.h +0 -260
  586. scipy/special/xsf/cephes/gamma.h +0 -398
  587. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  588. scipy/special/xsf/cephes/hyperg.h +0 -361
  589. scipy/special/xsf/cephes/i0.h +0 -149
  590. scipy/special/xsf/cephes/i1.h +0 -158
  591. scipy/special/xsf/cephes/igam.h +0 -421
  592. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  593. scipy/special/xsf/cephes/igami.h +0 -313
  594. scipy/special/xsf/cephes/j0.h +0 -225
  595. scipy/special/xsf/cephes/j1.h +0 -198
  596. scipy/special/xsf/cephes/jv.h +0 -715
  597. scipy/special/xsf/cephes/k0.h +0 -164
  598. scipy/special/xsf/cephes/k1.h +0 -163
  599. scipy/special/xsf/cephes/kn.h +0 -243
  600. scipy/special/xsf/cephes/lanczos.h +0 -112
  601. scipy/special/xsf/cephes/ndtr.h +0 -275
  602. scipy/special/xsf/cephes/poch.h +0 -85
  603. scipy/special/xsf/cephes/polevl.h +0 -167
  604. scipy/special/xsf/cephes/psi.h +0 -194
  605. scipy/special/xsf/cephes/rgamma.h +0 -111
  606. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  607. scipy/special/xsf/cephes/shichi.h +0 -248
  608. scipy/special/xsf/cephes/sici.h +0 -224
  609. scipy/special/xsf/cephes/sindg.h +0 -221
  610. scipy/special/xsf/cephes/tandg.h +0 -139
  611. scipy/special/xsf/cephes/trig.h +0 -58
  612. scipy/special/xsf/cephes/unity.h +0 -186
  613. scipy/special/xsf/cephes/zeta.h +0 -172
  614. scipy/special/xsf/config.h +0 -304
  615. scipy/special/xsf/digamma.h +0 -205
  616. scipy/special/xsf/error.h +0 -57
  617. scipy/special/xsf/evalpoly.h +0 -47
  618. scipy/special/xsf/expint.h +0 -266
  619. scipy/special/xsf/hyp2f1.h +0 -694
  620. scipy/special/xsf/iv_ratio.h +0 -173
  621. scipy/special/xsf/lambertw.h +0 -150
  622. scipy/special/xsf/loggamma.h +0 -163
  623. scipy/special/xsf/sici.h +0 -200
  624. scipy/special/xsf/tools.h +0 -427
  625. scipy/special/xsf/trig.h +0 -164
  626. scipy/special/xsf/wright_bessel.h +0 -843
  627. scipy/special/xsf/zlog1.h +0 -35
  628. scipy/stats/_mvn.cpython-313-darwin.so +0 -0
  629. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -6,10 +6,8 @@ from scipy._lib._array_api import assert_almost_equal
6
6
 
7
7
  from scipy import ndimage
8
8
 
9
- from scipy.conftest import array_api_compatible
10
9
  skip_xp_backends = pytest.mark.skip_xp_backends
11
- pytestmark = [array_api_compatible, pytest.mark.usefixtures("skip_xp_backends"),
12
- skip_xp_backends(cpu_only=True, exceptions=['cupy', 'jax.numpy'],)]
10
+ pytestmark = [skip_xp_backends(cpu_only=True, exceptions=['cupy', 'jax.numpy'])]
13
11
 
14
12
 
15
13
  def get_spline_knot_values(order):
Binary file
@@ -84,7 +84,7 @@ class BasinHoppingRunner:
84
84
  self.energy = minres.fun
85
85
  self.incumbent_minres = minres # best minimize result found so far
86
86
  if self.disp:
87
- print("basinhopping step %d: f %g" % (self.nstep, self.energy))
87
+ print(f"basinhopping step {self.nstep}: f {self.energy:g}")
88
88
 
89
89
  # initialize storage class
90
90
  self.storage = Storage(minres)
@@ -171,8 +171,10 @@ class BasinHoppingRunner:
171
171
  if self.disp:
172
172
  self.print_report(minres.fun, accept)
173
173
  if new_global_min:
174
- print("found new global minimum on step %d with function"
175
- " value %g" % (self.nstep, self.energy))
174
+ print(
175
+ f"found new global minimum on step {self.nstep} with "
176
+ f"function value {self.energy:g}"
177
+ )
176
178
 
177
179
  # save some variables as BasinHoppingRunner attributes
178
180
  self.xtrial = minres.x
@@ -184,9 +186,11 @@ class BasinHoppingRunner:
184
186
  def print_report(self, energy_trial, accept):
185
187
  """print a status update"""
186
188
  minres = self.storage.get_lowest()
187
- print("basinhopping step %d: f %g trial_f %g accepted %d "
188
- " lowest_f %g" % (self.nstep, self.energy, energy_trial,
189
- accept, minres.fun))
189
+ print(
190
+ f"basinhopping step {self.nstep}: f {self.energy:g} "
191
+ f"trial_f {energy_trial:g} accepted {accept} "
192
+ f"lowest_f {minres.fun:g}"
193
+ )
190
194
 
191
195
 
192
196
  class AdaptiveStepsize:
@@ -451,7 +455,9 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
451
455
  cause of the termination. The ``OptimizeResult`` object returned by the
452
456
  selected minimizer at the lowest minimum is also contained within this
453
457
  object and can be accessed through the ``lowest_optimization_result``
454
- attribute. See `OptimizeResult` for a description of other attributes.
458
+ attribute. ``lowest_optimization_result`` will only be updated if a
459
+ local minimization was successful.
460
+ See `OptimizeResult` for a description of other attributes.
455
461
 
456
462
  See Also
457
463
  --------
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
  import scipy._lib._elementwise_iterative_method as eim
3
3
  from scipy._lib._util import _RichResult
4
- from scipy._lib._array_api import array_namespace, xp_ravel, xp_default_dtype
4
+ from scipy._lib._array_api import array_namespace, xp_ravel, xp_promote
5
5
 
6
6
  _ELIMITS = -1 # used in _bracket_root
7
7
  _ESTOPONESIDE = 2 # used in _bracket_root
@@ -14,13 +14,7 @@ def _bracket_root_iv(func, xl0, xr0, xmin, xmax, factor, args, maxiter):
14
14
  if not np.iterable(args):
15
15
  args = (args,)
16
16
 
17
- xp = array_namespace(xl0)
18
- xl0 = xp.asarray(xl0)[()]
19
- if (not xp.isdtype(xl0.dtype, "numeric")
20
- or xp.isdtype(xl0.dtype, "complex floating")):
21
- raise ValueError('`xl0` must be numeric and real.')
22
- if not xp.isdtype(xl0.dtype, "real floating"):
23
- xl0 = xp.asarray(xl0, dtype=xp_default_dtype(xp))
17
+ xp = array_namespace(xl0, xr0, xmin, xmax, factor, *args)
24
18
 
25
19
  # If xr0 is not supplied, fill with a dummy value for the sake of
26
20
  # broadcasting. We need to wait until xmax has been validated to
@@ -33,8 +27,11 @@ def _bracket_root_iv(func, xl0, xr0, xmin, xmax, factor, args, maxiter):
33
27
  xmin = -xp.inf if xmin is None else xmin
34
28
  xmax = xp.inf if xmax is None else xmax
35
29
  factor = 2. if factor is None else factor
36
- xl0, xr0, xmin, xmax, factor = xp.broadcast_arrays(
37
- xl0, xp.asarray(xr0), xp.asarray(xmin), xp.asarray(xmax), xp.asarray(factor))
30
+ xl0, xr0, xmin, xmax, factor = xp_promote(
31
+ xl0, xr0, xmin, xmax, factor, broadcast=True, force_floating=True, xp=xp)
32
+
33
+ if not xp.isdtype(xl0.dtype, ('integral', 'real floating')):
34
+ raise ValueError('`xl0` must be numeric and real.')
38
35
 
39
36
  if (not xp.isdtype(xr0.dtype, "numeric")
40
37
  or xp.isdtype(xr0.dtype, "complex floating")):
@@ -57,7 +54,7 @@ def _bracket_root_iv(func, xl0, xr0, xmin, xmax, factor, args, maxiter):
57
54
  # Calculate the default value of xr0 if a value has not been supplied.
58
55
  # Be careful to ensure xr0 is not larger than xmax.
59
56
  if xr0_not_supplied:
60
- xr0 = xl0 + xp.minimum((xmax - xl0)/ 8, xp.asarray(1.0))
57
+ xr0 = xl0 + xp.minimum((xmax - xl0)/ 8, 1.0)
61
58
  xr0 = xp.astype(xr0, xl0.dtype, copy=False)
62
59
 
63
60
  maxiter = xp.asarray(maxiter)
@@ -425,13 +422,7 @@ def _bracket_minimum_iv(func, xm0, xl0, xr0, xmin, xmax, factor, args, maxiter):
425
422
  if not np.iterable(args):
426
423
  args = (args,)
427
424
 
428
- xp = array_namespace(xm0)
429
- xm0 = xp.asarray(xm0)[()]
430
- if (not xp.isdtype(xm0.dtype, "numeric")
431
- or xp.isdtype(xm0.dtype, "complex floating")):
432
- raise ValueError('`xm0` must be numeric and real.')
433
- if not xp.isdtype(xm0.dtype, "real floating"):
434
- xm0 = xp.asarray(xm0, dtype=xp_default_dtype(xp))
425
+ xp = array_namespace(xm0, xl0, xr0, xmin, xmax, factor, *args)
435
426
 
436
427
  xmin = -xp.inf if xmin is None else xmin
437
428
  xmax = xp.inf if xmax is None else xmax
@@ -450,10 +441,12 @@ def _bracket_minimum_iv(func, xm0, xl0, xr0, xmin, xmax, factor, args, maxiter):
450
441
  xr0_not_supplied = True
451
442
 
452
443
  factor = 2.0 if factor is None else factor
453
- xl0, xm0, xr0, xmin, xmax, factor = xp.broadcast_arrays(
454
- xp.asarray(xl0), xm0, xp.asarray(xr0), xp.asarray(xmin),
455
- xp.asarray(xmax), xp.asarray(factor)
456
- )
444
+
445
+ xm0, xl0, xr0, xmin, xmax, factor = xp_promote(
446
+ xm0, xl0, xr0, xmin, xmax, factor, broadcast=True, force_floating=True, xp=xp)
447
+
448
+ if not xp.isdtype(xm0.dtype, ('integral', 'real floating')):
449
+ raise ValueError('`xm0` must be numeric and real.')
457
450
 
458
451
  if (not xp.isdtype(xl0.dtype, "numeric")
459
452
  or xp.isdtype(xl0.dtype, "complex floating")):
@@ -481,10 +474,10 @@ def _bracket_minimum_iv(func, xm0, xl0, xr0, xmin, xmax, factor, args, maxiter):
481
474
  # by the user. We need to be careful to ensure xl0 and xr0 are not outside
482
475
  # of (xmin, xmax).
483
476
  if xl0_not_supplied:
484
- xl0 = xm0 - xp.minimum((xm0 - xmin)/16, xp.asarray(0.5))
477
+ xl0 = xm0 - xp.minimum((xm0 - xmin)/16, 0.5)
485
478
  xl0 = xp.astype(xl0, xm0.dtype, copy=False)
486
479
  if xr0_not_supplied:
487
- xr0 = xm0 + xp.minimum((xmax - xm0)/16, xp.asarray(0.5))
480
+ xr0 = xm0 + xp.minimum((xmax - xm0)/16, 0.5)
488
481
  xr0 = xp.astype(xr0, xm0.dtype, copy=False)
489
482
 
490
483
  maxiter = xp.asarray(maxiter)
@@ -2,7 +2,7 @@ import math
2
2
  import numpy as np
3
3
  import scipy._lib._elementwise_iterative_method as eim
4
4
  from scipy._lib._util import _RichResult
5
- from scipy._lib._array_api import xp_sign, xp_copy, xp_take_along_axis
5
+ from scipy._lib._array_api import xp_copy
6
6
 
7
7
  # TODO:
8
8
  # - (maybe?) don't use fancy indexing assignment
@@ -134,7 +134,7 @@ def _chandrupatla(func, a, b, *, args=(), xatol=None, xrtol=None,
134
134
  func, xs, fs, args, shape, dtype, xp = temp
135
135
  x1, x2 = xs
136
136
  f1, f2 = fs
137
- status = xp.full_like(x1, xp.asarray(eim._EINPROGRESS),
137
+ status = xp.full_like(x1, eim._EINPROGRESS,
138
138
  dtype=xp.int32) # in progress
139
139
  nit, nfev = 0, 2 # two function evaluations performed above
140
140
  finfo = xp.finfo(dtype)
@@ -187,7 +187,7 @@ def _chandrupatla(func, a, b, *, args=(), xatol=None, xrtol=None,
187
187
 
188
188
  # If the bracket is no longer valid, report failure (unless a function
189
189
  # tolerance is met, as detected above).
190
- i = (xp_sign(work.f1) == xp_sign(work.f2)) & ~stop
190
+ i = (xp.sign(work.f1) == xp.sign(work.f2)) & ~stop
191
191
  NaN = xp.asarray(xp.nan, dtype=work.xmin.dtype)
192
192
  work.xmin[i], work.fmin[i], work.status[i] = NaN, NaN, eim._ESIGNERR
193
193
  stop[i] = True
@@ -219,7 +219,7 @@ def _chandrupatla(func, a, b, *, args=(), xatol=None, xrtol=None,
219
219
  j = ((1 - xp.sqrt(1 - xi1)) < phi1) & (phi1 < xp.sqrt(xi1))
220
220
 
221
221
  f1j, f2j, f3j, alphaj = work.f1[j], work.f2[j], work.f3[j], alpha[j]
222
- t = xp.full_like(alpha, xp.asarray(0.5))
222
+ t = xp.full_like(alpha, 0.5)
223
223
  t[j] = (f1j / (f1j - f2j) * f3j / (f3j - f2j)
224
224
  - alphaj * f1j / (f3j - f1j) * f2j / (f2j - f3j))
225
225
 
@@ -401,8 +401,7 @@ def _chandrupatla_minimize(func, x1, x2, x3, *, args=(), xatol=None,
401
401
  x1, x2, x3 = xs
402
402
  f1, f2, f3 = fs
403
403
  phi = xp.asarray(0.5 + 0.5*5**0.5, dtype=dtype)[()] # golden ratio
404
- status = xp.full_like(x1, xp.asarray(eim._EINPROGRESS),
405
- dtype=xp.int32) # in progress
404
+ status = xp.full_like(x1, eim._EINPROGRESS, dtype=xp.int32) # in progress
406
405
  nit, nfev = 0, 3 # three function evaluations performed above
407
406
  fatol = xp.finfo(dtype).smallest_normal if fatol is None else fatol
408
407
  frtol = xp.finfo(dtype).smallest_normal if frtol is None else frtol
@@ -412,8 +411,8 @@ def _chandrupatla_minimize(func, x1, x2, x3, *, args=(), xatol=None,
412
411
  # Ensure that x1 < x2 < x3 initially.
413
412
  xs, fs = xp.stack((x1, x2, x3)), xp.stack((f1, f2, f3))
414
413
  i = xp.argsort(xs, axis=0)
415
- x1, x2, x3 = xp_take_along_axis(xs, i, axis=0) # data-apis/array-api#808
416
- f1, f2, f3 = xp_take_along_axis(fs, i, axis=0) # data-apis/array-api#808
414
+ x1, x2, x3 = xp.take_along_axis(xs, i, axis=0) # data-apis/array-api#808
415
+ f1, f2, f3 = xp.take_along_axis(fs, i, axis=0) # data-apis/array-api#808
417
416
  q0 = xp_copy(x3) # "At the start, q0 is set at x3..." ([1] after (7))
418
417
 
419
418
  work = _RichResult(x1=x1, f1=f1, x2=x2, f2=f2, x3=x3, f3=f3, phi=phi,
@@ -449,7 +448,7 @@ def _chandrupatla_minimize(func, x1, x2, x3, *, args=(), xatol=None,
449
448
  # tol away from x2."
450
449
  # See also QBASIC code after "Accept Ql adjust if close to X2".
451
450
  j = xp.abs(q1[i] - work.x2[i]) <= work.xtol[i]
452
- xi[j] = work.x2[i][j] + xp_sign(x32[i][j]) * work.xtol[i][j]
451
+ xi[j] = work.x2[i][j] + xp.sign(x32[i][j]) * work.xtol[i][j]
453
452
 
454
453
  # "If condition (7) is not satisfied, golden sectioning of the larger
455
454
  # interval is carried out to introduce the new point."
@@ -467,7 +466,7 @@ def _chandrupatla_minimize(func, x1, x2, x3, *, args=(), xatol=None,
467
466
  # point. In QBASIC code, see "IF SGN(X-X2) = SGN(X3-X2) THEN...".
468
467
  # There is an awful lot of data copying going on here; this would
469
468
  # probably benefit from code optimization or implementation in Pythran.
470
- i = xp_sign(x - work.x2) == xp_sign(work.x3 - work.x2)
469
+ i = xp.sign(x - work.x2) == xp.sign(work.x3 - work.x2)
471
470
  xi, x1i, x2i, x3i = x[i], work.x1[i], work.x2[i], work.x3[i],
472
471
  fi, f1i, f2i, f3i = f[i], work.f1[i], work.f2[i], work.f3[i]
473
472
  j = fi > f2i
@@ -10,39 +10,24 @@ Functions
10
10
 
11
11
  """
12
12
 
13
- import functools
14
- from threading import RLock
13
+ from inspect import signature
15
14
 
16
15
  import numpy as np
17
- from scipy.optimize import _cobyla as cobyla
18
16
  from ._optimize import (OptimizeResult, _check_unknown_options,
19
17
  _prepare_scalar_function)
20
- try:
21
- from itertools import izip
22
- except ImportError:
23
- izip = zip
18
+ from ._constraints import NonlinearConstraint
19
+
24
20
 
25
21
  __all__ = ['fmin_cobyla']
26
22
 
27
- # Workaround as _cobyla.minimize is not threadsafe
28
- # due to an unknown f2py bug and can segfault,
29
- # see gh-9658.
30
- _module_lock = RLock()
31
- def synchronized(func):
32
- @functools.wraps(func)
33
- def wrapper(*args, **kwargs):
34
- with _module_lock:
35
- return func(*args, **kwargs)
36
- return wrapper
37
-
38
- @synchronized
23
+
39
24
  def fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0,
40
25
  rhoend=1e-4, maxfun=1000, disp=None, catol=2e-4,
41
26
  *, callback=None):
42
27
  """
43
28
  Minimize a function using the Constrained Optimization By Linear
44
- Approximation (COBYLA) method. This method wraps a FORTRAN
45
- implementation of the algorithm.
29
+ Approximation (COBYLA) method. This method uses the pure-python implementation
30
+ of the algorithm from PRIMA.
46
31
 
47
32
  Parameters
48
33
  ----------
@@ -113,6 +98,11 @@ def fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0,
113
98
  how these issues are resolved, as well as how the points v_i are
114
99
  updated, refer to the source code or the references below.
115
100
 
101
+ .. versionchanged:: 1.16.0
102
+ The original Powell implementation was replaced by a pure
103
+ Python version from the PRIMA package, with bug fixes and
104
+ improvements being made.
105
+
116
106
 
117
107
  References
118
108
  ----------
@@ -127,6 +117,9 @@ def fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0,
127
117
  Powell M.J.D. (2007), "A view of algorithms for optimization without
128
118
  derivatives", Cambridge University Technical Report DAMTP 2007/NA03
129
119
 
120
+ Zhang Z. (2023), "PRIMA: Reference Implementation for Powell's Methods with
121
+ Modernization and Amelioration", https://www.libprima.net,
122
+ :doi:`10.5281/zenodo.8052654`
130
123
 
131
124
  Examples
132
125
  --------
@@ -169,7 +162,12 @@ def fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0,
169
162
  consargs = args
170
163
 
171
164
  # build constraints
172
- con = tuple({'type': 'ineq', 'fun': c, 'args': consargs} for c in cons)
165
+ nlcs = []
166
+ for con in cons:
167
+ # Use default argument, otherwise the last `con` is captured by all wrapped_con
168
+ def wrapped_con(x, confunc=con):
169
+ return confunc(x, *consargs)
170
+ nlcs.append(NonlinearConstraint(wrapped_con, 0, np.inf))
173
171
 
174
172
  # options
175
173
  opts = {'rhobeg': rhobeg,
@@ -179,21 +177,21 @@ def fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0,
179
177
  'catol': catol,
180
178
  'callback': callback}
181
179
 
182
- sol = _minimize_cobyla(func, x0, args, constraints=con,
180
+ sol = _minimize_cobyla(func, x0, args, constraints=nlcs,
183
181
  **opts)
184
182
  if disp and not sol['success']:
185
183
  print(f"COBYLA failed to find a solution: {sol.message}")
186
184
  return sol['x']
187
185
 
188
186
 
189
- @synchronized
190
187
  def _minimize_cobyla(fun, x0, args=(), constraints=(),
191
188
  rhobeg=1.0, tol=1e-4, maxiter=1000,
192
- disp=False, catol=2e-4, callback=None, bounds=None,
193
- **unknown_options):
189
+ disp=0, catol=None, f_target=-np.inf,
190
+ callback=None, bounds=None, **unknown_options):
194
191
  """
195
192
  Minimize a scalar function of one or more variables using the
196
193
  Constrained Optimization BY Linear Approximation (COBYLA) algorithm.
194
+ This method uses the pure-python implementation of the algorithm from PRIMA.
197
195
 
198
196
  Options
199
197
  -------
@@ -202,74 +200,44 @@ def _minimize_cobyla(fun, x0, args=(), constraints=(),
202
200
  tol : float
203
201
  Final accuracy in the optimization (not precisely guaranteed).
204
202
  This is a lower bound on the size of the trust region.
205
- disp : bool
206
- Set to True to print convergence messages. If False,
207
- `verbosity` is ignored as set to 0.
203
+ disp : int
204
+ Controls the frequency of output:
205
+ 0. (default) There will be no printing
206
+ 1. A message will be printed to the screen at the end of iteration, showing
207
+ the best vector of variables found and its objective function value
208
+ 2. in addition to 1, each new value of RHO is printed to the screen,
209
+ with the best vector of variables so far and its objective function
210
+ value.
211
+ 3. in addition to 2, each function evaluation with its variables will
212
+ be printed to the screen.
208
213
  maxiter : int
209
214
  Maximum number of function evaluations.
210
215
  catol : float
211
216
  Tolerance (absolute) for constraint violations
217
+ f_target : float
218
+ Stop if the objective function is less than `f_target`.
219
+
220
+ .. versionchanged:: 1.16.0
221
+ The original Powell implementation was replaced by a pure
222
+ Python version from the PRIMA package, with bug fixes and
223
+ improvements being made.
212
224
 
225
+
226
+ References
227
+ ----------
228
+ Zhang Z. (2023), "PRIMA: Reference Implementation for Powell's Methods with
229
+ Modernization and Amelioration", https://www.libprima.net,
230
+ :doi:`10.5281/zenodo.8052654`
213
231
  """
232
+ from .._lib.pyprima import minimize
233
+ from .._lib.pyprima.common.infos import SMALL_TR_RADIUS, FTARGET_ACHIEVED
234
+ from .._lib.pyprima.common.message import get_info_string
214
235
  _check_unknown_options(unknown_options)
215
- maxfun = maxiter
216
236
  rhoend = tol
217
- iprint = int(bool(disp))
218
-
219
- # check constraints
220
- if isinstance(constraints, dict):
221
- constraints = (constraints, )
222
-
223
- if bounds:
224
- i_lb = np.isfinite(bounds.lb)
225
- if np.any(i_lb):
226
- def lb_constraint(x, *args, **kwargs):
227
- return x[i_lb] - bounds.lb[i_lb]
228
-
229
- constraints.append({'type': 'ineq', 'fun': lb_constraint})
230
-
231
- i_ub = np.isfinite(bounds.ub)
232
- if np.any(i_ub):
233
- def ub_constraint(x):
234
- return bounds.ub[i_ub] - x[i_ub]
235
-
236
- constraints.append({'type': 'ineq', 'fun': ub_constraint})
237
-
238
- for ic, con in enumerate(constraints):
239
- # check type
240
- try:
241
- ctype = con['type'].lower()
242
- except KeyError as e:
243
- raise KeyError('Constraint %d has no type defined.' % ic) from e
244
- except TypeError as e:
245
- raise TypeError('Constraints must be defined using a '
246
- 'dictionary.') from e
247
- except AttributeError as e:
248
- raise TypeError("Constraint's type must be a string.") from e
249
- else:
250
- if ctype != 'ineq':
251
- raise ValueError(f"Constraints of type '{con['type']}' not handled by "
252
- "COBYLA.")
253
-
254
- # check function
255
- if 'fun' not in con:
256
- raise KeyError('Constraint %d has no function defined.' % ic)
257
-
258
- # check extra arguments
259
- if 'args' not in con:
260
- con['args'] = ()
261
-
262
- # m is the total number of constraint values
263
- # it takes into account that some constraints may be vector-valued
264
- cons_lengths = []
265
- for c in constraints:
266
- f = c['fun'](x0, *c['args'])
267
- try:
268
- cons_length = len(f)
269
- except TypeError:
270
- cons_length = 1
271
- cons_lengths.append(cons_length)
272
- m = sum(cons_lengths)
237
+ iprint = disp if disp is not None else 0
238
+ if iprint != 0 and iprint != 1 and iprint != 2 and iprint != 3:
239
+ raise ValueError(f'disp argument to minimize must be 0, 1, 2, or 3,\
240
+ received {iprint}')
273
241
 
274
242
  # create the ScalarFunction, cobyla doesn't require derivative function
275
243
  def _jac(x, *args):
@@ -277,40 +245,53 @@ def _minimize_cobyla(fun, x0, args=(), constraints=(),
277
245
 
278
246
  sf = _prepare_scalar_function(fun, x0, args=args, jac=_jac)
279
247
 
280
- def calcfc(x, con):
281
- f = sf.fun(x)
282
- i = 0
283
- for size, c in izip(cons_lengths, constraints):
284
- con[i: i + size] = c['fun'](x, *c['args'])
285
- i += size
286
- return f
287
-
288
- def wrapped_callback(x):
289
- if callback is not None:
290
- callback(np.copy(x))
291
-
292
- info = np.zeros(4, np.float64)
293
- xopt, info = cobyla.minimize(calcfc, m=m, x=np.copy(x0), rhobeg=rhobeg,
294
- rhoend=rhoend, iprint=iprint, maxfun=maxfun,
295
- dinfo=info, callback=wrapped_callback)
296
-
297
- if info[3] > catol:
298
- # Check constraint violation
299
- info[0] = 4
300
-
301
- return OptimizeResult(x=xopt,
302
- status=int(info[0]),
303
- success=info[0] == 1,
304
- message={1: 'Optimization terminated successfully.',
305
- 2: 'Maximum number of function evaluations '
306
- 'has been exceeded.',
307
- 3: 'Rounding errors are becoming damaging '
308
- 'in COBYLA subroutine.',
309
- 4: 'Did not converge to a solution '
310
- 'satisfying the constraints. See '
311
- '`maxcv` for magnitude of violation.',
312
- 5: 'NaN result encountered.'
313
- }.get(info[0], 'Unknown exit status.'),
314
- nfev=int(info[1]),
315
- fun=info[2],
316
- maxcv=info[3])
248
+ if callback is not None:
249
+ sig = signature(callback)
250
+ if set(sig.parameters) == {"intermediate_result"}:
251
+ def wrapped_callback_intermediate(x, f, nf, tr, cstrv, nlconstrlist):
252
+ intermediate_result = OptimizeResult(x=np.copy(x), fun=f, nfev=nf,
253
+ nit=tr, maxcv=cstrv)
254
+ callback(intermediate_result=intermediate_result)
255
+ else:
256
+ def wrapped_callback_intermediate(x, f, nf, tr, cstrv, nlconstrlist):
257
+ callback(np.copy(x))
258
+ def wrapped_callback(x, f, nf, tr, cstrv, nlconstrlist):
259
+ try:
260
+ wrapped_callback_intermediate(x, f, nf, tr, cstrv, nlconstrlist)
261
+ return False
262
+ except StopIteration:
263
+ return True
264
+ else:
265
+ wrapped_callback = None
266
+
267
+
268
+ ctol = catol if catol is not None else np.sqrt(np.finfo(float).eps)
269
+ options = {
270
+ 'rhobeg': rhobeg,
271
+ 'rhoend': rhoend,
272
+ 'maxfev': maxiter,
273
+ 'iprint': iprint,
274
+ 'ctol': ctol,
275
+ 'ftarget': f_target,
276
+ }
277
+
278
+ result = minimize(sf.fun, x0, method='cobyla', bounds=bounds,
279
+ constraints=constraints, callback=wrapped_callback,
280
+ options=options)
281
+
282
+
283
+ if result.cstrv > ctol:
284
+ success = False
285
+ message = ('Did not converge to a solution satisfying the constraints. See '
286
+ '`maxcv` for the magnitude of the violation.')
287
+ else:
288
+ success = result.info == SMALL_TR_RADIUS or result.info == FTARGET_ACHIEVED
289
+ message = get_info_string('COBYLA', result.info)
290
+
291
+ return OptimizeResult(x=result.x,
292
+ status=result.info,
293
+ success=success,
294
+ message=message,
295
+ nfev=result.nf,
296
+ fun=result.f,
297
+ maxcv=result.cstrv)
@@ -1,11 +1,15 @@
1
1
  """Constraints definition for minimize."""
2
+ from warnings import warn, catch_warnings, simplefilter, filterwarnings
3
+
2
4
  import numpy as np
3
- from ._hessian_update_strategy import BFGS
5
+
4
6
  from ._differentiable_functions import (
5
- VectorFunction, LinearVectorFunction, IdentityVectorFunction)
7
+ VectorFunction, LinearVectorFunction, IdentityVectorFunction
8
+ )
9
+ from ._hessian_update_strategy import BFGS
6
10
  from ._optimize import OptimizeWarning
7
- from warnings import warn, catch_warnings, simplefilter, filterwarnings
8
- from scipy.sparse import issparse
11
+
12
+ from scipy._lib._sparse import issparse
9
13
 
10
14
 
11
15
  def _arr_to_scalar(x):
@@ -48,7 +52,7 @@ class NonlinearConstraint:
48
52
  'cs'} select a finite difference scheme for the numerical estimation.
49
53
  A callable must have the following signature::
50
54
 
51
- jac(x) -> {ndarray, sparse matrix}, shape (m, n)
55
+ jac(x) -> {ndarray, sparse array}, shape (m, n)
52
56
 
53
57
  Default is '2-point'.
54
58
  hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy, None}, optional
@@ -63,7 +67,7 @@ class NonlinearConstraint:
63
67
 
64
68
  A callable must return the Hessian matrix of ``dot(fun, v)`` and
65
69
  must have the following signature:
66
- ``hess(x, v) -> {LinearOperator, sparse matrix, array_like}, shape (n, n)``.
70
+ ``hess(x, v) -> {LinearOperator, sparse array, array_like}, shape (n, n)``.
67
71
  Here ``v`` is ndarray with shape (m,) containing Lagrange multipliers.
68
72
  keep_feasible : array_like of bool, optional
69
73
  Whether to keep the constraint components feasible throughout
@@ -73,7 +77,7 @@ class NonlinearConstraint:
73
77
  Relative step size for the finite difference approximation. Default is
74
78
  None, which will select a reasonable value automatically depending
75
79
  on a finite difference scheme.
76
- finite_diff_jac_sparsity: {None, array_like, sparse matrix}, optional
80
+ finite_diff_jac_sparsity: {None, array_like, sparse array}, optional
77
81
  Defines the sparsity structure of the Jacobian matrix for finite
78
82
  difference estimation, its shape must be (m, n). If the Jacobian has
79
83
  only few non-zero elements in *each* row, providing the sparsity
@@ -135,7 +139,7 @@ class LinearConstraint:
135
139
 
136
140
  Parameters
137
141
  ----------
138
- A : {array_like, sparse matrix}, shape (m, n)
142
+ A : {array_like, sparse array}, shape (m, n)
139
143
  Matrix defining the constraint.
140
144
  lb, ub : dense array_like, optional
141
145
  Lower and upper limits on the constraint. Each array must have the
@@ -559,7 +563,7 @@ def old_constraint_to_new(ic, con):
559
563
  try:
560
564
  ctype = con['type'].lower()
561
565
  except KeyError as e:
562
- raise KeyError('Constraint %d has no type defined.' % ic) from e
566
+ raise KeyError(f'Constraint {ic} has no type defined.') from e
563
567
  except TypeError as e:
564
568
  raise TypeError(
565
569
  'Constraints must be a sequence of dictionaries.'
@@ -570,7 +574,7 @@ def old_constraint_to_new(ic, con):
570
574
  if ctype not in ['eq', 'ineq']:
571
575
  raise ValueError(f"Unknown constraint type '{con['type']}'.")
572
576
  if 'fun' not in con:
573
- raise ValueError('Constraint %d has no function defined.' % ic)
577
+ raise ValueError(f'Constraint {ic} has no function defined.')
574
578
 
575
579
  lb = 0
576
580
  if ctype == 'eq':