scipy 1.15.3__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0rc2__cp312-cp312-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (628) hide show
  1. scipy/__config__.py +4 -4
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-darwin.so +0 -0
  4. scipy/_lib/_array_api.py +486 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_sparse.py +41 -0
  11. scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
  12. scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
  13. scipy/_lib/_testutils.py +6 -2
  14. scipy/_lib/_util.py +222 -125
  15. scipy/_lib/array_api_compat/__init__.py +4 -4
  16. scipy/_lib/array_api_compat/_internal.py +19 -6
  17. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  18. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  19. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  20. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  21. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  22. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  23. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  24. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  25. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  26. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  27. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  28. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  29. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  30. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  31. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  32. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  33. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  34. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  35. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  36. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  37. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  38. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  39. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  40. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  41. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  42. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  43. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  44. scipy/_lib/array_api_extra/__init__.py +26 -3
  45. scipy/_lib/array_api_extra/_delegation.py +171 -0
  46. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  47. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  48. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  49. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  50. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  51. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  52. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  53. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  54. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  58. scipy/_lib/array_api_extra/testing.py +359 -0
  59. scipy/_lib/decorator.py +2 -2
  60. scipy/_lib/doccer.py +1 -7
  61. scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
  62. scipy/_lib/pyprima/__init__.py +212 -0
  63. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  64. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  65. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  66. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  67. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  68. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  69. scipy/_lib/pyprima/cobyla/update.py +289 -0
  70. scipy/_lib/pyprima/common/__init__.py +0 -0
  71. scipy/_lib/pyprima/common/_bounds.py +34 -0
  72. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  73. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  74. scipy/_lib/pyprima/common/_project.py +173 -0
  75. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  76. scipy/_lib/pyprima/common/consts.py +47 -0
  77. scipy/_lib/pyprima/common/evaluate.py +99 -0
  78. scipy/_lib/pyprima/common/history.py +38 -0
  79. scipy/_lib/pyprima/common/infos.py +30 -0
  80. scipy/_lib/pyprima/common/linalg.py +435 -0
  81. scipy/_lib/pyprima/common/message.py +290 -0
  82. scipy/_lib/pyprima/common/powalg.py +131 -0
  83. scipy/_lib/pyprima/common/preproc.py +277 -0
  84. scipy/_lib/pyprima/common/present.py +5 -0
  85. scipy/_lib/pyprima/common/ratio.py +54 -0
  86. scipy/_lib/pyprima/common/redrho.py +47 -0
  87. scipy/_lib/pyprima/common/selectx.py +296 -0
  88. scipy/_lib/tests/test__util.py +105 -121
  89. scipy/_lib/tests/test_array_api.py +166 -35
  90. scipy/_lib/tests/test_bunch.py +7 -0
  91. scipy/_lib/tests/test_ccallback.py +2 -10
  92. scipy/_lib/tests/test_public_api.py +13 -0
  93. scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
  94. scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
  95. scipy/cluster/_vq.cpython-312-darwin.so +0 -0
  96. scipy/cluster/hierarchy.py +393 -223
  97. scipy/cluster/tests/test_hierarchy.py +273 -335
  98. scipy/cluster/tests/test_vq.py +45 -61
  99. scipy/cluster/vq.py +39 -35
  100. scipy/conftest.py +263 -157
  101. scipy/constants/_constants.py +4 -1
  102. scipy/constants/tests/test_codata.py +2 -2
  103. scipy/constants/tests/test_constants.py +11 -18
  104. scipy/datasets/_download_all.py +15 -1
  105. scipy/datasets/_fetchers.py +7 -1
  106. scipy/datasets/_utils.py +1 -1
  107. scipy/differentiate/_differentiate.py +25 -25
  108. scipy/differentiate/tests/test_differentiate.py +24 -25
  109. scipy/fft/_basic.py +20 -0
  110. scipy/fft/_helper.py +3 -34
  111. scipy/fft/_pocketfft/helper.py +29 -1
  112. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  113. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  114. scipy/fft/_realtransforms.py +13 -0
  115. scipy/fft/tests/test_basic.py +27 -25
  116. scipy/fft/tests/test_fftlog.py +16 -7
  117. scipy/fft/tests/test_helper.py +18 -34
  118. scipy/fft/tests/test_real_transforms.py +8 -10
  119. scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
  120. scipy/fftpack/tests/test_basic.py +2 -4
  121. scipy/fftpack/tests/test_real_transforms.py +8 -9
  122. scipy/integrate/_bvp.py +9 -3
  123. scipy/integrate/_cubature.py +3 -2
  124. scipy/integrate/_dop.cpython-312-darwin.so +0 -0
  125. scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
  126. scipy/integrate/_ode.py +9 -2
  127. scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
  128. scipy/integrate/_quad_vec.py +21 -29
  129. scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
  130. scipy/integrate/_quadpack_py.py +11 -7
  131. scipy/integrate/_quadrature.py +3 -3
  132. scipy/integrate/_rules/_base.py +2 -2
  133. scipy/integrate/_tanhsinh.py +48 -47
  134. scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
  135. scipy/integrate/_vode.cpython-312-darwin.so +0 -0
  136. scipy/integrate/tests/test__quad_vec.py +0 -6
  137. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  138. scipy/integrate/tests/test_cubature.py +21 -35
  139. scipy/integrate/tests/test_quadrature.py +6 -8
  140. scipy/integrate/tests/test_tanhsinh.py +56 -48
  141. scipy/interpolate/__init__.py +70 -58
  142. scipy/interpolate/_bary_rational.py +22 -22
  143. scipy/interpolate/_bsplines.py +119 -66
  144. scipy/interpolate/_cubic.py +65 -50
  145. scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
  146. scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
  147. scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
  148. scipy/interpolate/_fitpack2.py +9 -6
  149. scipy/interpolate/_fitpack_impl.py +32 -26
  150. scipy/interpolate/_fitpack_repro.py +23 -19
  151. scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
  152. scipy/interpolate/_interpolate.py +30 -12
  153. scipy/interpolate/_ndbspline.py +13 -18
  154. scipy/interpolate/_ndgriddata.py +5 -8
  155. scipy/interpolate/_polyint.py +95 -31
  156. scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
  157. scipy/interpolate/_rbf.py +2 -2
  158. scipy/interpolate/_rbfinterp.py +1 -1
  159. scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
  160. scipy/interpolate/_rgi.py +31 -26
  161. scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
  162. scipy/interpolate/dfitpack.py +0 -20
  163. scipy/interpolate/interpnd.py +1 -2
  164. scipy/interpolate/tests/test_bary_rational.py +2 -2
  165. scipy/interpolate/tests/test_bsplines.py +97 -1
  166. scipy/interpolate/tests/test_fitpack2.py +39 -1
  167. scipy/interpolate/tests/test_interpnd.py +32 -20
  168. scipy/interpolate/tests/test_interpolate.py +48 -4
  169. scipy/interpolate/tests/test_rgi.py +2 -1
  170. scipy/io/_fast_matrix_market/__init__.py +2 -0
  171. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  172. scipy/io/_harwell_boeing/hb.py +7 -11
  173. scipy/io/_idl.py +5 -7
  174. scipy/io/_netcdf.py +15 -5
  175. scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
  176. scipy/io/arff/tests/test_arffread.py +3 -3
  177. scipy/io/matlab/__init__.py +5 -3
  178. scipy/io/matlab/_mio.py +4 -1
  179. scipy/io/matlab/_mio5.py +19 -13
  180. scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
  181. scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
  182. scipy/io/matlab/_miobase.py +4 -1
  183. scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
  184. scipy/io/matlab/tests/test_mio.py +46 -18
  185. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  186. scipy/io/tests/test_mmio.py +7 -1
  187. scipy/io/tests/test_wavfile.py +41 -0
  188. scipy/io/wavfile.py +57 -10
  189. scipy/linalg/_basic.py +113 -86
  190. scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
  191. scipy/linalg/_decomp.py +22 -9
  192. scipy/linalg/_decomp_cholesky.py +28 -13
  193. scipy/linalg/_decomp_cossin.py +45 -30
  194. scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
  195. scipy/linalg/_decomp_ldl.py +4 -1
  196. scipy/linalg/_decomp_lu.py +18 -6
  197. scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
  198. scipy/linalg/_decomp_polar.py +2 -0
  199. scipy/linalg/_decomp_qr.py +6 -2
  200. scipy/linalg/_decomp_qz.py +3 -0
  201. scipy/linalg/_decomp_schur.py +3 -1
  202. scipy/linalg/_decomp_svd.py +13 -2
  203. scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
  204. scipy/linalg/_expm_frechet.py +4 -0
  205. scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
  206. scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
  207. scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
  208. scipy/linalg/_matfuncs.py +187 -4
  209. scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
  210. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
  211. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  212. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
  213. scipy/linalg/_procrustes.py +2 -0
  214. scipy/linalg/_sketches.py +17 -6
  215. scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
  216. scipy/linalg/_solvers.py +7 -2
  217. scipy/linalg/_special_matrices.py +26 -36
  218. scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
  219. scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
  220. scipy/linalg/lapack.py +22 -2
  221. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  222. scipy/linalg/tests/test_basic.py +31 -16
  223. scipy/linalg/tests/test_batch.py +588 -0
  224. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  225. scipy/linalg/tests/test_decomp.py +40 -3
  226. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  227. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  228. scipy/linalg/tests/test_lapack.py +115 -7
  229. scipy/linalg/tests/test_matfuncs.py +157 -102
  230. scipy/linalg/tests/test_procrustes.py +0 -7
  231. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  232. scipy/linalg/tests/test_special_matrices.py +1 -5
  233. scipy/ndimage/__init__.py +1 -0
  234. scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
  235. scipy/ndimage/_delegators.py +8 -2
  236. scipy/ndimage/_filters.py +453 -5
  237. scipy/ndimage/_interpolation.py +36 -6
  238. scipy/ndimage/_measurements.py +4 -2
  239. scipy/ndimage/_morphology.py +5 -0
  240. scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
  241. scipy/ndimage/_ni_docstrings.py +5 -1
  242. scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
  243. scipy/ndimage/_ni_support.py +1 -5
  244. scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
  245. scipy/ndimage/_support_alternative_backends.py +18 -6
  246. scipy/ndimage/tests/test_filters.py +370 -259
  247. scipy/ndimage/tests/test_fourier.py +7 -9
  248. scipy/ndimage/tests/test_interpolation.py +68 -61
  249. scipy/ndimage/tests/test_measurements.py +18 -35
  250. scipy/ndimage/tests/test_morphology.py +143 -131
  251. scipy/ndimage/tests/test_splines.py +1 -3
  252. scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
  253. scipy/optimize/_basinhopping.py +13 -7
  254. scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
  255. scipy/optimize/_bracket.py +17 -24
  256. scipy/optimize/_chandrupatla.py +9 -10
  257. scipy/optimize/_cobyla_py.py +104 -123
  258. scipy/optimize/_constraints.py +14 -10
  259. scipy/optimize/_differentiable_functions.py +371 -230
  260. scipy/optimize/_differentialevolution.py +4 -3
  261. scipy/optimize/_direct.cpython-312-darwin.so +0 -0
  262. scipy/optimize/_dual_annealing.py +1 -1
  263. scipy/optimize/_elementwise.py +1 -4
  264. scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
  265. scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
  266. scipy/optimize/_lbfgsb_py.py +57 -16
  267. scipy/optimize/_linprog_doc.py +2 -2
  268. scipy/optimize/_linprog_highs.py +2 -2
  269. scipy/optimize/_linprog_ip.py +25 -10
  270. scipy/optimize/_linprog_util.py +14 -16
  271. scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
  272. scipy/optimize/_lsq/common.py +3 -3
  273. scipy/optimize/_lsq/dogbox.py +16 -2
  274. scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
  275. scipy/optimize/_lsq/least_squares.py +198 -126
  276. scipy/optimize/_lsq/lsq_linear.py +6 -6
  277. scipy/optimize/_lsq/trf.py +35 -8
  278. scipy/optimize/_milp.py +3 -1
  279. scipy/optimize/_minimize.py +105 -36
  280. scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
  281. scipy/optimize/_minpack_py.py +21 -14
  282. scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
  283. scipy/optimize/_nnls.py +20 -21
  284. scipy/optimize/_nonlin.py +34 -3
  285. scipy/optimize/_numdiff.py +288 -110
  286. scipy/optimize/_optimize.py +86 -48
  287. scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
  288. scipy/optimize/_remove_redundancy.py +5 -5
  289. scipy/optimize/_root_scalar.py +1 -1
  290. scipy/optimize/_shgo.py +6 -0
  291. scipy/optimize/_shgo_lib/_complex.py +1 -1
  292. scipy/optimize/_slsqp_py.py +216 -124
  293. scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
  294. scipy/optimize/_spectral.py +1 -1
  295. scipy/optimize/_tnc.py +8 -1
  296. scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
  297. scipy/optimize/_trustregion.py +20 -6
  298. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  299. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  300. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  301. scipy/optimize/_trustregion_constr/projections.py +12 -8
  302. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  303. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  304. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  305. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  306. scipy/optimize/_trustregion_exact.py +0 -1
  307. scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
  308. scipy/optimize/_zeros_py.py +97 -17
  309. scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
  310. scipy/optimize/slsqp.py +0 -1
  311. scipy/optimize/tests/test__basinhopping.py +1 -1
  312. scipy/optimize/tests/test__differential_evolution.py +4 -4
  313. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  314. scipy/optimize/tests/test__numdiff.py +66 -22
  315. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  316. scipy/optimize/tests/test__shgo.py +9 -1
  317. scipy/optimize/tests/test_bracket.py +36 -46
  318. scipy/optimize/tests/test_chandrupatla.py +133 -135
  319. scipy/optimize/tests/test_cobyla.py +74 -45
  320. scipy/optimize/tests/test_constraints.py +1 -1
  321. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  322. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  323. scipy/optimize/tests/test_least_squares.py +125 -13
  324. scipy/optimize/tests/test_linear_assignment.py +3 -3
  325. scipy/optimize/tests/test_linprog.py +3 -3
  326. scipy/optimize/tests/test_lsq_linear.py +6 -6
  327. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  328. scipy/optimize/tests/test_minpack.py +4 -4
  329. scipy/optimize/tests/test_nnls.py +43 -3
  330. scipy/optimize/tests/test_nonlin.py +36 -0
  331. scipy/optimize/tests/test_optimize.py +95 -17
  332. scipy/optimize/tests/test_slsqp.py +36 -4
  333. scipy/optimize/tests/test_zeros.py +34 -1
  334. scipy/signal/__init__.py +12 -23
  335. scipy/signal/_delegators.py +568 -0
  336. scipy/signal/_filter_design.py +459 -241
  337. scipy/signal/_fir_filter_design.py +262 -90
  338. scipy/signal/_lti_conversion.py +3 -2
  339. scipy/signal/_ltisys.py +118 -91
  340. scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
  341. scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
  342. scipy/signal/_polyutils.py +172 -0
  343. scipy/signal/_short_time_fft.py +519 -70
  344. scipy/signal/_signal_api.py +30 -0
  345. scipy/signal/_signaltools.py +719 -399
  346. scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
  347. scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
  348. scipy/signal/_spectral_py.py +230 -50
  349. scipy/signal/_spline.cpython-312-darwin.so +0 -0
  350. scipy/signal/_spline_filters.py +108 -68
  351. scipy/signal/_support_alternative_backends.py +73 -0
  352. scipy/signal/_upfirdn.py +4 -1
  353. scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
  354. scipy/signal/_waveforms.py +2 -11
  355. scipy/signal/_wavelets.py +1 -1
  356. scipy/signal/fir_filter_design.py +1 -0
  357. scipy/signal/spline.py +4 -11
  358. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  359. scipy/signal/tests/test_bsplines.py +114 -79
  360. scipy/signal/tests/test_cont2discrete.py +9 -2
  361. scipy/signal/tests/test_filter_design.py +721 -481
  362. scipy/signal/tests/test_fir_filter_design.py +332 -140
  363. scipy/signal/tests/test_savitzky_golay.py +4 -3
  364. scipy/signal/tests/test_short_time_fft.py +221 -3
  365. scipy/signal/tests/test_signaltools.py +2144 -1348
  366. scipy/signal/tests/test_spectral.py +50 -6
  367. scipy/signal/tests/test_splines.py +161 -96
  368. scipy/signal/tests/test_upfirdn.py +84 -50
  369. scipy/signal/tests/test_waveforms.py +20 -0
  370. scipy/signal/tests/test_windows.py +607 -466
  371. scipy/signal/windows/_windows.py +287 -148
  372. scipy/sparse/__init__.py +23 -4
  373. scipy/sparse/_base.py +270 -108
  374. scipy/sparse/_bsr.py +7 -4
  375. scipy/sparse/_compressed.py +59 -231
  376. scipy/sparse/_construct.py +90 -38
  377. scipy/sparse/_coo.py +115 -181
  378. scipy/sparse/_csc.py +4 -4
  379. scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
  380. scipy/sparse/_csr.py +2 -2
  381. scipy/sparse/_data.py +48 -48
  382. scipy/sparse/_dia.py +105 -18
  383. scipy/sparse/_dok.py +0 -23
  384. scipy/sparse/_index.py +4 -4
  385. scipy/sparse/_matrix.py +23 -0
  386. scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
  387. scipy/sparse/_sputils.py +37 -22
  388. scipy/sparse/base.py +0 -9
  389. scipy/sparse/bsr.py +0 -14
  390. scipy/sparse/compressed.py +0 -23
  391. scipy/sparse/construct.py +0 -6
  392. scipy/sparse/coo.py +0 -14
  393. scipy/sparse/csc.py +0 -3
  394. scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
  395. scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
  396. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
  397. scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
  398. scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
  399. scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
  400. scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
  401. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  402. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  403. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  404. scipy/sparse/csr.py +0 -5
  405. scipy/sparse/data.py +1 -6
  406. scipy/sparse/dia.py +0 -7
  407. scipy/sparse/dok.py +0 -10
  408. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
  409. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  410. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  411. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
  412. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  413. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  414. scipy/sparse/linalg/_interface.py +17 -18
  415. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  416. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  417. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  418. scipy/sparse/linalg/_isolve/minres.py +5 -5
  419. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  420. scipy/sparse/linalg/_isolve/utils.py +2 -8
  421. scipy/sparse/linalg/_matfuncs.py +1 -1
  422. scipy/sparse/linalg/_norm.py +1 -1
  423. scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
  424. scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
  425. scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
  426. scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
  427. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  428. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  429. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  430. scipy/sparse/tests/test_base.py +214 -42
  431. scipy/sparse/tests/test_common1d.py +7 -7
  432. scipy/sparse/tests/test_construct.py +1 -1
  433. scipy/sparse/tests/test_coo.py +272 -4
  434. scipy/sparse/tests/test_sparsetools.py +5 -0
  435. scipy/sparse/tests/test_sputils.py +36 -7
  436. scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
  437. scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
  438. scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
  439. scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
  440. scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
  441. scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
  442. scipy/spatial/distance.py +49 -42
  443. scipy/spatial/tests/test_distance.py +15 -1
  444. scipy/spatial/tests/test_kdtree.py +1 -0
  445. scipy/spatial/tests/test_qhull.py +7 -2
  446. scipy/spatial/transform/__init__.py +5 -3
  447. scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
  448. scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
  449. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  450. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  451. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  452. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  453. scipy/special/__init__.py +1 -47
  454. scipy/special/_add_newdocs.py +34 -772
  455. scipy/special/_basic.py +22 -25
  456. scipy/special/_comb.cpython-312-darwin.so +0 -0
  457. scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
  458. scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
  459. scipy/special/_logsumexp.py +67 -58
  460. scipy/special/_orthogonal.pyi +1 -1
  461. scipy/special/_specfun.cpython-312-darwin.so +0 -0
  462. scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
  463. scipy/special/_spherical_bessel.py +4 -4
  464. scipy/special/_support_alternative_backends.py +212 -119
  465. scipy/special/_test_internal.cpython-312-darwin.so +0 -0
  466. scipy/special/_testutils.py +4 -4
  467. scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
  468. scipy/special/_ufuncs.pyi +1 -0
  469. scipy/special/_ufuncs.pyx +215 -1400
  470. scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
  471. scipy/special/_ufuncs_cxx.pxd +2 -15
  472. scipy/special/_ufuncs_cxx.pyx +5 -44
  473. scipy/special/_ufuncs_cxx_defs.h +2 -16
  474. scipy/special/_ufuncs_defs.h +0 -8
  475. scipy/special/cython_special.cpython-312-darwin.so +0 -0
  476. scipy/special/cython_special.pxd +1 -1
  477. scipy/special/tests/_cython_examples/meson.build +10 -1
  478. scipy/special/tests/test_basic.py +153 -20
  479. scipy/special/tests/test_boost_ufuncs.py +3 -0
  480. scipy/special/tests/test_cdflib.py +35 -11
  481. scipy/special/tests/test_gammainc.py +16 -0
  482. scipy/special/tests/test_hyp2f1.py +2 -2
  483. scipy/special/tests/test_log1mexp.py +85 -0
  484. scipy/special/tests/test_logsumexp.py +206 -64
  485. scipy/special/tests/test_mpmath.py +1 -0
  486. scipy/special/tests/test_nan_inputs.py +1 -1
  487. scipy/special/tests/test_orthogonal.py +17 -18
  488. scipy/special/tests/test_sf_error.py +3 -2
  489. scipy/special/tests/test_sph_harm.py +6 -7
  490. scipy/special/tests/test_support_alternative_backends.py +211 -76
  491. scipy/stats/__init__.py +4 -1
  492. scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
  493. scipy/stats/_axis_nan_policy.py +5 -12
  494. scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
  495. scipy/stats/_continued_fraction.py +387 -0
  496. scipy/stats/_continuous_distns.py +277 -310
  497. scipy/stats/_correlation.py +1 -1
  498. scipy/stats/_covariance.py +6 -3
  499. scipy/stats/_discrete_distns.py +39 -32
  500. scipy/stats/_distn_infrastructure.py +39 -12
  501. scipy/stats/_distribution_infrastructure.py +900 -238
  502. scipy/stats/_entropy.py +9 -10
  503. scipy/{_lib → stats}/_finite_differences.py +1 -1
  504. scipy/stats/_hypotests.py +83 -50
  505. scipy/stats/_kde.py +53 -49
  506. scipy/stats/_ksstats.py +1 -1
  507. scipy/stats/_levy_stable/__init__.py +7 -15
  508. scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
  509. scipy/stats/_morestats.py +118 -73
  510. scipy/stats/_mstats_basic.py +13 -17
  511. scipy/stats/_mstats_extras.py +8 -8
  512. scipy/stats/_multivariate.py +89 -113
  513. scipy/stats/_new_distributions.py +97 -20
  514. scipy/stats/_page_trend_test.py +12 -5
  515. scipy/stats/_probability_distribution.py +265 -43
  516. scipy/stats/_qmc.py +14 -9
  517. scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
  518. scipy/stats/_qmvnt.py +16 -95
  519. scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
  520. scipy/stats/_quantile.py +335 -0
  521. scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
  522. scipy/stats/_resampling.py +4 -29
  523. scipy/stats/_sampling.py +1 -1
  524. scipy/stats/_sobol.cpython-312-darwin.so +0 -0
  525. scipy/stats/_stats.cpython-312-darwin.so +0 -0
  526. scipy/stats/_stats_mstats_common.py +21 -2
  527. scipy/stats/_stats_py.py +550 -476
  528. scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
  529. scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
  530. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  531. scipy/stats/_variation.py +6 -8
  532. scipy/stats/_wilcoxon.py +13 -7
  533. scipy/stats/tests/common_tests.py +6 -4
  534. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  535. scipy/stats/tests/test_continued_fraction.py +173 -0
  536. scipy/stats/tests/test_continuous.py +379 -60
  537. scipy/stats/tests/test_continuous_basic.py +18 -12
  538. scipy/stats/tests/test_discrete_basic.py +14 -8
  539. scipy/stats/tests/test_discrete_distns.py +16 -16
  540. scipy/stats/tests/test_distributions.py +95 -75
  541. scipy/stats/tests/test_entropy.py +40 -48
  542. scipy/stats/tests/test_fit.py +4 -3
  543. scipy/stats/tests/test_hypotests.py +153 -24
  544. scipy/stats/tests/test_kdeoth.py +109 -41
  545. scipy/stats/tests/test_marray.py +289 -0
  546. scipy/stats/tests/test_morestats.py +79 -47
  547. scipy/stats/tests/test_mstats_basic.py +3 -3
  548. scipy/stats/tests/test_multivariate.py +434 -83
  549. scipy/stats/tests/test_qmc.py +13 -10
  550. scipy/stats/tests/test_quantile.py +199 -0
  551. scipy/stats/tests/test_rank.py +119 -112
  552. scipy/stats/tests/test_resampling.py +47 -56
  553. scipy/stats/tests/test_sampling.py +9 -4
  554. scipy/stats/tests/test_stats.py +799 -939
  555. scipy/stats/tests/test_variation.py +8 -6
  556. scipy/version.py +2 -2
  557. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  558. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  559. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +560 -567
  560. scipy-1.16.0rc2.dist-info/WHEEL +6 -0
  561. scipy/_lib/array_api_extra/_funcs.py +0 -484
  562. scipy/_lib/array_api_extra/_typing.py +0 -8
  563. scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
  564. scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
  565. scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
  566. scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
  567. scipy/spatial/qhull_src/COPYING.txt +0 -38
  568. scipy/special/libsf_error_state.dylib +0 -0
  569. scipy/special/tests/test_log_softmax.py +0 -109
  570. scipy/special/tests/test_xsf_cuda.py +0 -114
  571. scipy/special/xsf/binom.h +0 -89
  572. scipy/special/xsf/cdflib.h +0 -100
  573. scipy/special/xsf/cephes/airy.h +0 -307
  574. scipy/special/xsf/cephes/besselpoly.h +0 -51
  575. scipy/special/xsf/cephes/beta.h +0 -257
  576. scipy/special/xsf/cephes/cbrt.h +0 -131
  577. scipy/special/xsf/cephes/chbevl.h +0 -85
  578. scipy/special/xsf/cephes/chdtr.h +0 -193
  579. scipy/special/xsf/cephes/const.h +0 -87
  580. scipy/special/xsf/cephes/ellie.h +0 -293
  581. scipy/special/xsf/cephes/ellik.h +0 -251
  582. scipy/special/xsf/cephes/ellpe.h +0 -107
  583. scipy/special/xsf/cephes/ellpk.h +0 -117
  584. scipy/special/xsf/cephes/expn.h +0 -260
  585. scipy/special/xsf/cephes/gamma.h +0 -398
  586. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  587. scipy/special/xsf/cephes/hyperg.h +0 -361
  588. scipy/special/xsf/cephes/i0.h +0 -149
  589. scipy/special/xsf/cephes/i1.h +0 -158
  590. scipy/special/xsf/cephes/igam.h +0 -421
  591. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  592. scipy/special/xsf/cephes/igami.h +0 -313
  593. scipy/special/xsf/cephes/j0.h +0 -225
  594. scipy/special/xsf/cephes/j1.h +0 -198
  595. scipy/special/xsf/cephes/jv.h +0 -715
  596. scipy/special/xsf/cephes/k0.h +0 -164
  597. scipy/special/xsf/cephes/k1.h +0 -163
  598. scipy/special/xsf/cephes/kn.h +0 -243
  599. scipy/special/xsf/cephes/lanczos.h +0 -112
  600. scipy/special/xsf/cephes/ndtr.h +0 -275
  601. scipy/special/xsf/cephes/poch.h +0 -85
  602. scipy/special/xsf/cephes/polevl.h +0 -167
  603. scipy/special/xsf/cephes/psi.h +0 -194
  604. scipy/special/xsf/cephes/rgamma.h +0 -111
  605. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  606. scipy/special/xsf/cephes/shichi.h +0 -248
  607. scipy/special/xsf/cephes/sici.h +0 -224
  608. scipy/special/xsf/cephes/sindg.h +0 -221
  609. scipy/special/xsf/cephes/tandg.h +0 -139
  610. scipy/special/xsf/cephes/trig.h +0 -58
  611. scipy/special/xsf/cephes/unity.h +0 -186
  612. scipy/special/xsf/cephes/zeta.h +0 -172
  613. scipy/special/xsf/config.h +0 -304
  614. scipy/special/xsf/digamma.h +0 -205
  615. scipy/special/xsf/error.h +0 -57
  616. scipy/special/xsf/evalpoly.h +0 -47
  617. scipy/special/xsf/expint.h +0 -266
  618. scipy/special/xsf/hyp2f1.h +0 -694
  619. scipy/special/xsf/iv_ratio.h +0 -173
  620. scipy/special/xsf/lambertw.h +0 -150
  621. scipy/special/xsf/loggamma.h +0 -163
  622. scipy/special/xsf/sici.h +0 -200
  623. scipy/special/xsf/tools.h +0 -427
  624. scipy/special/xsf/trig.h +0 -164
  625. scipy/special/xsf/wright_bessel.h +0 -843
  626. scipy/special/xsf/zlog1.h +0 -35
  627. scipy/stats/_mvn.cpython-312-darwin.so +0 -0
  628. scipy-1.15.3.dist-info/WHEEL +0 -4
