scipy 1.15.2__cp313-cp313-musllinux_1_2_aarch64.whl → 1.16.0rc1__cp313-cp313-musllinux_1_2_aarch64.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 (649) hide show
  1. scipy/__config__.py +11 -11
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-313-aarch64-linux-musl.so +0 -0
  4. scipy/_lib/_array_api.py +497 -161
  5. scipy/_lib/_array_api_compat_vendor.py +9 -0
  6. scipy/_lib/_bunch.py +4 -0
  7. scipy/_lib/_ccallback_c.cpython-313-aarch64-linux-musl.so +0 -0
  8. scipy/_lib/_docscrape.py +1 -1
  9. scipy/_lib/_elementwise_iterative_method.py +15 -26
  10. scipy/_lib/_fpumode.cpython-313-aarch64-linux-musl.so +0 -0
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_ccallback.cpython-313-aarch64-linux-musl.so +0 -0
  13. scipy/_lib/_test_deprecation_call.cpython-313-aarch64-linux-musl.so +0 -0
  14. scipy/_lib/_test_deprecation_def.cpython-313-aarch64-linux-musl.so +0 -0
  15. scipy/_lib/_testutils.py +6 -2
  16. scipy/_lib/_uarray/_uarray.cpython-313-aarch64-linux-musl.so +0 -0
  17. scipy/_lib/_util.py +222 -125
  18. scipy/_lib/array_api_compat/__init__.py +4 -4
  19. scipy/_lib/array_api_compat/_internal.py +19 -6
  20. scipy/_lib/array_api_compat/common/__init__.py +1 -1
  21. scipy/_lib/array_api_compat/common/_aliases.py +365 -193
  22. scipy/_lib/array_api_compat/common/_fft.py +94 -64
  23. scipy/_lib/array_api_compat/common/_helpers.py +413 -180
  24. scipy/_lib/array_api_compat/common/_linalg.py +116 -40
  25. scipy/_lib/array_api_compat/common/_typing.py +179 -10
  26. scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
  27. scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
  28. scipy/_lib/array_api_compat/cupy/_info.py +16 -6
  29. scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
  30. scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
  31. scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
  32. scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
  33. scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
  34. scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
  35. scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
  36. scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
  37. scipy/_lib/array_api_compat/numpy/_info.py +36 -16
  38. scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
  39. scipy/_lib/array_api_compat/numpy/fft.py +11 -5
  40. scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
  41. scipy/_lib/array_api_compat/torch/__init__.py +3 -5
  42. scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
  43. scipy/_lib/array_api_compat/torch/_info.py +27 -16
  44. scipy/_lib/array_api_compat/torch/_typing.py +3 -0
  45. scipy/_lib/array_api_compat/torch/fft.py +17 -18
  46. scipy/_lib/array_api_compat/torch/linalg.py +16 -16
  47. scipy/_lib/array_api_extra/__init__.py +26 -3
  48. scipy/_lib/array_api_extra/_delegation.py +171 -0
  49. scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
  50. scipy/_lib/array_api_extra/_lib/_at.py +463 -0
  51. scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
  52. scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
  53. scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
  54. scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
  55. scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
  56. scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
  57. scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
  58. scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
  59. scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
  60. scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
  61. scipy/_lib/array_api_extra/testing.py +359 -0
  62. scipy/_lib/decorator.py +2 -2
  63. scipy/_lib/doccer.py +1 -7
  64. scipy/_lib/messagestream.cpython-313-aarch64-linux-musl.so +0 -0
  65. scipy/_lib/pyprima/__init__.py +212 -0
  66. scipy/_lib/pyprima/cobyla/__init__.py +0 -0
  67. scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
  68. scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
  69. scipy/_lib/pyprima/cobyla/geometry.py +226 -0
  70. scipy/_lib/pyprima/cobyla/initialize.py +215 -0
  71. scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
  72. scipy/_lib/pyprima/cobyla/update.py +289 -0
  73. scipy/_lib/pyprima/common/__init__.py +0 -0
  74. scipy/_lib/pyprima/common/_bounds.py +34 -0
  75. scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
  76. scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
  77. scipy/_lib/pyprima/common/_project.py +173 -0
  78. scipy/_lib/pyprima/common/checkbreak.py +93 -0
  79. scipy/_lib/pyprima/common/consts.py +47 -0
  80. scipy/_lib/pyprima/common/evaluate.py +99 -0
  81. scipy/_lib/pyprima/common/history.py +38 -0
  82. scipy/_lib/pyprima/common/infos.py +30 -0
  83. scipy/_lib/pyprima/common/linalg.py +435 -0
  84. scipy/_lib/pyprima/common/message.py +290 -0
  85. scipy/_lib/pyprima/common/powalg.py +131 -0
  86. scipy/_lib/pyprima/common/preproc.py +277 -0
  87. scipy/_lib/pyprima/common/present.py +5 -0
  88. scipy/_lib/pyprima/common/ratio.py +54 -0
  89. scipy/_lib/pyprima/common/redrho.py +47 -0
  90. scipy/_lib/pyprima/common/selectx.py +296 -0
  91. scipy/_lib/tests/test__util.py +105 -121
  92. scipy/_lib/tests/test_array_api.py +169 -34
  93. scipy/_lib/tests/test_bunch.py +7 -0
  94. scipy/_lib/tests/test_ccallback.py +2 -10
  95. scipy/_lib/tests/test_public_api.py +13 -0
  96. scipy/cluster/_hierarchy.cpython-313-aarch64-linux-musl.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-313-aarch64-linux-musl.so +0 -0
  98. scipy/cluster/_vq.cpython-313-aarch64-linux-musl.so +0 -0
  99. scipy/cluster/hierarchy.py +393 -223
  100. scipy/cluster/tests/test_hierarchy.py +273 -335
  101. scipy/cluster/tests/test_vq.py +45 -61
  102. scipy/cluster/vq.py +39 -35
  103. scipy/conftest.py +263 -157
  104. scipy/constants/_constants.py +4 -1
  105. scipy/constants/tests/test_codata.py +2 -2
  106. scipy/constants/tests/test_constants.py +11 -18
  107. scipy/datasets/_download_all.py +15 -1
  108. scipy/datasets/_fetchers.py +7 -1
  109. scipy/datasets/_utils.py +1 -1
  110. scipy/differentiate/_differentiate.py +25 -25
  111. scipy/differentiate/tests/test_differentiate.py +24 -25
  112. scipy/fft/_basic.py +20 -0
  113. scipy/fft/_helper.py +3 -34
  114. scipy/fft/_pocketfft/helper.py +29 -1
  115. scipy/fft/_pocketfft/pypocketfft.cpython-313-aarch64-linux-musl.so +0 -0
  116. scipy/fft/_pocketfft/tests/test_basic.py +2 -4
  117. scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
  118. scipy/fft/_realtransforms.py +13 -0
  119. scipy/fft/tests/test_basic.py +27 -25
  120. scipy/fft/tests/test_fftlog.py +16 -7
  121. scipy/fft/tests/test_helper.py +18 -34
  122. scipy/fft/tests/test_real_transforms.py +8 -10
  123. scipy/fftpack/convolve.cpython-313-aarch64-linux-musl.so +0 -0
  124. scipy/fftpack/tests/test_basic.py +2 -4
  125. scipy/fftpack/tests/test_real_transforms.py +8 -9
  126. scipy/integrate/_bvp.py +9 -3
  127. scipy/integrate/_cubature.py +3 -2
  128. scipy/integrate/_dop.cpython-313-aarch64-linux-musl.so +0 -0
  129. scipy/integrate/_ivp/common.py +3 -3
  130. scipy/integrate/_ivp/ivp.py +9 -2
  131. scipy/integrate/_ivp/tests/test_ivp.py +19 -0
  132. scipy/integrate/_lsoda.cpython-313-aarch64-linux-musl.so +0 -0
  133. scipy/integrate/_ode.py +9 -2
  134. scipy/integrate/_odepack.cpython-313-aarch64-linux-musl.so +0 -0
  135. scipy/integrate/_quad_vec.py +21 -29
  136. scipy/integrate/_quadpack.cpython-313-aarch64-linux-musl.so +0 -0
  137. scipy/integrate/_quadpack_py.py +11 -7
  138. scipy/integrate/_quadrature.py +3 -3
  139. scipy/integrate/_rules/_base.py +2 -2
  140. scipy/integrate/_tanhsinh.py +57 -54
  141. scipy/integrate/_test_multivariate.cpython-313-aarch64-linux-musl.so +0 -0
  142. scipy/integrate/_test_odeint_banded.cpython-313-aarch64-linux-musl.so +0 -0
  143. scipy/integrate/_vode.cpython-313-aarch64-linux-musl.so +0 -0
  144. scipy/integrate/tests/test__quad_vec.py +0 -6
  145. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  146. scipy/integrate/tests/test_cubature.py +21 -35
  147. scipy/integrate/tests/test_quadrature.py +6 -8
  148. scipy/integrate/tests/test_tanhsinh.py +61 -43
  149. scipy/interpolate/__init__.py +70 -58
  150. scipy/interpolate/_bary_rational.py +22 -22
  151. scipy/interpolate/_bsplines.py +119 -66
  152. scipy/interpolate/_cubic.py +65 -50
  153. scipy/interpolate/_dfitpack.cpython-313-aarch64-linux-musl.so +0 -0
  154. scipy/interpolate/_dierckx.cpython-313-aarch64-linux-musl.so +0 -0
  155. scipy/interpolate/_fitpack.cpython-313-aarch64-linux-musl.so +0 -0
  156. scipy/interpolate/_fitpack2.py +9 -6
  157. scipy/interpolate/_fitpack_impl.py +32 -26
  158. scipy/interpolate/_fitpack_repro.py +23 -19
  159. scipy/interpolate/_interpnd.cpython-313-aarch64-linux-musl.so +0 -0
  160. scipy/interpolate/_interpolate.py +30 -12
  161. scipy/interpolate/_ndbspline.py +13 -18
  162. scipy/interpolate/_ndgriddata.py +5 -8
  163. scipy/interpolate/_polyint.py +95 -31
  164. scipy/interpolate/_ppoly.cpython-313-aarch64-linux-musl.so +0 -0
  165. scipy/interpolate/_rbf.py +2 -2
  166. scipy/interpolate/_rbfinterp.py +1 -1
  167. scipy/interpolate/_rbfinterp_pythran.cpython-313-aarch64-linux-musl.so +0 -0
  168. scipy/interpolate/_rgi.py +31 -26
  169. scipy/interpolate/_rgi_cython.cpython-313-aarch64-linux-musl.so +0 -0
  170. scipy/interpolate/dfitpack.py +0 -20
  171. scipy/interpolate/interpnd.py +1 -2
  172. scipy/interpolate/tests/test_bary_rational.py +2 -2
  173. scipy/interpolate/tests/test_bsplines.py +97 -1
  174. scipy/interpolate/tests/test_fitpack2.py +39 -1
  175. scipy/interpolate/tests/test_interpnd.py +32 -20
  176. scipy/interpolate/tests/test_interpolate.py +48 -4
  177. scipy/interpolate/tests/test_rgi.py +2 -1
  178. scipy/io/_fast_matrix_market/__init__.py +2 -0
  179. scipy/io/_fast_matrix_market/_fmm_core.cpython-313-aarch64-linux-musl.so +0 -0
  180. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  181. scipy/io/_harwell_boeing/hb.py +7 -11
  182. scipy/io/_idl.py +5 -7
  183. scipy/io/_netcdf.py +15 -5
  184. scipy/io/_test_fortran.cpython-313-aarch64-linux-musl.so +0 -0
  185. scipy/io/arff/tests/test_arffread.py +3 -3
  186. scipy/io/matlab/__init__.py +5 -3
  187. scipy/io/matlab/_mio.py +4 -1
  188. scipy/io/matlab/_mio5.py +19 -13
  189. scipy/io/matlab/_mio5_utils.cpython-313-aarch64-linux-musl.so +0 -0
  190. scipy/io/matlab/_mio_utils.cpython-313-aarch64-linux-musl.so +0 -0
  191. scipy/io/matlab/_miobase.py +4 -1
  192. scipy/io/matlab/_streams.cpython-313-aarch64-linux-musl.so +0 -0
  193. scipy/io/matlab/tests/test_mio.py +46 -18
  194. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  195. scipy/io/tests/test_mmio.py +7 -1
  196. scipy/io/tests/test_wavfile.py +41 -0
  197. scipy/io/wavfile.py +57 -10
  198. scipy/linalg/_basic.py +113 -86
  199. scipy/linalg/_cythonized_array_utils.cpython-313-aarch64-linux-musl.so +0 -0
  200. scipy/linalg/_decomp.py +22 -9
  201. scipy/linalg/_decomp_cholesky.py +28 -13
  202. scipy/linalg/_decomp_cossin.py +45 -30
  203. scipy/linalg/_decomp_interpolative.cpython-313-aarch64-linux-musl.so +0 -0
  204. scipy/linalg/_decomp_ldl.py +4 -1
  205. scipy/linalg/_decomp_lu.py +18 -6
  206. scipy/linalg/_decomp_lu_cython.cpython-313-aarch64-linux-musl.so +0 -0
  207. scipy/linalg/_decomp_polar.py +2 -0
  208. scipy/linalg/_decomp_qr.py +6 -2
  209. scipy/linalg/_decomp_qz.py +3 -0
  210. scipy/linalg/_decomp_schur.py +3 -1
  211. scipy/linalg/_decomp_svd.py +13 -2
  212. scipy/linalg/_decomp_update.cpython-313-aarch64-linux-musl.so +0 -0
  213. scipy/linalg/_expm_frechet.py +4 -0
  214. scipy/linalg/_fblas.cpython-313-aarch64-linux-musl.so +0 -0
  215. scipy/linalg/_flapack.cpython-313-aarch64-linux-musl.so +0 -0
  216. scipy/linalg/_linalg_pythran.cpython-313-aarch64-linux-musl.so +0 -0
  217. scipy/linalg/_matfuncs.py +187 -4
  218. scipy/linalg/_matfuncs_expm.cpython-313-aarch64-linux-musl.so +0 -0
  219. scipy/linalg/_matfuncs_schur_sqrtm.cpython-313-aarch64-linux-musl.so +0 -0
  220. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  221. scipy/linalg/_matfuncs_sqrtm_triu.cpython-313-aarch64-linux-musl.so +0 -0
  222. scipy/linalg/_procrustes.py +2 -0
  223. scipy/linalg/_sketches.py +17 -6
  224. scipy/linalg/_solve_toeplitz.cpython-313-aarch64-linux-musl.so +0 -0
  225. scipy/linalg/_solvers.py +7 -2
  226. scipy/linalg/_special_matrices.py +26 -36
  227. scipy/linalg/cython_blas.cpython-313-aarch64-linux-musl.so +0 -0
  228. scipy/linalg/cython_lapack.cpython-313-aarch64-linux-musl.so +0 -0
  229. scipy/linalg/lapack.py +22 -2
  230. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  231. scipy/linalg/tests/test_basic.py +31 -16
  232. scipy/linalg/tests/test_batch.py +588 -0
  233. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  234. scipy/linalg/tests/test_decomp.py +40 -3
  235. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  236. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  237. scipy/linalg/tests/test_interpolative.py +17 -0
  238. scipy/linalg/tests/test_lapack.py +115 -7
  239. scipy/linalg/tests/test_matfuncs.py +157 -102
  240. scipy/linalg/tests/test_procrustes.py +0 -7
  241. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  242. scipy/linalg/tests/test_special_matrices.py +1 -5
  243. scipy/ndimage/__init__.py +1 -0
  244. scipy/ndimage/_ctest.cpython-313-aarch64-linux-musl.so +0 -0
  245. scipy/ndimage/_cytest.cpython-313-aarch64-linux-musl.so +0 -0
  246. scipy/ndimage/_delegators.py +8 -2
  247. scipy/ndimage/_filters.py +433 -5
  248. scipy/ndimage/_interpolation.py +36 -6
  249. scipy/ndimage/_measurements.py +4 -2
  250. scipy/ndimage/_morphology.py +5 -0
  251. scipy/ndimage/_nd_image.cpython-313-aarch64-linux-musl.so +0 -0
  252. scipy/ndimage/_ndimage_api.py +2 -1
  253. scipy/ndimage/_ni_docstrings.py +5 -1
  254. scipy/ndimage/_ni_label.cpython-313-aarch64-linux-musl.so +0 -0
  255. scipy/ndimage/_ni_support.py +1 -5
  256. scipy/ndimage/_rank_filter_1d.cpython-313-aarch64-linux-musl.so +0 -0
  257. scipy/ndimage/_support_alternative_backends.py +18 -6
  258. scipy/ndimage/tests/test_filters.py +351 -259
  259. scipy/ndimage/tests/test_fourier.py +7 -9
  260. scipy/ndimage/tests/test_interpolation.py +68 -61
  261. scipy/ndimage/tests/test_measurements.py +18 -35
  262. scipy/ndimage/tests/test_morphology.py +143 -131
  263. scipy/ndimage/tests/test_splines.py +1 -3
  264. scipy/odr/__odrpack.cpython-313-aarch64-linux-musl.so +0 -0
  265. scipy/optimize/_basinhopping.py +13 -7
  266. scipy/optimize/_bglu_dense.cpython-313-aarch64-linux-musl.so +0 -0
  267. scipy/optimize/_bracket.py +46 -26
  268. scipy/optimize/_chandrupatla.py +9 -10
  269. scipy/optimize/_cobyla_py.py +104 -123
  270. scipy/optimize/_constraints.py +14 -10
  271. scipy/optimize/_differentiable_functions.py +371 -230
  272. scipy/optimize/_differentialevolution.py +4 -3
  273. scipy/optimize/_direct.cpython-313-aarch64-linux-musl.so +0 -0
  274. scipy/optimize/_dual_annealing.py +1 -1
  275. scipy/optimize/_elementwise.py +1 -4
  276. scipy/optimize/_group_columns.cpython-313-aarch64-linux-musl.so +0 -0
  277. scipy/optimize/_highspy/_core.cpython-313-aarch64-linux-musl.so +0 -0
  278. scipy/optimize/_highspy/_highs_options.cpython-313-aarch64-linux-musl.so +0 -0
  279. scipy/optimize/_highspy/_highs_wrapper.py +6 -4
  280. scipy/optimize/_lbfgsb.cpython-313-aarch64-linux-musl.so +0 -0
  281. scipy/optimize/_lbfgsb_py.py +57 -16
  282. scipy/optimize/_linprog_doc.py +2 -2
  283. scipy/optimize/_linprog_highs.py +11 -11
  284. scipy/optimize/_linprog_ip.py +25 -10
  285. scipy/optimize/_linprog_util.py +18 -19
  286. scipy/optimize/_lsap.cpython-313-aarch64-linux-musl.so +0 -0
  287. scipy/optimize/_lsq/common.py +3 -3
  288. scipy/optimize/_lsq/dogbox.py +16 -2
  289. scipy/optimize/_lsq/givens_elimination.cpython-313-aarch64-linux-musl.so +0 -0
  290. scipy/optimize/_lsq/least_squares.py +198 -126
  291. scipy/optimize/_lsq/lsq_linear.py +6 -6
  292. scipy/optimize/_lsq/trf.py +35 -8
  293. scipy/optimize/_milp.py +3 -1
  294. scipy/optimize/_minimize.py +105 -36
  295. scipy/optimize/_minpack.cpython-313-aarch64-linux-musl.so +0 -0
  296. scipy/optimize/_minpack_py.py +21 -14
  297. scipy/optimize/_moduleTNC.cpython-313-aarch64-linux-musl.so +0 -0
  298. scipy/optimize/_nnls.py +20 -21
  299. scipy/optimize/_nonlin.py +34 -3
  300. scipy/optimize/_numdiff.py +288 -110
  301. scipy/optimize/_optimize.py +86 -48
  302. scipy/optimize/_pava_pybind.cpython-313-aarch64-linux-musl.so +0 -0
  303. scipy/optimize/_remove_redundancy.py +5 -5
  304. scipy/optimize/_root_scalar.py +1 -1
  305. scipy/optimize/_shgo.py +6 -0
  306. scipy/optimize/_shgo_lib/_complex.py +1 -1
  307. scipy/optimize/_slsqp_py.py +216 -124
  308. scipy/optimize/_slsqplib.cpython-313-aarch64-linux-musl.so +0 -0
  309. scipy/optimize/_spectral.py +1 -1
  310. scipy/optimize/_tnc.py +8 -1
  311. scipy/optimize/_trlib/_trlib.cpython-313-aarch64-linux-musl.so +0 -0
  312. scipy/optimize/_trustregion.py +20 -6
  313. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  314. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  315. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  316. scipy/optimize/_trustregion_constr/projections.py +12 -8
  317. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  318. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  319. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  320. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  321. scipy/optimize/_trustregion_exact.py +0 -1
  322. scipy/optimize/_zeros.cpython-313-aarch64-linux-musl.so +0 -0
  323. scipy/optimize/_zeros_py.py +97 -17
  324. scipy/optimize/cython_optimize/_zeros.cpython-313-aarch64-linux-musl.so +0 -0
  325. scipy/optimize/slsqp.py +0 -1
  326. scipy/optimize/tests/test__basinhopping.py +1 -1
  327. scipy/optimize/tests/test__differential_evolution.py +4 -4
  328. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  329. scipy/optimize/tests/test__numdiff.py +66 -22
  330. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  331. scipy/optimize/tests/test__shgo.py +9 -1
  332. scipy/optimize/tests/test_bracket.py +71 -46
  333. scipy/optimize/tests/test_chandrupatla.py +133 -135
  334. scipy/optimize/tests/test_cobyla.py +74 -45
  335. scipy/optimize/tests/test_constraints.py +1 -1
  336. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  337. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  338. scipy/optimize/tests/test_least_squares.py +125 -13
  339. scipy/optimize/tests/test_linear_assignment.py +3 -3
  340. scipy/optimize/tests/test_linprog.py +3 -3
  341. scipy/optimize/tests/test_lsq_linear.py +5 -5
  342. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  343. scipy/optimize/tests/test_minpack.py +4 -4
  344. scipy/optimize/tests/test_nnls.py +43 -3
  345. scipy/optimize/tests/test_nonlin.py +36 -0
  346. scipy/optimize/tests/test_optimize.py +95 -17
  347. scipy/optimize/tests/test_slsqp.py +36 -4
  348. scipy/optimize/tests/test_zeros.py +34 -1
  349. scipy/signal/__init__.py +12 -23
  350. scipy/signal/_delegators.py +568 -0
  351. scipy/signal/_filter_design.py +459 -241
  352. scipy/signal/_fir_filter_design.py +262 -90
  353. scipy/signal/_lti_conversion.py +3 -2
  354. scipy/signal/_ltisys.py +118 -91
  355. scipy/signal/_max_len_seq_inner.cpython-313-aarch64-linux-musl.so +0 -0
  356. scipy/signal/_peak_finding_utils.cpython-313-aarch64-linux-musl.so +0 -0
  357. scipy/signal/_polyutils.py +172 -0
  358. scipy/signal/_short_time_fft.py +553 -76
  359. scipy/signal/_signal_api.py +30 -0
  360. scipy/signal/_signaltools.py +719 -396
  361. scipy/signal/_sigtools.cpython-313-aarch64-linux-musl.so +0 -0
  362. scipy/signal/_sosfilt.cpython-313-aarch64-linux-musl.so +0 -0
  363. scipy/signal/_spectral_py.py +221 -50
  364. scipy/signal/_spline.cpython-313-aarch64-linux-musl.so +0 -0
  365. scipy/signal/_spline_filters.py +108 -68
  366. scipy/signal/_support_alternative_backends.py +73 -0
  367. scipy/signal/_upfirdn.py +4 -1
  368. scipy/signal/_upfirdn_apply.cpython-313-aarch64-linux-musl.so +0 -0
  369. scipy/signal/_waveforms.py +2 -11
  370. scipy/signal/_wavelets.py +1 -1
  371. scipy/signal/fir_filter_design.py +1 -0
  372. scipy/signal/spline.py +4 -11
  373. scipy/signal/tests/_scipy_spectral_test_shim.py +5 -182
  374. scipy/signal/tests/test_bsplines.py +114 -79
  375. scipy/signal/tests/test_cont2discrete.py +9 -2
  376. scipy/signal/tests/test_filter_design.py +721 -481
  377. scipy/signal/tests/test_fir_filter_design.py +332 -140
  378. scipy/signal/tests/test_savitzky_golay.py +4 -3
  379. scipy/signal/tests/test_short_time_fft.py +231 -5
  380. scipy/signal/tests/test_signaltools.py +2149 -1348
  381. scipy/signal/tests/test_spectral.py +19 -6
  382. scipy/signal/tests/test_splines.py +161 -96
  383. scipy/signal/tests/test_upfirdn.py +84 -50
  384. scipy/signal/tests/test_waveforms.py +20 -0
  385. scipy/signal/tests/test_windows.py +607 -466
  386. scipy/signal/windows/_windows.py +287 -148
  387. scipy/sparse/__init__.py +23 -4
  388. scipy/sparse/_base.py +269 -120
  389. scipy/sparse/_bsr.py +7 -4
  390. scipy/sparse/_compressed.py +59 -234
  391. scipy/sparse/_construct.py +90 -38
  392. scipy/sparse/_coo.py +115 -181
  393. scipy/sparse/_csc.py +4 -4
  394. scipy/sparse/_csparsetools.cpython-313-aarch64-linux-musl.so +0 -0
  395. scipy/sparse/_csr.py +2 -2
  396. scipy/sparse/_data.py +48 -48
  397. scipy/sparse/_dia.py +105 -21
  398. scipy/sparse/_dok.py +0 -23
  399. scipy/sparse/_index.py +4 -4
  400. scipy/sparse/_matrix.py +23 -0
  401. scipy/sparse/_sparsetools.cpython-313-aarch64-linux-musl.so +0 -0
  402. scipy/sparse/_sputils.py +37 -22
  403. scipy/sparse/base.py +0 -9
  404. scipy/sparse/bsr.py +0 -14
  405. scipy/sparse/compressed.py +0 -23
  406. scipy/sparse/construct.py +0 -6
  407. scipy/sparse/coo.py +0 -14
  408. scipy/sparse/csc.py +0 -3
  409. scipy/sparse/csgraph/_flow.cpython-313-aarch64-linux-musl.so +0 -0
  410. scipy/sparse/csgraph/_matching.cpython-313-aarch64-linux-musl.so +0 -0
  411. scipy/sparse/csgraph/_min_spanning_tree.cpython-313-aarch64-linux-musl.so +0 -0
  412. scipy/sparse/csgraph/_reordering.cpython-313-aarch64-linux-musl.so +0 -0
  413. scipy/sparse/csgraph/_shortest_path.cpython-313-aarch64-linux-musl.so +0 -0
  414. scipy/sparse/csgraph/_tools.cpython-313-aarch64-linux-musl.so +0 -0
  415. scipy/sparse/csgraph/_traversal.cpython-313-aarch64-linux-musl.so +0 -0
  416. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  417. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  418. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  419. scipy/sparse/csr.py +0 -5
  420. scipy/sparse/data.py +1 -6
  421. scipy/sparse/dia.py +0 -7
  422. scipy/sparse/dok.py +0 -10
  423. scipy/sparse/linalg/_dsolve/_superlu.cpython-313-aarch64-linux-musl.so +0 -0
  424. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  425. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  426. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-313-aarch64-linux-musl.so +0 -0
  427. scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
  428. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  429. scipy/sparse/linalg/_expm_multiply.py +8 -3
  430. scipy/sparse/linalg/_interface.py +29 -26
  431. scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
  432. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  433. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  434. scipy/sparse/linalg/_isolve/minres.py +5 -5
  435. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  436. scipy/sparse/linalg/_isolve/utils.py +2 -8
  437. scipy/sparse/linalg/_matfuncs.py +1 -1
  438. scipy/sparse/linalg/_norm.py +1 -1
  439. scipy/sparse/linalg/_propack/_cpropack.cpython-313-aarch64-linux-musl.so +0 -0
  440. scipy/sparse/linalg/_propack/_dpropack.cpython-313-aarch64-linux-musl.so +0 -0
  441. scipy/sparse/linalg/_propack/_spropack.cpython-313-aarch64-linux-musl.so +0 -0
  442. scipy/sparse/linalg/_propack/_zpropack.cpython-313-aarch64-linux-musl.so +0 -0
  443. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  444. scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
  445. scipy/sparse/linalg/tests/test_interface.py +35 -0
  446. scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
  447. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  448. scipy/sparse/tests/test_base.py +217 -40
  449. scipy/sparse/tests/test_common1d.py +17 -12
  450. scipy/sparse/tests/test_construct.py +1 -1
  451. scipy/sparse/tests/test_coo.py +272 -4
  452. scipy/sparse/tests/test_sparsetools.py +5 -0
  453. scipy/sparse/tests/test_sputils.py +36 -7
  454. scipy/spatial/_ckdtree.cpython-313-aarch64-linux-musl.so +0 -0
  455. scipy/spatial/_distance_pybind.cpython-313-aarch64-linux-musl.so +0 -0
  456. scipy/spatial/_distance_wrap.cpython-313-aarch64-linux-musl.so +0 -0
  457. scipy/spatial/_hausdorff.cpython-313-aarch64-linux-musl.so +0 -0
  458. scipy/spatial/_qhull.cpython-313-aarch64-linux-musl.so +0 -0
  459. scipy/spatial/_voronoi.cpython-313-aarch64-linux-musl.so +0 -0
  460. scipy/spatial/distance.py +49 -42
  461. scipy/spatial/tests/test_distance.py +3 -1
  462. scipy/spatial/tests/test_kdtree.py +1 -0
  463. scipy/spatial/tests/test_qhull.py +106 -2
  464. scipy/spatial/transform/__init__.py +5 -3
  465. scipy/spatial/transform/_rigid_transform.cpython-313-aarch64-linux-musl.so +0 -0
  466. scipy/spatial/transform/_rotation.cpython-313-aarch64-linux-musl.so +0 -0
  467. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  468. scipy/spatial/transform/tests/test_rotation.py +1342 -790
  469. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  470. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  471. scipy/special/__init__.py +1 -47
  472. scipy/special/_add_newdocs.py +34 -772
  473. scipy/special/_basic.py +22 -25
  474. scipy/special/_comb.cpython-313-aarch64-linux-musl.so +0 -0
  475. scipy/special/_ellip_harm_2.cpython-313-aarch64-linux-musl.so +0 -0
  476. scipy/special/_gufuncs.cpython-313-aarch64-linux-musl.so +0 -0
  477. scipy/special/_logsumexp.py +83 -69
  478. scipy/special/_orthogonal.pyi +1 -1
  479. scipy/special/_specfun.cpython-313-aarch64-linux-musl.so +0 -0
  480. scipy/special/_special_ufuncs.cpython-313-aarch64-linux-musl.so +0 -0
  481. scipy/special/_spherical_bessel.py +4 -4
  482. scipy/special/_support_alternative_backends.py +212 -119
  483. scipy/special/_test_internal.cpython-313-aarch64-linux-musl.so +0 -0
  484. scipy/special/_testutils.py +4 -4
  485. scipy/special/_ufuncs.cpython-313-aarch64-linux-musl.so +0 -0
  486. scipy/special/_ufuncs.pyi +1 -0
  487. scipy/special/_ufuncs.pyx +215 -1400
  488. scipy/special/_ufuncs_cxx.cpython-313-aarch64-linux-musl.so +0 -0
  489. scipy/special/_ufuncs_cxx.pxd +2 -15
  490. scipy/special/_ufuncs_cxx.pyx +5 -44
  491. scipy/special/_ufuncs_cxx_defs.h +2 -16
  492. scipy/special/_ufuncs_defs.h +0 -8
  493. scipy/special/cython_special.cpython-313-aarch64-linux-musl.so +0 -0
  494. scipy/special/cython_special.pxd +1 -1
  495. scipy/special/tests/_cython_examples/meson.build +10 -1
  496. scipy/special/tests/test_basic.py +153 -20
  497. scipy/special/tests/test_boost_ufuncs.py +3 -0
  498. scipy/special/tests/test_cdflib.py +35 -11
  499. scipy/special/tests/test_gammainc.py +16 -0
  500. scipy/special/tests/test_hyp2f1.py +23 -2
  501. scipy/special/tests/test_log1mexp.py +85 -0
  502. scipy/special/tests/test_logsumexp.py +220 -64
  503. scipy/special/tests/test_mpmath.py +1 -0
  504. scipy/special/tests/test_nan_inputs.py +1 -1
  505. scipy/special/tests/test_orthogonal.py +17 -18
  506. scipy/special/tests/test_sf_error.py +3 -2
  507. scipy/special/tests/test_sph_harm.py +6 -7
  508. scipy/special/tests/test_support_alternative_backends.py +211 -76
  509. scipy/stats/__init__.py +4 -1
  510. scipy/stats/_ansari_swilk_statistics.cpython-313-aarch64-linux-musl.so +0 -0
  511. scipy/stats/_axis_nan_policy.py +4 -3
  512. scipy/stats/_biasedurn.cpython-313-aarch64-linux-musl.so +0 -0
  513. scipy/stats/_continued_fraction.py +387 -0
  514. scipy/stats/_continuous_distns.py +296 -319
  515. scipy/stats/_covariance.py +6 -3
  516. scipy/stats/_discrete_distns.py +39 -32
  517. scipy/stats/_distn_infrastructure.py +39 -12
  518. scipy/stats/_distribution_infrastructure.py +900 -238
  519. scipy/stats/_entropy.py +7 -8
  520. scipy/{_lib → stats}/_finite_differences.py +1 -1
  521. scipy/stats/_hypotests.py +82 -49
  522. scipy/stats/_kde.py +53 -49
  523. scipy/stats/_ksstats.py +1 -1
  524. scipy/stats/_levy_stable/__init__.py +7 -15
  525. scipy/stats/_levy_stable/levyst.cpython-313-aarch64-linux-musl.so +0 -0
  526. scipy/stats/_morestats.py +112 -67
  527. scipy/stats/_mstats_basic.py +13 -17
  528. scipy/stats/_mstats_extras.py +8 -8
  529. scipy/stats/_multivariate.py +89 -113
  530. scipy/stats/_new_distributions.py +97 -20
  531. scipy/stats/_page_trend_test.py +12 -5
  532. scipy/stats/_probability_distribution.py +265 -43
  533. scipy/stats/_qmc.py +14 -9
  534. scipy/stats/_qmc_cy.cpython-313-aarch64-linux-musl.so +0 -0
  535. scipy/stats/_qmvnt.py +16 -95
  536. scipy/stats/_qmvnt_cy.cpython-313-aarch64-linux-musl.so +0 -0
  537. scipy/stats/_quantile.py +335 -0
  538. scipy/stats/_rcont/rcont.cpython-313-aarch64-linux-musl.so +0 -0
  539. scipy/stats/_resampling.py +4 -29
  540. scipy/stats/_sampling.py +1 -1
  541. scipy/stats/_sobol.cpython-313-aarch64-linux-musl.so +0 -0
  542. scipy/stats/_stats.cpython-313-aarch64-linux-musl.so +0 -0
  543. scipy/stats/_stats_mstats_common.py +19 -2
  544. scipy/stats/_stats_py.py +534 -460
  545. scipy/stats/_stats_pythran.cpython-313-aarch64-linux-musl.so +0 -0
  546. scipy/stats/_unuran/unuran_wrapper.cpython-313-aarch64-linux-musl.so +0 -0
  547. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  548. scipy/stats/_variation.py +5 -7
  549. scipy/stats/_wilcoxon.py +13 -7
  550. scipy/stats/tests/common_tests.py +6 -4
  551. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  552. scipy/stats/tests/test_continued_fraction.py +173 -0
  553. scipy/stats/tests/test_continuous.py +379 -60
  554. scipy/stats/tests/test_continuous_basic.py +18 -12
  555. scipy/stats/tests/test_discrete_basic.py +14 -8
  556. scipy/stats/tests/test_discrete_distns.py +16 -16
  557. scipy/stats/tests/test_distributions.py +117 -75
  558. scipy/stats/tests/test_entropy.py +40 -48
  559. scipy/stats/tests/test_fit.py +4 -3
  560. scipy/stats/tests/test_hypotests.py +153 -24
  561. scipy/stats/tests/test_kdeoth.py +109 -41
  562. scipy/stats/tests/test_marray.py +289 -0
  563. scipy/stats/tests/test_morestats.py +79 -47
  564. scipy/stats/tests/test_mstats_basic.py +3 -3
  565. scipy/stats/tests/test_multivariate.py +434 -83
  566. scipy/stats/tests/test_qmc.py +13 -10
  567. scipy/stats/tests/test_quantile.py +199 -0
  568. scipy/stats/tests/test_rank.py +119 -112
  569. scipy/stats/tests/test_resampling.py +47 -56
  570. scipy/stats/tests/test_sampling.py +9 -4
  571. scipy/stats/tests/test_stats.py +799 -939
  572. scipy/stats/tests/test_variation.py +8 -6
  573. scipy/version.py +2 -2
  574. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
  575. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +9 -9
  576. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +1316 -1323
  577. scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
  578. scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
  579. scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
  580. scipy/_lib/array_api_extra/_funcs.py +0 -484
  581. scipy/_lib/array_api_extra/_typing.py +0 -8
  582. scipy/interpolate/_bspl.cpython-313-aarch64-linux-musl.so +0 -0
  583. scipy/optimize/_cobyla.cpython-313-aarch64-linux-musl.so +0 -0
  584. scipy/optimize/_cython_nnls.cpython-313-aarch64-linux-musl.so +0 -0
  585. scipy/optimize/_slsqp.cpython-313-aarch64-linux-musl.so +0 -0
  586. scipy/spatial/qhull_src/COPYING.txt +0 -38
  587. scipy/special/libsf_error_state.so +0 -0
  588. scipy/special/tests/test_log_softmax.py +0 -109
  589. scipy/special/tests/test_xsf_cuda.py +0 -114
  590. scipy/special/xsf/binom.h +0 -89
  591. scipy/special/xsf/cdflib.h +0 -100
  592. scipy/special/xsf/cephes/airy.h +0 -307
  593. scipy/special/xsf/cephes/besselpoly.h +0 -51
  594. scipy/special/xsf/cephes/beta.h +0 -257
  595. scipy/special/xsf/cephes/cbrt.h +0 -131
  596. scipy/special/xsf/cephes/chbevl.h +0 -85
  597. scipy/special/xsf/cephes/chdtr.h +0 -193
  598. scipy/special/xsf/cephes/const.h +0 -87
  599. scipy/special/xsf/cephes/ellie.h +0 -293
  600. scipy/special/xsf/cephes/ellik.h +0 -251
  601. scipy/special/xsf/cephes/ellpe.h +0 -107
  602. scipy/special/xsf/cephes/ellpk.h +0 -117
  603. scipy/special/xsf/cephes/expn.h +0 -260
  604. scipy/special/xsf/cephes/gamma.h +0 -398
  605. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  606. scipy/special/xsf/cephes/hyperg.h +0 -361
  607. scipy/special/xsf/cephes/i0.h +0 -149
  608. scipy/special/xsf/cephes/i1.h +0 -158
  609. scipy/special/xsf/cephes/igam.h +0 -421
  610. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  611. scipy/special/xsf/cephes/igami.h +0 -313
  612. scipy/special/xsf/cephes/j0.h +0 -225
  613. scipy/special/xsf/cephes/j1.h +0 -198
  614. scipy/special/xsf/cephes/jv.h +0 -715
  615. scipy/special/xsf/cephes/k0.h +0 -164
  616. scipy/special/xsf/cephes/k1.h +0 -163
  617. scipy/special/xsf/cephes/kn.h +0 -243
  618. scipy/special/xsf/cephes/lanczos.h +0 -112
  619. scipy/special/xsf/cephes/ndtr.h +0 -275
  620. scipy/special/xsf/cephes/poch.h +0 -85
  621. scipy/special/xsf/cephes/polevl.h +0 -167
  622. scipy/special/xsf/cephes/psi.h +0 -194
  623. scipy/special/xsf/cephes/rgamma.h +0 -111
  624. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  625. scipy/special/xsf/cephes/shichi.h +0 -248
  626. scipy/special/xsf/cephes/sici.h +0 -224
  627. scipy/special/xsf/cephes/sindg.h +0 -221
  628. scipy/special/xsf/cephes/tandg.h +0 -139
  629. scipy/special/xsf/cephes/trig.h +0 -58
  630. scipy/special/xsf/cephes/unity.h +0 -186
  631. scipy/special/xsf/cephes/zeta.h +0 -172
  632. scipy/special/xsf/config.h +0 -304
  633. scipy/special/xsf/digamma.h +0 -205
  634. scipy/special/xsf/error.h +0 -57
  635. scipy/special/xsf/evalpoly.h +0 -47
  636. scipy/special/xsf/expint.h +0 -266
  637. scipy/special/xsf/hyp2f1.h +0 -694
  638. scipy/special/xsf/iv_ratio.h +0 -173
  639. scipy/special/xsf/lambertw.h +0 -150
  640. scipy/special/xsf/loggamma.h +0 -163
  641. scipy/special/xsf/sici.h +0 -200
  642. scipy/special/xsf/tools.h +0 -427
  643. scipy/special/xsf/trig.h +0 -164
  644. scipy/special/xsf/wright_bessel.h +0 -843
  645. scipy/special/xsf/zlog1.h +0 -35
  646. scipy/stats/_mvn.cpython-313-aarch64-linux-musl.so +0 -0
  647. scipy.libs/libgcc_s-7393e603.so.1 +0 -0
  648. scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
  649. {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/WHEEL +0 -0
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
- from typing import (overload, Callable, NamedTuple, Protocol)
2
+ from typing import (overload, NamedTuple, Protocol)
3
+ from collections.abc import Callable
3
4
  import numpy.typing as npt
4
5
  from scipy._lib._util import SeedType
5
6
  import scipy.stats as stats
scipy/stats/_variation.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from scipy._lib._util import _get_nan
4
- from scipy._lib._array_api import array_namespace, xp_copysign
4
+ from scipy._lib._array_api import array_namespace
5
5
 
6
6
  from ._axis_nan_policy import _axis_nan_policy_factory
7
7
 
@@ -103,22 +103,20 @@ def variation(a, axis=0, nan_policy='propagate', ddof=0, *, keepdims=False):
103
103
  axis = 0
104
104
 
105
105
  n = a.shape[axis]
106
- NaN = _get_nan(a)
107
106
 
108
107
  if a.size == 0 or ddof > n:
109
108
  # Handle as a special case to avoid spurious warnings.
110
109
  # The return values, if any, are all nan.
111
- shp = list(a.shape)
112
- shp.pop(axis)
113
- result = xp.full(shp, fill_value=NaN)
114
- return result[()] if result.ndim == 0 else result
110
+ shape = list(a.shape)
111
+ shape.pop(axis)
112
+ return _get_nan(a, shape=tuple(shape), xp=xp)
115
113
 
116
114
  mean_a = xp.mean(a, axis=axis)
117
115
 
118
116
  if ddof == n:
119
117
  # Another special case. Result is either inf or nan.
120
118
  std_a = xp.std(a, axis=axis, correction=0)
121
- result = xp.where(std_a > 0, xp_copysign(xp.asarray(xp.inf), mean_a), NaN)
119
+ result = xp.where(std_a > 0, xp.copysign(xp.inf, mean_a), xp.nan)
122
120
  return result[()] if result.ndim == 0 else result
123
121
 
124
122
  with np.errstate(divide='ignore', invalid='ignore'):
scipy/stats/_wilcoxon.py CHANGED
@@ -5,7 +5,8 @@ from ._stats_py import _get_pvalue, _rankdata, _SimpleNormal
5
5
  from . import _morestats
6
6
  from ._axis_nan_policy import _broadcast_arrays
7
7
  from ._hypotests import _get_wilcoxon_distr
8
- from scipy._lib._util import _lazywhere, _get_nan
8
+ from scipy._lib._util import _get_nan
9
+ import scipy._lib.array_api_extra as xpx
9
10
 
10
11
 
11
12
  class WilcoxonDistribution:
@@ -40,13 +41,17 @@ class WilcoxonDistribution:
40
41
 
41
42
  def cdf(self, k):
42
43
  k, mn, out = self._prep(k)
43
- return _lazywhere(k <= mn, (k, self.n), self._cdf,
44
- f2=lambda k, n: 1 - self._sf(k+1, n))[()]
44
+ return xpx.apply_where(
45
+ k <= mn, (k, self.n),
46
+ self._cdf,
47
+ lambda k, n: 1 - self._sf(k+1, n))[()]
45
48
 
46
49
  def sf(self, k):
47
50
  k, mn, out = self._prep(k)
48
- return _lazywhere(k <= mn, (k, self.n), self._sf,
49
- f2=lambda k, n: 1 - self._cdf(k-1, n))[()]
51
+ return xpx.apply_where(
52
+ k <= mn, (k, self.n),
53
+ self._sf,
54
+ lambda k, n: 1 - self._cdf(k-1, n))[()]
50
55
 
51
56
 
52
57
  def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
@@ -57,6 +62,7 @@ def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
57
62
  raise ValueError(message)
58
63
 
59
64
  message = '`axis` must be compatible with the shape(s) of `x` (and `y`)'
65
+ AxisError = getattr(np, 'AxisError', None) or np.exceptions.AxisError
60
66
  try:
61
67
  if y is None:
62
68
  x = np.asarray(x)
@@ -65,8 +71,8 @@ def _wilcoxon_iv(x, y, zero_method, correction, alternative, method, axis):
65
71
  x, y = _broadcast_arrays((x, y), axis=axis)
66
72
  d = x - y
67
73
  d = np.moveaxis(d, axis, -1)
68
- except np.AxisError as e:
69
- raise ValueError(message) from e
74
+ except AxisError as e:
75
+ raise AxisError(message) from e
70
76
 
71
77
  message = "`x` and `y` must have the same length along `axis`."
72
78
  if y is not None and x.shape[axis] != y.shape[axis]:
@@ -344,11 +344,13 @@ def check_freezing(distfn, args):
344
344
 
345
345
 
346
346
  def check_rvs_broadcast(distfunc, distname, allargs, shape, shape_only, otype):
347
- np.random.seed(123)
348
- sample = distfunc.rvs(*allargs)
347
+ rng = np.random.RandomState(123)
348
+ sample = distfunc.rvs(*allargs, random_state=rng)
349
349
  assert_equal(sample.shape, shape, f"{distname}: rvs failed to broadcast")
350
350
  if not shape_only:
351
- rvs = np.vectorize(lambda *allargs: distfunc.rvs(*allargs), otypes=otype)
352
- np.random.seed(123)
351
+ rvs = np.vectorize(
352
+ lambda *allargs: distfunc.rvs(*allargs, random_state=rng),
353
+ otypes=otype)
354
+ rng = np.random.RandomState(123)
353
355
  expected = rvs(*allargs)
354
356
  assert_allclose(sample, expected, rtol=1e-13)
@@ -56,11 +56,23 @@ def xp_var(*args, **kwargs):
56
56
  return stats._stats_py._xp_var(*args, **kwargs)
57
57
 
58
58
 
59
+ def gstd(*args, **kwargs):
60
+ kwargs.pop('_no_deco', None)
61
+ return stats.gstd(*args, **kwargs)
62
+
63
+
59
64
  def combine_pvalues_weighted(*args, **kwargs):
60
65
  return stats.combine_pvalues(args[0], *args[2:], weights=args[1],
61
66
  method='stouffer', **kwargs)
62
67
 
63
68
 
69
+ def weightedtau_weighted(x, y, rank, **kwargs):
70
+ axis = kwargs.get('axis', 0)
71
+ nan_policy = kwargs.get('nan_policy', 'propagate')
72
+ rank = stats.rankdata(rank, axis=axis, nan_policy=nan_policy)
73
+ return stats.weightedtau(x, y, rank, **kwargs)
74
+
75
+
64
76
  axis_nan_policy_cases = [
65
77
  # function, args, kwds, number of samples, number of outputs,
66
78
  # ... paired, unpacker function
@@ -133,6 +145,7 @@ axis_nan_policy_cases = [
133
145
  (stats.circvar, tuple(), dict(), 1, 1, False, lambda x: (x,)),
134
146
  (stats.circstd, tuple(), dict(), 1, 1, False, lambda x: (x,)),
135
147
  (stats.f_oneway, tuple(), {}, 2, 2, False, None),
148
+ (stats.f_oneway, tuple(), {'equal_var': False}, 2, 2, False, None),
136
149
  (stats.alexandergovern, tuple(), {}, 2, 2, False,
137
150
  lambda res: (res.statistic, res.pvalue)),
138
151
  (stats.combine_pvalues, tuple(), {}, 1, 2, False, None),
@@ -143,6 +156,24 @@ axis_nan_policy_cases = [
143
156
  (xp_var, tuple(), dict(), 1, 1, False, lambda x: (x,)),
144
157
  (stats.chatterjeexi, tuple(), dict(), 2, 2, True,
145
158
  lambda res: (res.statistic, res.pvalue)),
159
+ (stats.pointbiserialr, tuple(), dict(), 2, 3, True,
160
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
161
+ (stats.kendalltau, tuple(), dict(), 2, 3, True,
162
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
163
+ (stats.weightedtau, tuple(), dict(), 2, 3, True,
164
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
165
+ (weightedtau_weighted, tuple(), dict(), 3, 3, True,
166
+ lambda res: (res.statistic, res.pvalue, res.correlation)),
167
+ (stats.linregress, tuple(), dict(), 2, 6, True,
168
+ lambda res: tuple(res) + (res.intercept_stderr,)),
169
+ (stats.theilslopes, tuple(), dict(), 2, 4, True, tuple),
170
+ (stats.theilslopes, tuple(), dict(), 1, 4, True, tuple),
171
+ (stats.siegelslopes, tuple(), dict(), 2, 2, True, tuple),
172
+ (stats.siegelslopes, tuple(), dict(), 1, 2, True, tuple),
173
+ (gstd, tuple(), dict(), 1, 1, False, lambda x: (x,)),
174
+ (stats.power_divergence, tuple(), dict(), 1, 2, False, None),
175
+ (stats.chisquare, tuple(), dict(), 1, 2, False, None),
176
+ (stats._morestats._boxcox_llf, tuple(), dict(lmb=1.5), 1, 1, False, lambda x: (x,)),
146
177
  ]
147
178
 
148
179
  # If the message is one of those expected, put nans in
@@ -175,6 +206,9 @@ too_small_messages = {"Degrees of freedom <= 0 for slice",
175
206
  "One or more sample arguments is too small",
176
207
  "invalid value encountered",
177
208
  "divide by zero encountered",
209
+ "`x` and `y` must have length at least 2.",
210
+ "Inputs must not be empty.",
211
+ "All `x` coordinates are identical.",
178
212
  }
179
213
 
180
214
  # If the message is one of these, results of the function may be inaccurate,
@@ -183,13 +217,13 @@ inaccuracy_messages = {"Precision loss occurred in moment calculation",
183
217
  "Sample size too small for normal approximation."}
184
218
 
185
219
  # For some functions, nan_policy='propagate' should not just return NaNs
186
- override_propagate_funcs = {stats.mode}
220
+ override_propagate_funcs = {stats.mode, weightedtau_weighted, stats.weightedtau}
187
221
 
188
222
  # For some functions, empty arrays produce non-NaN results
189
- empty_special_case_funcs = {stats.entropy}
223
+ empty_special_case_funcs = {stats.entropy, stats.chisquare, stats.power_divergence}
190
224
 
191
225
  # Some functions don't follow the usual "too small" warning rules
192
- too_small_special_case_funcs = {stats.entropy}
226
+ too_small_special_case_funcs = {stats.entropy, stats.chisquare, stats.power_divergence}
193
227
 
194
228
  def _mixed_data_generator(n_samples, n_repetitions, axis, rng,
195
229
  paired=False):
@@ -301,6 +335,7 @@ def nan_policy_1d(hypotest, data1d, unpacker, *args, n_outputs=2,
301
335
  @pytest.mark.parametrize(("nan_policy"), ("propagate", "omit", "raise"))
302
336
  @pytest.mark.parametrize(("axis"), (1,))
303
337
  @pytest.mark.parametrize(("data_generator"), ("mixed",))
338
+ @pytest.mark.parallel_threads(1)
304
339
  def test_axis_nan_policy_fast(hypotest, args, kwds, n_samples, n_outputs,
305
340
  paired, unpacker, nan_policy, axis,
306
341
  data_generator):
@@ -413,7 +448,7 @@ def _axis_nan_policy_test(hypotest, args, kwds, n_samples, n_outputs, paired,
413
448
  n_outputs=n_outputs,
414
449
  nan_policy=nan_policy,
415
450
  paired=paired, _no_deco=True, **kwds)
416
- except (ValueError, RuntimeWarning, ZeroDivisionError) as ea:
451
+ except (ValueError, RuntimeWarning, ZeroDivisionError, UserWarning) as ea:
417
452
  ea_str = str(ea)
418
453
  if any([str(ea_str).startswith(msg) for msg in too_small_messages]):
419
454
  res_1da = np.full(n_outputs, np.nan)
@@ -472,6 +507,7 @@ def _axis_nan_policy_test(hypotest, args, kwds, n_samples, n_outputs, paired,
472
507
  @pytest.mark.parametrize(("nan_policy"), ("propagate", "omit", "raise"))
473
508
  @pytest.mark.parametrize(("data_generator"),
474
509
  ("all_nans", "all_finite", "mixed", "empty"))
510
+ @pytest.mark.parallel_threads(1)
475
511
  def test_axis_nan_policy_axis_is_None(hypotest, args, kwds, n_samples,
476
512
  n_outputs, paired, unpacker, nan_policy,
477
513
  data_generator):
@@ -524,7 +560,7 @@ def test_axis_nan_policy_axis_is_None(hypotest, args, kwds, n_samples,
524
560
  res1da = nan_policy_1d(hypotest, data_raveled, unpacker, *args,
525
561
  n_outputs=n_outputs, nan_policy=nan_policy,
526
562
  paired=paired, _no_deco=True, **kwds)
527
- except (RuntimeWarning, ValueError, ZeroDivisionError) as ea:
563
+ except (RuntimeWarning, ValueError, ZeroDivisionError, UserWarning) as ea:
528
564
  res1da = None
529
565
  ea_str = str(ea)
530
566
 
@@ -594,6 +630,8 @@ def test_keepdims(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker,
594
630
  stats.differential_entropy}
595
631
  if sample_shape == (2, 3, 3, 4) and hypotest in small_sample_raises:
596
632
  pytest.skip("Sample too small; test raises error.")
633
+ if hypotest in {weightedtau_weighted}:
634
+ pytest.skip("`rankdata` used in testing doesn't support axis tuple.")
597
635
  # test if keepdims parameter works correctly
598
636
  if not unpacker:
599
637
  def unpacker(res):
@@ -787,6 +825,7 @@ def _check_arrays_broadcastable(arrays, axis):
787
825
  @pytest.mark.slow
788
826
  @pytest.mark.parametrize(("hypotest", "args", "kwds", "n_samples", "n_outputs",
789
827
  "paired", "unpacker"), axis_nan_policy_cases)
828
+ @pytest.mark.parallel_threads(1)
790
829
  def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
791
830
  # test for correct output shape when at least one input is empty
792
831
  if hypotest in {stats.kruskal, stats.friedmanchisquare} and not SCIPY_XSLOW:
@@ -834,15 +873,16 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
834
873
  sup.filter(RuntimeWarning, "Mean of empty slice.")
835
874
  sup.filter(RuntimeWarning, "invalid value encountered")
836
875
  expected = np.mean(concat, axis=axis) * np.nan
876
+ mask = np.isnan(expected)
877
+ expected = [np.asarray(expected.copy()) for i in range(n_outputs)]
837
878
 
838
879
  if hypotest in empty_special_case_funcs:
839
880
  empty_val = hypotest(*([[]]*len(samples)), *args, **kwds)
840
- expected = np.asarray(expected)
841
- mask = np.isnan(expected)
842
- expected[mask] = empty_val
843
- expected = expected[()]
881
+ empty_val = list(unpacker(empty_val))
882
+ for i in range(n_outputs):
883
+ expected[i][mask] = empty_val[i]
844
884
 
845
- if expected.size and hypotest not in too_small_special_case_funcs:
885
+ if expected[0].size and hypotest not in too_small_special_case_funcs:
846
886
  message = (too_small_1d_not_omit if max_axis == 1
847
887
  else too_small_nd_not_omit)
848
888
  with pytest.warns(SmallSampleWarning, match=message):
@@ -855,7 +895,7 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
855
895
  res = unpacker(res)
856
896
 
857
897
  for i in range(n_outputs):
858
- assert_equal(res[i], expected)
898
+ assert_equal(res[i], expected[i])
859
899
 
860
900
  except ValueError:
861
901
  # confirm that the arrays truly are not broadcastable
@@ -872,22 +912,21 @@ def test_empty(hypotest, args, kwds, n_samples, n_outputs, paired, unpacker):
872
912
 
873
913
 
874
914
  def paired_non_broadcastable_cases():
875
- rng = np.random.default_rng(91359824598245)
876
915
  for case in axis_nan_policy_cases:
877
916
  hypotest, args, kwds, n_samples, n_outputs, paired, unpacker = case
878
917
  if n_samples == 1: # broadcasting only needed with >1 sample
879
918
  continue
880
- yield case + (rng,)
919
+ yield case
881
920
 
882
921
 
883
922
  @pytest.mark.parametrize("axis", [0, 1])
884
923
  @pytest.mark.parametrize(("hypotest", "args", "kwds", "n_samples", "n_outputs",
885
- "paired", "unpacker", "rng"),
924
+ "paired", "unpacker"),
886
925
  paired_non_broadcastable_cases())
887
926
  def test_non_broadcastable(hypotest, args, kwds, n_samples, n_outputs, paired,
888
- unpacker, rng, axis):
927
+ unpacker, axis):
889
928
  # test for correct error message when shapes are not broadcastable
890
-
929
+ rng = np.random.default_rng(91359824598245)
891
930
  get_samples = True
892
931
  while get_samples:
893
932
  samples = [rng.random(size=rng.integers(2, 100, size=2))
@@ -913,7 +952,6 @@ def test_non_broadcastable(hypotest, args, kwds, n_samples, n_outputs, paired,
913
952
  with pytest.raises(ValueError, match=message):
914
953
  hypotest(other_sample, *most_samples, *args, **kwds)
915
954
 
916
-
917
955
  def test_masked_array_2_sentinel_array():
918
956
  # prepare arrays
919
957
  np.random.seed(0)
@@ -1078,13 +1116,13 @@ def test_mixed_mask_nan_1():
1078
1116
  m, n = 3, 20
1079
1117
  axis = -1
1080
1118
 
1081
- np.random.seed(0)
1082
- a = np.random.rand(m, n)
1083
- b = np.random.rand(m, n)
1084
- mask_a1 = np.random.rand(m, n) < 0.2
1085
- mask_a2 = np.random.rand(m, n) < 0.1
1086
- mask_b1 = np.random.rand(m, n) < 0.15
1087
- mask_b2 = np.random.rand(m, n) < 0.15
1119
+ rng = np.random.RandomState(0)
1120
+ a = rng.rand(m, n)
1121
+ b = rng.rand(m, n)
1122
+ mask_a1 = rng.rand(m, n) < 0.2
1123
+ mask_a2 = rng.rand(m, n) < 0.1
1124
+ mask_b1 = rng.rand(m, n) < 0.15
1125
+ mask_b2 = rng.rand(m, n) < 0.15
1088
1126
  mask_a1[2, :] = True
1089
1127
 
1090
1128
  a_nans = a.copy()
@@ -0,0 +1,173 @@
1
+ import math
2
+
3
+ import pytest
4
+ import numpy as np
5
+
6
+ from scipy._lib._array_api import array_namespace
7
+ from scipy._lib._array_api_no_0d import xp_assert_close, xp_assert_less, xp_assert_equal
8
+ from scipy.stats._continued_fraction import _continued_fraction
9
+
10
+
11
+ @pytest.mark.skip_xp_backends('array_api_strict', reason='No fancy indexing assignment')
12
+ @pytest.mark.skip_xp_backends('jax.numpy', reason="Don't support mutation")
13
+ # dask doesn't like lines like this
14
+ # n = int(xp.real(xp_ravel(n))[0])
15
+ # (at some point in here the shape becomes nan)
16
+ @pytest.mark.skip_xp_backends('dask.array', reason="dask has issues with the shapes")
17
+ class TestContinuedFraction:
18
+ rng = np.random.default_rng(5895448232066142650)
19
+ p = rng.uniform(1, 10, size=10)
20
+
21
+ def a1(self, n, x=1.5):
22
+ if n == 0:
23
+ y = 0*x
24
+ elif n == 1:
25
+ y = x
26
+ else:
27
+ y = -x**2
28
+ if np.isscalar(y) and np.__version__ < "2.0":
29
+ y = np.full_like(x, y) # preserve dtype pre NEP 50
30
+ return y
31
+
32
+ def b1(self, n, x=1.5):
33
+ if n == 0:
34
+ y = 0*x
35
+ else:
36
+ one = x/x # gets array of correct type, dtype, and shape
37
+ y = one * (2*n - 1)
38
+ if np.isscalar(y) and np.__version__ < "2.0":
39
+ y = np.full_like(x, y) # preserve dtype pre NEP 50
40
+ return y
41
+
42
+ def log_a1(self, n, x):
43
+ xp = array_namespace(x)
44
+ if n == 0:
45
+ y = xp.full_like(x, -xp.asarray(math.inf, dtype=x.dtype))
46
+ elif n == 1:
47
+ y = xp.log(x)
48
+ else:
49
+ y = 2 * xp.log(x) + math.pi * 1j
50
+ return y
51
+
52
+ def log_b1(self, n, x):
53
+ xp = array_namespace(x)
54
+ if n == 0:
55
+ y = xp.full_like(x, -xp.asarray(math.inf, dtype=x.dtype))
56
+ else:
57
+ one = x - x # gets array of correct type, dtype, and shape
58
+ y = one + math.log(2 * n - 1)
59
+ return y
60
+
61
+ def test_input_validation(self, xp):
62
+ a1 = self.a1
63
+ b1 = self.b1
64
+
65
+ message = '`a` and `b` must be callable.'
66
+ with pytest.raises(ValueError, match=message):
67
+ _continued_fraction(1, b1)
68
+ with pytest.raises(ValueError, match=message):
69
+ _continued_fraction(a1, 1)
70
+
71
+ message = r'`eps` and `tiny` must be \(or represent the logarithm of\)...'
72
+ with pytest.raises(ValueError, match=message):
73
+ _continued_fraction(a1, b1, tolerances={'eps': -10})
74
+ with pytest.raises(ValueError, match=message):
75
+ _continued_fraction(a1, b1, tolerances={'eps': np.nan})
76
+ with pytest.raises(ValueError, match=message):
77
+ _continued_fraction(a1, b1, tolerances={'eps': 1+1j}, log=True)
78
+ with pytest.raises(ValueError, match=message):
79
+ _continued_fraction(a1, b1, tolerances={'tiny': 0})
80
+ with pytest.raises(ValueError, match=message):
81
+ _continued_fraction(a1, b1, tolerances={'tiny': np.inf})
82
+ with pytest.raises(ValueError, match=message):
83
+ _continued_fraction(a1, b1, tolerances={'tiny': np.inf}, log=True)
84
+ # this should not raise
85
+ kwargs = dict(args=xp.asarray(1.5+0j), log=True, maxiter=0)
86
+ _continued_fraction(a1, b1, tolerances={'eps': -10}, **kwargs)
87
+ _continued_fraction(a1, b1, tolerances={'tiny': -10}, **kwargs)
88
+
89
+ message = '`maxiter` must be a non-negative integer.'
90
+ with pytest.raises(ValueError, match=message):
91
+ _continued_fraction(a1, b1, maxiter=-1)
92
+
93
+ message = '`log` must be boolean.'
94
+ with pytest.raises(ValueError, match=message):
95
+ _continued_fraction(a1, b1, log=2)
96
+
97
+ @pytest.mark.parametrize('dtype', ['float32', 'float64', 'complex64', 'complex128'])
98
+ @pytest.mark.parametrize('shape', [(), (1,), (3,), (3, 2)])
99
+ def test_basic(self, shape, dtype, xp):
100
+ np_dtype = getattr(np, dtype)
101
+ xp_dtype = getattr(xp, dtype)
102
+ rng = np.random.default_rng(2435908729190400)
103
+
104
+ x = rng.random(shape).astype(np_dtype)
105
+ x = x + rng.random(shape).astype(np_dtype)*1j if dtype.startswith('c') else x
106
+ x = xp.asarray(x, dtype=xp_dtype)
107
+
108
+ res = _continued_fraction(self.a1, self.b1, args=(x,))
109
+ ref = xp.tan(x)
110
+ xp_assert_close(res.f, ref)
111
+
112
+ @pytest.mark.skip_xp_backends('torch', reason='pytorch/pytorch#136063')
113
+ @pytest.mark.parametrize('dtype', ['float32', 'float64'])
114
+ @pytest.mark.parametrize('shape', [(), (1,), (3,), (3, 2)])
115
+ def test_log(self, shape, dtype, xp):
116
+ if (np.__version__ < "2") and (dtype == 'float32'):
117
+ pytest.skip("Scalar dtypes only respected after NEP 50.")
118
+ np_dtype = getattr(np, dtype)
119
+ rng = np.random.default_rng(2435908729190400)
120
+ x = rng.random(shape).astype(np_dtype)
121
+ x = xp.asarray(x)
122
+
123
+ res = _continued_fraction(self.log_a1, self.log_b1, args=(x + 0j,), log=True)
124
+ ref = xp.tan(x)
125
+ xp_assert_close(xp.exp(xp.real(res.f)), ref)
126
+
127
+ def test_maxiter(self, xp):
128
+ rng = np.random.default_rng(2435908729190400)
129
+ x = xp.asarray(rng.random(), dtype=xp.float64)
130
+ ref = xp.tan(x)
131
+
132
+ res1 = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=3)
133
+ assert res1.nit == 3
134
+
135
+ res2 = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=6)
136
+ assert res2.nit == 6
137
+
138
+ xp_assert_less(xp.abs(res2.f - ref), xp.abs(res1.f - ref))
139
+
140
+ def test_eps(self, xp):
141
+ x = xp.asarray(1.5, dtype=xp.float64) # x = 1.5 is the default defined above
142
+ ref = xp.tan(x)
143
+ res1 = _continued_fraction(self.a1, self.b1, args=(x,),
144
+ tolerances={'eps': 1e-6})
145
+ res2 = _continued_fraction(self.a1, self.b1, args=(x,))
146
+ xp_assert_less(res1.nit, res2.nit)
147
+ xp_assert_less(xp.abs(res2.f - ref), xp.abs(res1.f - ref))
148
+
149
+ def test_feval(self, xp):
150
+ def a(n, x):
151
+ a.nfev += 1
152
+ return n * x
153
+
154
+ def b(n, x):
155
+ b.nfev += 1
156
+ return n * x
157
+
158
+ a.nfev, b.nfev = 0, 0
159
+
160
+ res = _continued_fraction(a, b, args=(xp.asarray(1.),))
161
+ assert res.nfev == a.nfev == b.nfev == res.nit + 1
162
+
163
+ def test_status(self, xp):
164
+ x = xp.asarray([1, 10, np.nan], dtype=xp.float64)
165
+ res = _continued_fraction(self.a1, self.b1, args=(x,), maxiter=15)
166
+ xp_assert_equal(res.success, xp.asarray([True, False, False]))
167
+ xp_assert_equal(res.status, xp.asarray([0, -2, -3], dtype=xp.int32))
168
+
169
+ def test_special_cases(self, xp):
170
+ one = xp.asarray(1)
171
+ res = _continued_fraction(lambda x: one, lambda x: one, maxiter=0)
172
+ xp_assert_close(res.f, xp.asarray(1.))
173
+ assert res.nit == res.nfev - 1 == 0