@@ -1,10 +1,11 @@
1
1
  import math
2
2
  import pytest
3
3
  import numpy as np
4
+ from copy import deepcopy
4
5
 
5
6
  from scipy import stats, special
6
7
  import scipy._lib._elementwise_iterative_method as eim
7
- from scipy.conftest import array_api_compatible
8
+ import scipy._lib.array_api_extra as xpx
8
9
  from scipy._lib._array_api import array_namespace, is_cupy, is_numpy, xp_ravel, xp_size
9
10
  from scipy._lib._array_api_no_0d import (xp_assert_close, xp_assert_equal,
10
11
  xp_assert_less)
@@ -13,7 +14,6 @@ from scipy.optimize.elementwise import find_minimum, find_root
13
14
  from scipy.optimize._tstutils import _CHANDRUPATLA_TESTS
14
15
 
15
16
  from itertools import permutations
16
- from .test_zeros import TestScalarRootFinders
17
17
 
18
18
 
19
19
  def _vectorize(xp):
@@ -82,7 +82,6 @@ def _wrap_chandrupatla(func):
82
82
  return _chandrupatla_wrapper
83
83
 
84
84
 
85
- _chandrupatla_root = _wrap_chandrupatla(find_root)
86
85
  _chandrupatla_minimize = _wrap_chandrupatla(find_minimum)
87
86
 
88
87
 
@@ -186,8 +185,7 @@ cases = [
186
185
  ]
187
186
 
188
187
 
189
- @array_api_compatible
190
- @pytest.mark.usefixtures("skip_xp_backends")
188
+ @pytest.mark.skip_xp_backends('dask.array', reason='no take_along_axis')
191
189
  @pytest.mark.skip_xp_backends('jax.numpy',
192
190
  reason='JAX arrays do not support item assignment.')
193
191
  @pytest.mark.skip_xp_backends('array_api_strict',
@@ -221,7 +219,6 @@ class TestChandrupatlaMinimize:
221
219
  loc = xp.linspace(-0.05, 1.05, 12).reshape(shape) if shape else xp.asarray(0.6)
222
220
  args = (loc,)
223
221
  bracket = xp.asarray(-5.), xp.asarray(0.), xp.asarray(5.)
224
- xp_test = array_namespace(loc) # need xp.stack
225
222
 
226
223
  @_vectorize(xp)
227
224
  def chandrupatla_single(loc_single):
@@ -238,7 +235,7 @@ class TestChandrupatlaMinimize:
238
235
  attrs = ['x', 'fun', 'success', 'status', 'nfev', 'nit',
239
236
  'xl', 'xm', 'xr', 'fl', 'fm', 'fr']
240
237
  for attr in attrs:
241
- ref_attr = xp_test.stack([getattr(ref, attr) for ref in refs])
238
+ ref_attr = xp.stack([getattr(ref, attr) for ref in refs])
242
239
  res_attr = xp_ravel(getattr(res, attr))
243
240
  xp_assert_equal(res_attr, ref_attr)
244
241
  assert getattr(res, attr).shape == shape
@@ -250,10 +247,10 @@ class TestChandrupatlaMinimize:
250
247
  assert xp.max(res.nfev) == f.f_evals
251
248
  assert xp.max(res.nit) == f.f_evals - 3
252
249
 
253
- assert xp_test.isdtype(res.success.dtype, 'bool')
254
- assert xp_test.isdtype(res.status.dtype, 'integral')
255
- assert xp_test.isdtype(res.nfev.dtype, 'integral')
256
- assert xp_test.isdtype(res.nit.dtype, 'integral')
250
+ assert xp.isdtype(res.success.dtype, 'bool')
251
+ assert xp.isdtype(res.status.dtype, 'integral')
252
+ assert xp.isdtype(res.nfev.dtype, 'integral')
253
+ assert xp.isdtype(res.nit.dtype, 'integral')
257
254
 
258
255
 
259
256
  def test_flags(self, xp):
@@ -285,7 +282,7 @@ class TestChandrupatlaMinimize:
285
282
  # Test that the convergence tolerances behave as expected
286
283
  rng = np.random.default_rng(2585255913088665241)
287
284
  p = xp.asarray(rng.random(size=3))
288
- bracket = (xp.asarray(-5), xp.asarray(0), xp.asarray(5))
285
+ bracket = (xp.asarray(-5, dtype=xp.float64), xp.asarray(0), xp.asarray(5))
289
286
  args = (p,)
290
287
  kwargs0 = dict(args=args, xatol=0, xrtol=0, fatol=0, frtol=0)
291
288
 
@@ -427,10 +424,9 @@ class TestChandrupatlaMinimize:
427
424
  xp.asarray(1, dtype=dtype),
428
425
  xp.asarray(5, dtype=dtype))
429
426
 
430
- xp_test = array_namespace(loc) # need astype
431
427
  def f(x, loc):
432
428
  assert x.dtype == dtype
433
- return xp_test.astype((x - loc)**2, dtype)
429
+ return xp.astype((x - loc)**2, dtype)
434
430
 
435
431
  res = _chandrupatla_minimize(f, *bracket, args=(loc,))
436
432
  assert res.x.dtype == dtype
@@ -484,22 +480,19 @@ class TestChandrupatlaMinimize:
484
480
 
485
481
  def test_bracket_order(self, xp):
486
482
  # Confirm that order of points in bracket doesn't
487
- xp_test = array_namespace(xp.asarray(1.)) # need `xp.newaxis`
488
- loc = xp.linspace(-1, 1, 6)[:, xp_test.newaxis]
483
+ loc = xp.linspace(-1, 1, 6)[:, xp.newaxis]
489
484
  brackets = xp.asarray(list(permutations([-5, 0, 5]))).T
490
485
  res = _chandrupatla_minimize(self.f, *brackets, args=(loc,))
491
- assert xp.all(xp.isclose(res.x, loc) | (res.fun == self.f(loc, loc)))
486
+ assert xp.all(xpx.isclose(res.x, loc) | (res.fun == self.f(loc, loc)))
492
487
  ref = res.x[:, 0] # all columns should be the same
493
- xp_test = array_namespace(loc) # need `xp.broadcast_arrays
494
- xp_assert_close(*xp_test.broadcast_arrays(res.x.T, ref), rtol=1e-15)
488
+ xp_assert_close(*xp.broadcast_arrays(res.x.T, ref), rtol=1e-15)
495
489
 
496
490
  def test_special_cases(self, xp):
497
491
  # Test edge cases and other special cases
498
492
 
499
493
  # Test that integers are not passed to `f`
500
- xp_test = array_namespace(xp.asarray(1.)) # need `xp.isdtype`
501
494
  def f(x):
502
- assert xp_test.isdtype(x.dtype, "real floating")
495
+ assert xp.isdtype(x.dtype, "real floating")
503
496
  return (x - 1)**2
504
497
 
505
498
  bracket = xp.asarray(-7), xp.asarray(0), xp.asarray(8)
@@ -552,15 +545,12 @@ class TestChandrupatlaMinimize:
552
545
  assert f(res.xl) == f(res.xm) == f(res.xr)
553
546
 
554
547
 
555
- @array_api_compatible
556
- @pytest.mark.usefixtures("skip_xp_backends")
548
+ @pytest.mark.skip_xp_backends('dask.array', reason='boolean indexing assignment')
557
549
  @pytest.mark.skip_xp_backends('array_api_strict',
558
550
  reason='Currently uses fancy indexing assignment.')
559
551
  @pytest.mark.skip_xp_backends('jax.numpy',
560
552
  reason='JAX arrays do not support item assignment.')
561
- @pytest.mark.skip_xp_backends('cupy',
562
- reason='cupy/cupy#8391')
563
- class TestChandrupatla(TestScalarRootFinders):
553
+ class TestFindRoot:
564
554
 
565
555
  def f(self, q, p):
566
556
  return special.ndtr(q) - p
@@ -569,7 +559,7 @@ class TestChandrupatla(TestScalarRootFinders):
569
559
  def test_basic(self, p, xp):
570
560
  # Invert distribution CDF and compare against distribution `ppf`
571
561
  a, b = xp.asarray(-5.), xp.asarray(5.)
572
- res = _chandrupatla_root(self.f, a, b, args=(xp.asarray(p),))
562
+ res = find_root(self.f, (a, b), args=(xp.asarray(p),))
573
563
  ref = xp.asarray(stats.norm().ppf(p), dtype=xp.asarray(p).dtype)
574
564
  xp_assert_close(res.x, ref)
575
565
 
@@ -582,36 +572,36 @@ class TestChandrupatla(TestScalarRootFinders):
582
572
  p_xp = xp.asarray(p)
583
573
  args_xp = (p_xp,)
584
574
  dtype = p_xp.dtype
585
- xp_test = array_namespace(p_xp) # need xp.bool
586
575
 
587
576
  @np.vectorize
588
- def chandrupatla_single(p):
589
- return _chandrupatla_root(self.f, -5, 5, args=(p,))
577
+ def find_root_single(p):
578
+ return find_root(self.f, (-5, 5), args=(p,))
590
579
 
591
580
  def f(*args, **kwargs):
592
581
  f.f_evals += 1
593
582
  return self.f(*args, **kwargs)
594
583
  f.f_evals = 0
595
584
 
596
- res = _chandrupatla_root(f, xp.asarray(-5.), xp.asarray(5.), args=args_xp)
597
- refs = chandrupatla_single(p).ravel()
585
+ bracket = xp.asarray(-5., dtype=xp.float64), xp.asarray(5., dtype=xp.float64)
586
+ res = find_root(f, bracket, args=args_xp)
587
+ refs = find_root_single(p).ravel()
598
588
 
599
589
  ref_x = [ref.x for ref in refs]
600
590
  ref_x = xp.reshape(xp.asarray(ref_x, dtype=dtype), shape)
601
591
  xp_assert_close(res.x, ref_x)
602
592
 
603
- ref_fun = [ref.fun for ref in refs]
604
- ref_fun = xp.reshape(xp.asarray(ref_fun, dtype=dtype), shape)
605
- xp_assert_close(res.fun, ref_fun, atol=1e-15)
606
- xp_assert_equal(res.fun, self.f(res.x, *args_xp))
593
+ ref_f = [ref.f_x for ref in refs]
594
+ ref_f = xp.reshape(xp.asarray(ref_f, dtype=dtype), shape)
595
+ xp_assert_close(res.f_x, ref_f, atol=1e-15)
596
+ xp_assert_equal(res.f_x, self.f(res.x, *args_xp))
607
597
 
608
598
  ref_success = [bool(ref.success) for ref in refs]
609
- ref_success = xp.reshape(xp.asarray(ref_success, dtype=xp_test.bool), shape)
599
+ ref_success = xp.reshape(xp.asarray(ref_success, dtype=xp.bool), shape)
610
600
  xp_assert_equal(res.success, ref_success)
611
601
 
612
- ref_flag = [ref.status for ref in refs]
613
- ref_flag = xp.reshape(xp.asarray(ref_flag, dtype=xp.int32), shape)
614
- xp_assert_equal(res.status, ref_flag)
602
+ ref_status = [ref.status for ref in refs]
603
+ ref_status = xp.reshape(xp.asarray(ref_status, dtype=xp.int32), shape)
604
+ xp_assert_equal(res.status, ref_status)
615
605
 
616
606
  ref_nfev = [ref.nfev for ref in refs]
617
607
  ref_nfev = xp.reshape(xp.asarray(ref_nfev, dtype=xp.int32), shape)
@@ -631,35 +621,35 @@ class TestChandrupatla(TestScalarRootFinders):
631
621
  assert res.nit.shape == shape
632
622
  assert res.nit.dtype == xp.int32
633
623
 
634
- ref_xl = [ref.xl for ref in refs]
624
+ ref_xl = [ref.bracket[0] for ref in refs]
635
625
  ref_xl = xp.reshape(xp.asarray(ref_xl, dtype=dtype), shape)
636
- xp_assert_close(res.xl, ref_xl)
626
+ xp_assert_close(res.bracket[0], ref_xl)
637
627
 
638
- ref_xr = [ref.xr for ref in refs]
628
+ ref_xr = [ref.bracket[1] for ref in refs]
639
629
  ref_xr = xp.reshape(xp.asarray(ref_xr, dtype=dtype), shape)
640
- xp_assert_close(res.xr, ref_xr)
630
+ xp_assert_close(res.bracket[1], ref_xr)
641
631
 
642
- xp_assert_less(res.xl, res.xr)
632
+ xp_assert_less(res.bracket[0], res.bracket[1])
643
633
  finite = xp.isfinite(res.x)
644
- assert xp.all((res.x[finite] == res.xl[finite])
645
- | (res.x[finite] == res.xr[finite]))
634
+ assert xp.all((res.x[finite] == res.bracket[0][finite])
635
+ | (res.x[finite] == res.bracket[1][finite]))
646
636
 
647
637
  # PyTorch and CuPy don't solve to the same accuracy as NumPy - that's OK.
648
638
  atol = 1e-15 if is_numpy(xp) else 1e-9
649
639
 
650
- ref_fl = [ref.fl for ref in refs]
640
+ ref_fl = [ref.f_bracket[0] for ref in refs]
651
641
  ref_fl = xp.reshape(xp.asarray(ref_fl, dtype=dtype), shape)
652
- xp_assert_close(res.fl, ref_fl, atol=atol)
653
- xp_assert_equal(res.fl, self.f(res.xl, *args_xp))
642
+ xp_assert_close(res.f_bracket[0], ref_fl, atol=atol)
643
+ xp_assert_equal(res.f_bracket[0], self.f(res.bracket[0], *args_xp))
654
644
 
655
- ref_fr = [ref.fr for ref in refs]
645
+ ref_fr = [ref.f_bracket[1] for ref in refs]
656
646
  ref_fr = xp.reshape(xp.asarray(ref_fr, dtype=dtype), shape)
657
- xp_assert_close(res.fr, ref_fr, atol=atol)
658
- xp_assert_equal(res.fr, self.f(res.xr, *args_xp))
647
+ xp_assert_close(res.f_bracket[1], ref_fr, atol=atol)
648
+ xp_assert_equal(res.f_bracket[1], self.f(res.bracket[1], *args_xp))
659
649
 
660
- assert xp.all(xp.abs(res.fun[finite]) ==
661
- xp.minimum(xp.abs(res.fl[finite]),
662
- xp.abs(res.fr[finite])))
650
+ assert xp.all(xp.abs(res.f_x[finite]) ==
651
+ xp.minimum(xp.abs(res.f_bracket[0][finite]),
652
+ xp.abs(res.f_bracket[1][finite])))
663
653
 
664
654
  def test_flags(self, xp):
665
655
  # Test cases that should produce different status flags; show that all
@@ -684,7 +674,7 @@ class TestChandrupatla(TestScalarRootFinders):
684
674
 
685
675
  args = (xp.arange(4, dtype=xp.int64),)
686
676
  a, b = xp.asarray([0.]*4), xp.asarray([xp.pi]*4)
687
- res = _chandrupatla_root(f, a, b, args=args, maxiter=2)
677
+ res = find_root(f, (a, b), args=args, maxiter=2)
688
678
 
689
679
  ref_flags = xp.asarray([eim._ECONVERGED,
690
680
  eim._ESIGNERR,
@@ -698,45 +688,50 @@ class TestChandrupatla(TestScalarRootFinders):
698
688
  p = xp.asarray(rng.random(size=3))
699
689
  bracket = (-xp.asarray(5.), xp.asarray(5.))
700
690
  args = (p,)
701
- kwargs0 = dict(args=args, xatol=0, xrtol=0, fatol=0, frtol=0)
702
-
703
- kwargs = kwargs0.copy()
704
- kwargs['xatol'] = 1e-3
705
- res1 = _chandrupatla_root(self.f, *bracket, **kwargs)
706
- xp_assert_less(res1.xr - res1.xl, xp.full_like(p, xp.asarray(1e-3)))
707
- kwargs['xatol'] = 1e-6
708
- res2 = _chandrupatla_root(self.f, *bracket, **kwargs)
709
- xp_assert_less(res2.xr - res2.xl, xp.full_like(p, xp.asarray(1e-6)))
710
- xp_assert_less(res2.xr - res2.xl, res1.xr - res1.xl)
711
-
712
- kwargs = kwargs0.copy()
713
- kwargs['xrtol'] = 1e-3
714
- res1 = _chandrupatla_root(self.f, *bracket, **kwargs)
715
- xp_assert_less(res1.xr - res1.xl, 1e-3 * xp.abs(res1.x))
716
- kwargs['xrtol'] = 1e-6
717
- res2 = _chandrupatla_root(self.f, *bracket, **kwargs)
718
- xp_assert_less(res2.xr - res2.xl, 1e-6 * xp.abs(res2.x))
719
- xp_assert_less(res2.xr - res2.xl, res1.xr - res1.xl)
720
-
721
- kwargs = kwargs0.copy()
722
- kwargs['fatol'] = 1e-3
723
- res1 = _chandrupatla_root(self.f, *bracket, **kwargs)
724
- xp_assert_less(xp.abs(res1.fun), xp.full_like(p, xp.asarray(1e-3)))
725
- kwargs['fatol'] = 1e-6
726
- res2 = _chandrupatla_root(self.f, *bracket, **kwargs)
727
- xp_assert_less(xp.abs(res2.fun), xp.full_like(p, xp.asarray(1e-6)))
728
- xp_assert_less(xp.abs(res2.fun), xp.abs(res1.fun))
729
-
730
- kwargs = kwargs0.copy()
731
- kwargs['frtol'] = 1e-3
691
+ kwargs0 = dict(args=args, tolerances=dict(xatol=0, xrtol=0, fatol=0, frtol=0))
692
+
693
+ kwargs = deepcopy(kwargs0)
694
+ kwargs['tolerances']['xatol'] = 1e-3
695
+ res1 = find_root(self.f, bracket, **kwargs)
696
+ xp_assert_less(res1.bracket[1] - res1.bracket[0],
697
+ xp.full_like(p, xp.asarray(1e-3)))
698
+ kwargs['tolerances']['xatol'] = 1e-6
699
+ res2 = find_root(self.f, bracket, **kwargs)
700
+ xp_assert_less(res2.bracket[1] - res2.bracket[0],
701
+ xp.full_like(p, xp.asarray(1e-6)))
702
+ xp_assert_less(res2.bracket[1] - res2.bracket[0],
703
+ res1.bracket[1] - res1.bracket[0])
704
+
705
+ kwargs = deepcopy(kwargs0)
706
+ kwargs['tolerances']['xrtol'] = 1e-3
707
+ res1 = find_root(self.f, bracket, **kwargs)
708
+ xp_assert_less(res1.bracket[1] - res1.bracket[0], 1e-3 * xp.abs(res1.x))
709
+ kwargs['tolerances']['xrtol'] = 1e-6
710
+ res2 = find_root(self.f, bracket, **kwargs)
711
+ xp_assert_less(res2.bracket[1] - res2.bracket[0],
712
+ 1e-6 * xp.abs(res2.x))
713
+ xp_assert_less(res2.bracket[1] - res2.bracket[0],
714
+ res1.bracket[1] - res1.bracket[0])
715
+
716
+ kwargs = deepcopy(kwargs0)
717
+ kwargs['tolerances']['fatol'] = 1e-3
718
+ res1 = find_root(self.f, bracket, **kwargs)
719
+ xp_assert_less(xp.abs(res1.f_x), xp.full_like(p, xp.asarray(1e-3)))
720
+ kwargs['tolerances']['fatol'] = 1e-6
721
+ res2 = find_root(self.f, bracket, **kwargs)
722
+ xp_assert_less(xp.abs(res2.f_x), xp.full_like(p, xp.asarray(1e-6)))
723
+ xp_assert_less(xp.abs(res2.f_x), xp.abs(res1.f_x))
724
+
725
+ kwargs = deepcopy(kwargs0)
726
+ kwargs['tolerances']['frtol'] = 1e-3
732
727
  x1, x2 = bracket
733
728
  f0 = xp.minimum(xp.abs(self.f(x1, *args)), xp.abs(self.f(x2, *args)))
734
- res1 = _chandrupatla_root(self.f, *bracket, **kwargs)
735
- xp_assert_less(xp.abs(res1.fun), 1e-3*f0)
736
- kwargs['frtol'] = 1e-6
737
- res2 = _chandrupatla_root(self.f, *bracket, **kwargs)
738
- xp_assert_less(xp.abs(res2.fun), 1e-6*f0)
739
- xp_assert_less(xp.abs(res2.fun), xp.abs(res1.fun))
729
+ res1 = find_root(self.f, bracket, **kwargs)
730
+ xp_assert_less(xp.abs(res1.f_x), 1e-3*f0)
731
+ kwargs['tolerances']['frtol'] = 1e-6
732
+ res2 = find_root(self.f, bracket, **kwargs)
733
+ xp_assert_less(xp.abs(res2.f_x), 1e-6*f0)
734
+ xp_assert_less(xp.abs(res2.f_x), xp.abs(res1.f_x))
740
735
 
741
736
  def test_maxiter_callback(self, xp):
742
737
  # Test behavior of `maxiter` parameter and `callback` interface
@@ -747,12 +742,12 @@ class TestChandrupatla(TestScalarRootFinders):
747
742
  def f(q, p):
748
743
  res = special.ndtr(q) - p
749
744
  f.x = q
750
- f.fun = res
745
+ f.f_x = res
751
746
  return res
752
747
  f.x = None
753
- f.fun = None
748
+ f.f_x = None
754
749
 
755
- res = _chandrupatla_root(f, *bracket, args=(p,), maxiter=maxiter)
750
+ res = find_root(f, bracket, args=(p,), maxiter=maxiter)
756
751
  assert not xp.any(res.success)
757
752
  assert xp.all(res.nfev == maxiter+2)
758
753
  assert xp.all(res.nit == maxiter)
@@ -763,26 +758,27 @@ class TestChandrupatla(TestScalarRootFinders):
763
758
  assert hasattr(res, 'x')
764
759
  if callback.iter == 0:
765
760
  # callback is called once with initial bracket
766
- assert (res.xl, res.xr) == bracket
761
+ assert (res.bracket[0], res.bracket[1]) == bracket
767
762
  else:
768
- changed = (((res.xl == callback.xl) & (res.xr != callback.xr))
769
- | ((res.xl != callback.xl) & (res.xr == callback.xr)))
763
+ changed = (((res.bracket[0] == callback.bracket[0])
764
+ & (res.bracket[1] != callback.bracket[1]))
765
+ | ((res.bracket[0] != callback.bracket[0])
766
+ & (res.bracket[1] == callback.bracket[1])))
770
767
  assert xp.all(changed)
771
768
 
772
- callback.xl = res.xl
773
- callback.xr = res.xr
769
+ callback.bracket[0] = res.bracket[0]
770
+ callback.bracket[1] = res.bracket[1]
774
771
  assert res.status == eim._EINPROGRESS
775
- xp_assert_equal(self.f(res.xl, p), res.fl)
776
- xp_assert_equal(self.f(res.xr, p), res.fr)
777
- xp_assert_equal(self.f(res.x, p), res.fun)
772
+ xp_assert_equal(self.f(res.bracket[0], p), res.f_bracket[0])
773
+ xp_assert_equal(self.f(res.bracket[1], p), res.f_bracket[1])
774
+ xp_assert_equal(self.f(res.x, p), res.f_x)
778
775
  if callback.iter == maxiter:
779
776
  raise StopIteration
780
777
  callback.iter = -1 # callback called once before first iteration
781
778
  callback.res = None
782
- callback.xl = None
783
- callback.xr = None
779
+ callback.bracket = [None, None]
784
780
 
785
- res2 = _chandrupatla_root(f, *bracket, args=(p,), callback=callback)
781
+ res2 = find_root(f, bracket, args=(p,), callback=callback)
786
782
 
787
783
  # terminating with callback is identical to terminating due to maxiter
788
784
  # (except for `status`)
@@ -790,6 +786,9 @@ class TestChandrupatla(TestScalarRootFinders):
790
786
  if key == 'status':
791
787
  xp_assert_equal(res[key], xp.asarray(eim._ECONVERR, dtype=xp.int32))
792
788
  xp_assert_equal(res2[key], xp.asarray(eim._ECALLBACK, dtype=xp.int32))
789
+ elif key in {'bracket', 'f_bracket'}:
790
+ xp_assert_equal(res2[key][0], res[key][0])
791
+ xp_assert_equal(res2[key][1], res[key][1])
793
792
  elif key.startswith('_'):
794
793
  continue
795
794
  else:
@@ -809,8 +808,8 @@ class TestChandrupatla(TestScalarRootFinders):
809
808
  xp.asarray(bracket[1], dtype=xp.float64))
810
809
  root = xp.asarray(root, dtype=xp.float64)
811
810
 
812
- res = _chandrupatla_root(f, *bracket, xrtol=4e-10, xatol=1e-5)
813
- xp_assert_close(res.fun, xp.asarray(f(root), dtype=xp.float64),
811
+ res = find_root(f, bracket, tolerances=dict(xrtol=4e-10, xatol=1e-5))
812
+ xp_assert_close(res.f_x, xp.asarray(f(root), dtype=xp.float64),
814
813
  rtol=1e-8, atol=2e-3)
815
814
  xp_assert_equal(res.nfev, xp.asarray(nfeval, dtype=xp.int32))
816
815
 
@@ -834,12 +833,12 @@ class TestChandrupatla(TestScalarRootFinders):
834
833
 
835
834
  a, b = xp.asarray(-3, dtype=dtype), xp.asarray(3, dtype=dtype)
836
835
  root = xp.asarray(root, dtype=dtype)
837
- res = _chandrupatla_root(f, a, b, args=(root,), xatol=1e-3)
836
+ res = find_root(f, (a, b), args=(root,), tolerances={'xatol': 1e-3})
838
837
  try:
839
838
  xp_assert_close(res.x, root, atol=1e-3)
840
839
  except AssertionError:
841
840
  assert res.x.dtype == dtype
842
- xp.all(res.fun == 0)
841
+ xp.all(res.f_x == 0)
843
842
 
844
843
  def test_input_validation(self, xp):
845
844
  # Test input validation for appropriate error messages
@@ -850,44 +849,44 @@ class TestChandrupatla(TestScalarRootFinders):
850
849
  message = '`func` must be callable.'
851
850
  with pytest.raises(ValueError, match=message):
852
851
  bracket = xp.asarray(-4), xp.asarray(4)
853
- _chandrupatla_root(None, *bracket)
852
+ find_root(None, bracket)
854
853
 
855
854
  message = 'Abscissae and function output must be real numbers.'
856
855
  with pytest.raises(ValueError, match=message):
857
856
  bracket = xp.asarray(-4+1j), xp.asarray(4)
858
- _chandrupatla_root(func, *bracket)
857
+ find_root(func, bracket)
859
858
 
860
859
  # raised by `np.broadcast, but the traceback is readable IMO
861
860
  message = "...not be broadcast..." # all messages include this part
862
861
  with pytest.raises((ValueError, RuntimeError), match=message):
863
862
  bracket = xp.asarray([-2, -3]), xp.asarray([3, 4, 5])
864
- _chandrupatla_root(func, *bracket)
863
+ find_root(func, bracket)
865
864
 
866
865
  message = "The shape of the array returned by `func`..."
867
866
  with pytest.raises(ValueError, match=message):
868
867
  bracket = xp.asarray([-3, -3]), xp.asarray([5, 5])
869
- _chandrupatla_root(lambda x: [x[0], x[1], x[1]], *bracket)
868
+ find_root(lambda x: [x[0], x[1], x[1]], bracket)
870
869
 
871
870
  message = 'Tolerances must be non-negative scalars.'
872
871
  bracket = xp.asarray(-4), xp.asarray(4)
873
872
  with pytest.raises(ValueError, match=message):
874
- _chandrupatla_root(func, *bracket, xatol=-1)
873
+ find_root(func, bracket, tolerances=dict(xatol=-1))
875
874
  with pytest.raises(ValueError, match=message):
876
- _chandrupatla_root(func, *bracket, xrtol=xp.nan)
875
+ find_root(func, bracket, tolerances=dict(xrtol=xp.nan))
877
876
  with pytest.raises(ValueError, match=message):
878
- _chandrupatla_root(func, *bracket, fatol='ekki')
877
+ find_root(func, bracket, tolerances=dict(fatol='ekki'))
879
878
  with pytest.raises(ValueError, match=message):
880
- _chandrupatla_root(func, *bracket, frtol=xp.nan)
879
+ find_root(func, bracket, tolerances=dict(frtol=xp.nan))
881
880
 
882
881
  message = '`maxiter` must be a non-negative integer.'
883
882
  with pytest.raises(ValueError, match=message):
884
- _chandrupatla_root(func, *bracket, maxiter=1.5)
883
+ find_root(func, bracket, maxiter=1.5)
885
884
  with pytest.raises(ValueError, match=message):
886
- _chandrupatla_root(func, *bracket, maxiter=-1)
885
+ find_root(func, bracket, maxiter=-1)
887
886
 
888
887
  message = '`callback` must be callable.'
889
888
  with pytest.raises(ValueError, match=message):
890
- _chandrupatla_root(func, *bracket, callback='shrubbery')
889
+ find_root(func, bracket, callback='shrubbery')
891
890
 
892
891
  def test_special_cases(self, xp):
893
892
  # Test edge cases and other special cases
@@ -899,21 +898,20 @@ class TestChandrupatla(TestScalarRootFinders):
899
898
  a, b = xp.asarray([0.1, 0., 0., 0.1]), xp.asarray([0.9, 1.0, 0.9, 1.0])
900
899
 
901
900
  with np.errstate(divide='ignore', invalid='ignore'):
902
- res = _chandrupatla_root(f, a, b)
901
+ res = find_root(f, (a, b))
903
902
 
904
903
  assert xp.all(res.success)
905
904
  xp_assert_close(res.x[1:], xp.full((3,), res.x[0]))
906
905
 
907
906
  # Test that integers are not passed to `f`
908
907
  # (otherwise this would overflow)
909
- xp_test = array_namespace(a) # need isdtype
910
908
  def f(x):
911
- assert xp_test.isdtype(x.dtype, "real floating")
909
+ assert xp.isdtype(x.dtype, "real floating")
912
910
  # this would overflow if x were an xp integer dtype
913
911
  return x ** 31 - 1
914
912
 
915
913
  # note that all inputs are integer type; result is automatically default float
916
- res = _chandrupatla_root(f, xp.asarray(-7), xp.asarray(5))
914
+ res = find_root(f, (xp.asarray(-7), xp.asarray(5)))
917
915
  assert res.success
918
916
  xp_assert_close(res.x, xp.asarray(1.))
919
917
 
@@ -923,7 +921,7 @@ class TestChandrupatla(TestScalarRootFinders):
923
921
  return x**2 - root
924
922
 
925
923
  root = xp.asarray([0, 1])
926
- res = _chandrupatla_root(f, xp.asarray(1), xp.asarray(1), args=(root,))
924
+ res = find_root(f, (xp.asarray(1), xp.asarray(1)), args=(root,))
927
925
  xp_assert_equal(res.success, xp.asarray([False, True]))
928
926
  xp_assert_equal(res.x, xp.asarray([xp.nan, 1.]))
929
927
 
@@ -932,7 +930,7 @@ class TestChandrupatla(TestScalarRootFinders):
932
930
 
933
931
  with np.errstate(invalid='ignore'):
934
932
  inf = xp.asarray(xp.inf)
935
- res = _chandrupatla_root(f, inf, inf)
933
+ res = find_root(f, (inf, inf))
936
934
  assert res.success
937
935
  xp_assert_equal(res.x, xp.asarray(xp.inf))
938
936
 
@@ -941,21 +939,21 @@ class TestChandrupatla(TestScalarRootFinders):
941
939
  return x**3 - 1
942
940
 
943
941
  a, b = xp.asarray(-3.), xp.asarray(5.)
944
- res = _chandrupatla_root(f, a, b, maxiter=0)
942
+ res = find_root(f, (a, b), maxiter=0)
945
943
  xp_assert_equal(res.success, xp.asarray(False))
946
944
  xp_assert_equal(res.status, xp.asarray(-2, dtype=xp.int32))
947
945
  xp_assert_equal(res.nit, xp.asarray(0, dtype=xp.int32))
948
946
  xp_assert_equal(res.nfev, xp.asarray(2, dtype=xp.int32))
949
- xp_assert_equal(res.xl, a)
950
- xp_assert_equal(res.xr, b)
947
+ xp_assert_equal(res.bracket[0], a)
948
+ xp_assert_equal(res.bracket[1], b)
951
949
  # The `x` attribute is the one with the smaller function value
952
950
  xp_assert_equal(res.x, a)
953
951
  # Reverse bracket; check that this is still true
954
- res = _chandrupatla_root(f, -b, -a, maxiter=0)
952
+ res = find_root(f, (-b, -a), maxiter=0)
955
953
  xp_assert_equal(res.x, -a)
956
954
 
957
955
  # Test maxiter = 1
958
- res = _chandrupatla_root(f, a, b, maxiter=1)
956
+ res = find_root(f, (a, b), maxiter=1)
959
957
  xp_assert_equal(res.success, xp.asarray(True))
960
958
  xp_assert_equal(res.status, xp.asarray(0, dtype=xp.int32))
961
959
  xp_assert_equal(res.nit, xp.asarray(1, dtype=xp.int32))
@@ -966,7 +964,7 @@ class TestChandrupatla(TestScalarRootFinders):
966
964
  def f(x, c):
967
965
  return c*x - 1
968
966
 
969
- res = _chandrupatla_root(f, xp.asarray(-1), xp.asarray(1), args=xp.asarray(3))
967
+ res = find_root(f, (xp.asarray(-1), xp.asarray(1)), args=xp.asarray(3))
970
968
  xp_assert_close(res.x, xp.asarray(1/3))
971
969
 
972
970
  # # TODO: Test zero tolerance