scipy 1.15.3__cp312-cp312-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp312-cp312-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 (641) hide show
  1. scipy/__config__.py +10 -10
  2. scipy/__init__.py +3 -6
  3. scipy/_cyutility.cpython-312-aarch64-linux-musl.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-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-312-aarch64-linux-musl.so +0 -0
  11. scipy/_lib/_sparse.py +41 -0
  12. scipy/_lib/_test_ccallback.cpython-312-aarch64-linux-musl.so +0 -0
  13. scipy/_lib/_test_deprecation_call.cpython-312-aarch64-linux-musl.so +0 -0
  14. scipy/_lib/_test_deprecation_def.cpython-312-aarch64-linux-musl.so +0 -0
  15. scipy/_lib/_testutils.py +6 -2
  16. scipy/_lib/_uarray/_uarray.cpython-312-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-312-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 +166 -35
  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-312-aarch64-linux-musl.so +0 -0
  97. scipy/cluster/_optimal_leaf_ordering.cpython-312-aarch64-linux-musl.so +0 -0
  98. scipy/cluster/_vq.cpython-312-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-312-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-312-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-312-aarch64-linux-musl.so +0 -0
  129. scipy/integrate/_lsoda.cpython-312-aarch64-linux-musl.so +0 -0
  130. scipy/integrate/_ode.py +9 -2
  131. scipy/integrate/_odepack.cpython-312-aarch64-linux-musl.so +0 -0
  132. scipy/integrate/_quad_vec.py +21 -29
  133. scipy/integrate/_quadpack.cpython-312-aarch64-linux-musl.so +0 -0
  134. scipy/integrate/_quadpack_py.py +11 -7
  135. scipy/integrate/_quadrature.py +3 -3
  136. scipy/integrate/_rules/_base.py +2 -2
  137. scipy/integrate/_tanhsinh.py +48 -47
  138. scipy/integrate/_test_multivariate.cpython-312-aarch64-linux-musl.so +0 -0
  139. scipy/integrate/_test_odeint_banded.cpython-312-aarch64-linux-musl.so +0 -0
  140. scipy/integrate/_vode.cpython-312-aarch64-linux-musl.so +0 -0
  141. scipy/integrate/tests/test__quad_vec.py +0 -6
  142. scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
  143. scipy/integrate/tests/test_cubature.py +21 -35
  144. scipy/integrate/tests/test_quadrature.py +6 -8
  145. scipy/integrate/tests/test_tanhsinh.py +56 -48
  146. scipy/interpolate/__init__.py +70 -58
  147. scipy/interpolate/_bary_rational.py +22 -22
  148. scipy/interpolate/_bsplines.py +119 -66
  149. scipy/interpolate/_cubic.py +65 -50
  150. scipy/interpolate/_dfitpack.cpython-312-aarch64-linux-musl.so +0 -0
  151. scipy/interpolate/_dierckx.cpython-312-aarch64-linux-musl.so +0 -0
  152. scipy/interpolate/_fitpack.cpython-312-aarch64-linux-musl.so +0 -0
  153. scipy/interpolate/_fitpack2.py +9 -6
  154. scipy/interpolate/_fitpack_impl.py +32 -26
  155. scipy/interpolate/_fitpack_repro.py +23 -19
  156. scipy/interpolate/_interpnd.cpython-312-aarch64-linux-musl.so +0 -0
  157. scipy/interpolate/_interpolate.py +30 -12
  158. scipy/interpolate/_ndbspline.py +13 -18
  159. scipy/interpolate/_ndgriddata.py +5 -8
  160. scipy/interpolate/_polyint.py +95 -31
  161. scipy/interpolate/_ppoly.cpython-312-aarch64-linux-musl.so +0 -0
  162. scipy/interpolate/_rbf.py +2 -2
  163. scipy/interpolate/_rbfinterp.py +1 -1
  164. scipy/interpolate/_rbfinterp_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  165. scipy/interpolate/_rgi.py +31 -26
  166. scipy/interpolate/_rgi_cython.cpython-312-aarch64-linux-musl.so +0 -0
  167. scipy/interpolate/dfitpack.py +0 -20
  168. scipy/interpolate/interpnd.py +1 -2
  169. scipy/interpolate/tests/test_bary_rational.py +2 -2
  170. scipy/interpolate/tests/test_bsplines.py +97 -1
  171. scipy/interpolate/tests/test_fitpack2.py +39 -1
  172. scipy/interpolate/tests/test_interpnd.py +32 -20
  173. scipy/interpolate/tests/test_interpolate.py +48 -4
  174. scipy/interpolate/tests/test_rgi.py +2 -1
  175. scipy/io/_fast_matrix_market/__init__.py +2 -0
  176. scipy/io/_fast_matrix_market/_fmm_core.cpython-312-aarch64-linux-musl.so +0 -0
  177. scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
  178. scipy/io/_harwell_boeing/hb.py +7 -11
  179. scipy/io/_idl.py +5 -7
  180. scipy/io/_netcdf.py +15 -5
  181. scipy/io/_test_fortran.cpython-312-aarch64-linux-musl.so +0 -0
  182. scipy/io/arff/tests/test_arffread.py +3 -3
  183. scipy/io/matlab/__init__.py +5 -3
  184. scipy/io/matlab/_mio.py +4 -1
  185. scipy/io/matlab/_mio5.py +19 -13
  186. scipy/io/matlab/_mio5_utils.cpython-312-aarch64-linux-musl.so +0 -0
  187. scipy/io/matlab/_mio_utils.cpython-312-aarch64-linux-musl.so +0 -0
  188. scipy/io/matlab/_miobase.py +4 -1
  189. scipy/io/matlab/_streams.cpython-312-aarch64-linux-musl.so +0 -0
  190. scipy/io/matlab/tests/test_mio.py +46 -18
  191. scipy/io/matlab/tests/test_mio_funcs.py +1 -1
  192. scipy/io/tests/test_mmio.py +7 -1
  193. scipy/io/tests/test_wavfile.py +41 -0
  194. scipy/io/wavfile.py +57 -10
  195. scipy/linalg/_basic.py +113 -86
  196. scipy/linalg/_cythonized_array_utils.cpython-312-aarch64-linux-musl.so +0 -0
  197. scipy/linalg/_decomp.py +22 -9
  198. scipy/linalg/_decomp_cholesky.py +28 -13
  199. scipy/linalg/_decomp_cossin.py +45 -30
  200. scipy/linalg/_decomp_interpolative.cpython-312-aarch64-linux-musl.so +0 -0
  201. scipy/linalg/_decomp_ldl.py +4 -1
  202. scipy/linalg/_decomp_lu.py +18 -6
  203. scipy/linalg/_decomp_lu_cython.cpython-312-aarch64-linux-musl.so +0 -0
  204. scipy/linalg/_decomp_polar.py +2 -0
  205. scipy/linalg/_decomp_qr.py +6 -2
  206. scipy/linalg/_decomp_qz.py +3 -0
  207. scipy/linalg/_decomp_schur.py +3 -1
  208. scipy/linalg/_decomp_svd.py +13 -2
  209. scipy/linalg/_decomp_update.cpython-312-aarch64-linux-musl.so +0 -0
  210. scipy/linalg/_expm_frechet.py +4 -0
  211. scipy/linalg/_fblas.cpython-312-aarch64-linux-musl.so +0 -0
  212. scipy/linalg/_flapack.cpython-312-aarch64-linux-musl.so +0 -0
  213. scipy/linalg/_linalg_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  214. scipy/linalg/_matfuncs.py +187 -4
  215. scipy/linalg/_matfuncs_expm.cpython-312-aarch64-linux-musl.so +0 -0
  216. scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-aarch64-linux-musl.so +0 -0
  217. scipy/linalg/_matfuncs_sqrtm.py +1 -99
  218. scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-aarch64-linux-musl.so +0 -0
  219. scipy/linalg/_procrustes.py +2 -0
  220. scipy/linalg/_sketches.py +17 -6
  221. scipy/linalg/_solve_toeplitz.cpython-312-aarch64-linux-musl.so +0 -0
  222. scipy/linalg/_solvers.py +7 -2
  223. scipy/linalg/_special_matrices.py +26 -36
  224. scipy/linalg/cython_blas.cpython-312-aarch64-linux-musl.so +0 -0
  225. scipy/linalg/cython_lapack.cpython-312-aarch64-linux-musl.so +0 -0
  226. scipy/linalg/lapack.py +22 -2
  227. scipy/linalg/tests/_cython_examples/meson.build +7 -0
  228. scipy/linalg/tests/test_basic.py +31 -16
  229. scipy/linalg/tests/test_batch.py +588 -0
  230. scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
  231. scipy/linalg/tests/test_decomp.py +40 -3
  232. scipy/linalg/tests/test_decomp_cossin.py +14 -0
  233. scipy/linalg/tests/test_decomp_ldl.py +1 -1
  234. scipy/linalg/tests/test_lapack.py +115 -7
  235. scipy/linalg/tests/test_matfuncs.py +157 -102
  236. scipy/linalg/tests/test_procrustes.py +0 -7
  237. scipy/linalg/tests/test_solve_toeplitz.py +1 -1
  238. scipy/linalg/tests/test_special_matrices.py +1 -5
  239. scipy/ndimage/__init__.py +1 -0
  240. scipy/ndimage/_ctest.cpython-312-aarch64-linux-musl.so +0 -0
  241. scipy/ndimage/_cytest.cpython-312-aarch64-linux-musl.so +0 -0
  242. scipy/ndimage/_delegators.py +8 -2
  243. scipy/ndimage/_filters.py +453 -5
  244. scipy/ndimage/_interpolation.py +36 -6
  245. scipy/ndimage/_measurements.py +4 -2
  246. scipy/ndimage/_morphology.py +5 -0
  247. scipy/ndimage/_nd_image.cpython-312-aarch64-linux-musl.so +0 -0
  248. scipy/ndimage/_ni_docstrings.py +5 -1
  249. scipy/ndimage/_ni_label.cpython-312-aarch64-linux-musl.so +0 -0
  250. scipy/ndimage/_ni_support.py +1 -5
  251. scipy/ndimage/_rank_filter_1d.cpython-312-aarch64-linux-musl.so +0 -0
  252. scipy/ndimage/_support_alternative_backends.py +18 -6
  253. scipy/ndimage/tests/test_filters.py +370 -259
  254. scipy/ndimage/tests/test_fourier.py +7 -9
  255. scipy/ndimage/tests/test_interpolation.py +68 -61
  256. scipy/ndimage/tests/test_measurements.py +18 -35
  257. scipy/ndimage/tests/test_morphology.py +143 -131
  258. scipy/ndimage/tests/test_splines.py +1 -3
  259. scipy/odr/__odrpack.cpython-312-aarch64-linux-musl.so +0 -0
  260. scipy/optimize/_basinhopping.py +13 -7
  261. scipy/optimize/_bglu_dense.cpython-312-aarch64-linux-musl.so +0 -0
  262. scipy/optimize/_bracket.py +17 -24
  263. scipy/optimize/_chandrupatla.py +9 -10
  264. scipy/optimize/_cobyla_py.py +104 -123
  265. scipy/optimize/_constraints.py +14 -10
  266. scipy/optimize/_differentiable_functions.py +371 -230
  267. scipy/optimize/_differentialevolution.py +4 -3
  268. scipy/optimize/_direct.cpython-312-aarch64-linux-musl.so +0 -0
  269. scipy/optimize/_dual_annealing.py +1 -1
  270. scipy/optimize/_elementwise.py +1 -4
  271. scipy/optimize/_group_columns.cpython-312-aarch64-linux-musl.so +0 -0
  272. scipy/optimize/_highspy/_core.cpython-312-aarch64-linux-musl.so +0 -0
  273. scipy/optimize/_highspy/_highs_options.cpython-312-aarch64-linux-musl.so +0 -0
  274. scipy/optimize/_lbfgsb.cpython-312-aarch64-linux-musl.so +0 -0
  275. scipy/optimize/_lbfgsb_py.py +57 -16
  276. scipy/optimize/_linprog_doc.py +2 -2
  277. scipy/optimize/_linprog_highs.py +2 -2
  278. scipy/optimize/_linprog_ip.py +25 -10
  279. scipy/optimize/_linprog_util.py +14 -16
  280. scipy/optimize/_lsap.cpython-312-aarch64-linux-musl.so +0 -0
  281. scipy/optimize/_lsq/common.py +3 -3
  282. scipy/optimize/_lsq/dogbox.py +16 -2
  283. scipy/optimize/_lsq/givens_elimination.cpython-312-aarch64-linux-musl.so +0 -0
  284. scipy/optimize/_lsq/least_squares.py +198 -126
  285. scipy/optimize/_lsq/lsq_linear.py +6 -6
  286. scipy/optimize/_lsq/trf.py +35 -8
  287. scipy/optimize/_milp.py +3 -1
  288. scipy/optimize/_minimize.py +105 -36
  289. scipy/optimize/_minpack.cpython-312-aarch64-linux-musl.so +0 -0
  290. scipy/optimize/_minpack_py.py +21 -14
  291. scipy/optimize/_moduleTNC.cpython-312-aarch64-linux-musl.so +0 -0
  292. scipy/optimize/_nnls.py +20 -21
  293. scipy/optimize/_nonlin.py +34 -3
  294. scipy/optimize/_numdiff.py +288 -110
  295. scipy/optimize/_optimize.py +86 -48
  296. scipy/optimize/_pava_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  297. scipy/optimize/_remove_redundancy.py +5 -5
  298. scipy/optimize/_root_scalar.py +1 -1
  299. scipy/optimize/_shgo.py +6 -0
  300. scipy/optimize/_shgo_lib/_complex.py +1 -1
  301. scipy/optimize/_slsqp_py.py +216 -124
  302. scipy/optimize/_slsqplib.cpython-312-aarch64-linux-musl.so +0 -0
  303. scipy/optimize/_spectral.py +1 -1
  304. scipy/optimize/_tnc.py +8 -1
  305. scipy/optimize/_trlib/_trlib.cpython-312-aarch64-linux-musl.so +0 -0
  306. scipy/optimize/_trustregion.py +20 -6
  307. scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
  308. scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
  309. scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
  310. scipy/optimize/_trustregion_constr/projections.py +12 -8
  311. scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
  312. scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
  313. scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
  314. scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
  315. scipy/optimize/_trustregion_exact.py +0 -1
  316. scipy/optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  317. scipy/optimize/_zeros_py.py +97 -17
  318. scipy/optimize/cython_optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
  319. scipy/optimize/slsqp.py +0 -1
  320. scipy/optimize/tests/test__basinhopping.py +1 -1
  321. scipy/optimize/tests/test__differential_evolution.py +4 -4
  322. scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
  323. scipy/optimize/tests/test__numdiff.py +66 -22
  324. scipy/optimize/tests/test__remove_redundancy.py +2 -2
  325. scipy/optimize/tests/test__shgo.py +9 -1
  326. scipy/optimize/tests/test_bracket.py +36 -46
  327. scipy/optimize/tests/test_chandrupatla.py +133 -135
  328. scipy/optimize/tests/test_cobyla.py +74 -45
  329. scipy/optimize/tests/test_constraints.py +1 -1
  330. scipy/optimize/tests/test_differentiable_functions.py +226 -6
  331. scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
  332. scipy/optimize/tests/test_least_squares.py +125 -13
  333. scipy/optimize/tests/test_linear_assignment.py +3 -3
  334. scipy/optimize/tests/test_linprog.py +3 -3
  335. scipy/optimize/tests/test_lsq_linear.py +6 -6
  336. scipy/optimize/tests/test_minimize_constrained.py +2 -2
  337. scipy/optimize/tests/test_minpack.py +4 -4
  338. scipy/optimize/tests/test_nnls.py +43 -3
  339. scipy/optimize/tests/test_nonlin.py +36 -0
  340. scipy/optimize/tests/test_optimize.py +95 -17
  341. scipy/optimize/tests/test_slsqp.py +36 -4
  342. scipy/optimize/tests/test_zeros.py +34 -1
  343. scipy/signal/__init__.py +12 -23
  344. scipy/signal/_delegators.py +568 -0
  345. scipy/signal/_filter_design.py +459 -241
  346. scipy/signal/_fir_filter_design.py +262 -90
  347. scipy/signal/_lti_conversion.py +3 -2
  348. scipy/signal/_ltisys.py +118 -91
  349. scipy/signal/_max_len_seq_inner.cpython-312-aarch64-linux-musl.so +0 -0
  350. scipy/signal/_peak_finding_utils.cpython-312-aarch64-linux-musl.so +0 -0
  351. scipy/signal/_polyutils.py +172 -0
  352. scipy/signal/_short_time_fft.py +519 -70
  353. scipy/signal/_signal_api.py +30 -0
  354. scipy/signal/_signaltools.py +719 -399
  355. scipy/signal/_sigtools.cpython-312-aarch64-linux-musl.so +0 -0
  356. scipy/signal/_sosfilt.cpython-312-aarch64-linux-musl.so +0 -0
  357. scipy/signal/_spectral_py.py +230 -50
  358. scipy/signal/_spline.cpython-312-aarch64-linux-musl.so +0 -0
  359. scipy/signal/_spline_filters.py +108 -68
  360. scipy/signal/_support_alternative_backends.py +73 -0
  361. scipy/signal/_upfirdn.py +4 -1
  362. scipy/signal/_upfirdn_apply.cpython-312-aarch64-linux-musl.so +0 -0
  363. scipy/signal/_waveforms.py +2 -11
  364. scipy/signal/_wavelets.py +1 -1
  365. scipy/signal/fir_filter_design.py +1 -0
  366. scipy/signal/spline.py +4 -11
  367. scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
  368. scipy/signal/tests/test_bsplines.py +114 -79
  369. scipy/signal/tests/test_cont2discrete.py +9 -2
  370. scipy/signal/tests/test_filter_design.py +721 -481
  371. scipy/signal/tests/test_fir_filter_design.py +332 -140
  372. scipy/signal/tests/test_savitzky_golay.py +4 -3
  373. scipy/signal/tests/test_short_time_fft.py +221 -3
  374. scipy/signal/tests/test_signaltools.py +2144 -1348
  375. scipy/signal/tests/test_spectral.py +50 -6
  376. scipy/signal/tests/test_splines.py +161 -96
  377. scipy/signal/tests/test_upfirdn.py +84 -50
  378. scipy/signal/tests/test_waveforms.py +20 -0
  379. scipy/signal/tests/test_windows.py +607 -466
  380. scipy/signal/windows/_windows.py +287 -148
  381. scipy/sparse/__init__.py +23 -4
  382. scipy/sparse/_base.py +270 -108
  383. scipy/sparse/_bsr.py +7 -4
  384. scipy/sparse/_compressed.py +59 -231
  385. scipy/sparse/_construct.py +90 -38
  386. scipy/sparse/_coo.py +115 -181
  387. scipy/sparse/_csc.py +4 -4
  388. scipy/sparse/_csparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  389. scipy/sparse/_csr.py +2 -2
  390. scipy/sparse/_data.py +48 -48
  391. scipy/sparse/_dia.py +105 -18
  392. scipy/sparse/_dok.py +0 -23
  393. scipy/sparse/_index.py +4 -4
  394. scipy/sparse/_matrix.py +23 -0
  395. scipy/sparse/_sparsetools.cpython-312-aarch64-linux-musl.so +0 -0
  396. scipy/sparse/_sputils.py +37 -22
  397. scipy/sparse/base.py +0 -9
  398. scipy/sparse/bsr.py +0 -14
  399. scipy/sparse/compressed.py +0 -23
  400. scipy/sparse/construct.py +0 -6
  401. scipy/sparse/coo.py +0 -14
  402. scipy/sparse/csc.py +0 -3
  403. scipy/sparse/csgraph/_flow.cpython-312-aarch64-linux-musl.so +0 -0
  404. scipy/sparse/csgraph/_matching.cpython-312-aarch64-linux-musl.so +0 -0
  405. scipy/sparse/csgraph/_min_spanning_tree.cpython-312-aarch64-linux-musl.so +0 -0
  406. scipy/sparse/csgraph/_reordering.cpython-312-aarch64-linux-musl.so +0 -0
  407. scipy/sparse/csgraph/_shortest_path.cpython-312-aarch64-linux-musl.so +0 -0
  408. scipy/sparse/csgraph/_tools.cpython-312-aarch64-linux-musl.so +0 -0
  409. scipy/sparse/csgraph/_traversal.cpython-312-aarch64-linux-musl.so +0 -0
  410. scipy/sparse/csgraph/tests/test_matching.py +14 -2
  411. scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
  412. scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
  413. scipy/sparse/csr.py +0 -5
  414. scipy/sparse/data.py +1 -6
  415. scipy/sparse/dia.py +0 -7
  416. scipy/sparse/dok.py +0 -10
  417. scipy/sparse/linalg/_dsolve/_superlu.cpython-312-aarch64-linux-musl.so +0 -0
  418. scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
  419. scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
  420. scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-aarch64-linux-musl.so +0 -0
  421. scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
  422. scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
  423. scipy/sparse/linalg/_interface.py +17 -18
  424. scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
  425. scipy/sparse/linalg/_isolve/iterative.py +51 -45
  426. scipy/sparse/linalg/_isolve/lgmres.py +6 -6
  427. scipy/sparse/linalg/_isolve/minres.py +5 -5
  428. scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
  429. scipy/sparse/linalg/_isolve/utils.py +2 -8
  430. scipy/sparse/linalg/_matfuncs.py +1 -1
  431. scipy/sparse/linalg/_norm.py +1 -1
  432. scipy/sparse/linalg/_propack/_cpropack.cpython-312-aarch64-linux-musl.so +0 -0
  433. scipy/sparse/linalg/_propack/_dpropack.cpython-312-aarch64-linux-musl.so +0 -0
  434. scipy/sparse/linalg/_propack/_spropack.cpython-312-aarch64-linux-musl.so +0 -0
  435. scipy/sparse/linalg/_propack/_zpropack.cpython-312-aarch64-linux-musl.so +0 -0
  436. scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
  437. scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
  438. scipy/sparse/tests/test_arithmetic1d.py +5 -2
  439. scipy/sparse/tests/test_base.py +214 -42
  440. scipy/sparse/tests/test_common1d.py +7 -7
  441. scipy/sparse/tests/test_construct.py +1 -1
  442. scipy/sparse/tests/test_coo.py +272 -4
  443. scipy/sparse/tests/test_sparsetools.py +5 -0
  444. scipy/sparse/tests/test_sputils.py +36 -7
  445. scipy/spatial/_ckdtree.cpython-312-aarch64-linux-musl.so +0 -0
  446. scipy/spatial/_distance_pybind.cpython-312-aarch64-linux-musl.so +0 -0
  447. scipy/spatial/_distance_wrap.cpython-312-aarch64-linux-musl.so +0 -0
  448. scipy/spatial/_hausdorff.cpython-312-aarch64-linux-musl.so +0 -0
  449. scipy/spatial/_qhull.cpython-312-aarch64-linux-musl.so +0 -0
  450. scipy/spatial/_voronoi.cpython-312-aarch64-linux-musl.so +0 -0
  451. scipy/spatial/distance.py +49 -42
  452. scipy/spatial/tests/test_distance.py +15 -1
  453. scipy/spatial/tests/test_kdtree.py +1 -0
  454. scipy/spatial/tests/test_qhull.py +7 -2
  455. scipy/spatial/transform/__init__.py +5 -3
  456. scipy/spatial/transform/_rigid_transform.cpython-312-aarch64-linux-musl.so +0 -0
  457. scipy/spatial/transform/_rotation.cpython-312-aarch64-linux-musl.so +0 -0
  458. scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
  459. scipy/spatial/transform/tests/test_rotation.py +1213 -832
  460. scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
  461. scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
  462. scipy/special/__init__.py +1 -47
  463. scipy/special/_add_newdocs.py +34 -772
  464. scipy/special/_basic.py +22 -25
  465. scipy/special/_comb.cpython-312-aarch64-linux-musl.so +0 -0
  466. scipy/special/_ellip_harm_2.cpython-312-aarch64-linux-musl.so +0 -0
  467. scipy/special/_gufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  468. scipy/special/_logsumexp.py +67 -58
  469. scipy/special/_orthogonal.pyi +1 -1
  470. scipy/special/_specfun.cpython-312-aarch64-linux-musl.so +0 -0
  471. scipy/special/_special_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  472. scipy/special/_spherical_bessel.py +4 -4
  473. scipy/special/_support_alternative_backends.py +212 -119
  474. scipy/special/_test_internal.cpython-312-aarch64-linux-musl.so +0 -0
  475. scipy/special/_testutils.py +4 -4
  476. scipy/special/_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
  477. scipy/special/_ufuncs.pyi +1 -0
  478. scipy/special/_ufuncs.pyx +215 -1400
  479. scipy/special/_ufuncs_cxx.cpython-312-aarch64-linux-musl.so +0 -0
  480. scipy/special/_ufuncs_cxx.pxd +2 -15
  481. scipy/special/_ufuncs_cxx.pyx +5 -44
  482. scipy/special/_ufuncs_cxx_defs.h +2 -16
  483. scipy/special/_ufuncs_defs.h +0 -8
  484. scipy/special/cython_special.cpython-312-aarch64-linux-musl.so +0 -0
  485. scipy/special/cython_special.pxd +1 -1
  486. scipy/special/tests/_cython_examples/meson.build +10 -1
  487. scipy/special/tests/test_basic.py +153 -20
  488. scipy/special/tests/test_boost_ufuncs.py +3 -0
  489. scipy/special/tests/test_cdflib.py +35 -11
  490. scipy/special/tests/test_gammainc.py +16 -0
  491. scipy/special/tests/test_hyp2f1.py +2 -2
  492. scipy/special/tests/test_log1mexp.py +85 -0
  493. scipy/special/tests/test_logsumexp.py +206 -64
  494. scipy/special/tests/test_mpmath.py +1 -0
  495. scipy/special/tests/test_nan_inputs.py +1 -1
  496. scipy/special/tests/test_orthogonal.py +17 -18
  497. scipy/special/tests/test_sf_error.py +3 -2
  498. scipy/special/tests/test_sph_harm.py +6 -7
  499. scipy/special/tests/test_support_alternative_backends.py +211 -76
  500. scipy/stats/__init__.py +4 -1
  501. scipy/stats/_ansari_swilk_statistics.cpython-312-aarch64-linux-musl.so +0 -0
  502. scipy/stats/_axis_nan_policy.py +5 -12
  503. scipy/stats/_biasedurn.cpython-312-aarch64-linux-musl.so +0 -0
  504. scipy/stats/_continued_fraction.py +387 -0
  505. scipy/stats/_continuous_distns.py +277 -310
  506. scipy/stats/_correlation.py +1 -1
  507. scipy/stats/_covariance.py +6 -3
  508. scipy/stats/_discrete_distns.py +39 -32
  509. scipy/stats/_distn_infrastructure.py +39 -12
  510. scipy/stats/_distribution_infrastructure.py +900 -238
  511. scipy/stats/_entropy.py +9 -10
  512. scipy/{_lib → stats}/_finite_differences.py +1 -1
  513. scipy/stats/_hypotests.py +83 -50
  514. scipy/stats/_kde.py +53 -49
  515. scipy/stats/_ksstats.py +1 -1
  516. scipy/stats/_levy_stable/__init__.py +7 -15
  517. scipy/stats/_levy_stable/levyst.cpython-312-aarch64-linux-musl.so +0 -0
  518. scipy/stats/_morestats.py +118 -73
  519. scipy/stats/_mstats_basic.py +13 -17
  520. scipy/stats/_mstats_extras.py +8 -8
  521. scipy/stats/_multivariate.py +89 -113
  522. scipy/stats/_new_distributions.py +97 -20
  523. scipy/stats/_page_trend_test.py +12 -5
  524. scipy/stats/_probability_distribution.py +265 -43
  525. scipy/stats/_qmc.py +14 -9
  526. scipy/stats/_qmc_cy.cpython-312-aarch64-linux-musl.so +0 -0
  527. scipy/stats/_qmvnt.py +16 -95
  528. scipy/stats/_qmvnt_cy.cpython-312-aarch64-linux-musl.so +0 -0
  529. scipy/stats/_quantile.py +335 -0
  530. scipy/stats/_rcont/rcont.cpython-312-aarch64-linux-musl.so +0 -0
  531. scipy/stats/_resampling.py +4 -29
  532. scipy/stats/_sampling.py +1 -1
  533. scipy/stats/_sobol.cpython-312-aarch64-linux-musl.so +0 -0
  534. scipy/stats/_stats.cpython-312-aarch64-linux-musl.so +0 -0
  535. scipy/stats/_stats_mstats_common.py +21 -2
  536. scipy/stats/_stats_py.py +550 -476
  537. scipy/stats/_stats_pythran.cpython-312-aarch64-linux-musl.so +0 -0
  538. scipy/stats/_unuran/unuran_wrapper.cpython-312-aarch64-linux-musl.so +0 -0
  539. scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
  540. scipy/stats/_variation.py +6 -8
  541. scipy/stats/_wilcoxon.py +13 -7
  542. scipy/stats/tests/common_tests.py +6 -4
  543. scipy/stats/tests/test_axis_nan_policy.py +62 -24
  544. scipy/stats/tests/test_continued_fraction.py +173 -0
  545. scipy/stats/tests/test_continuous.py +379 -60
  546. scipy/stats/tests/test_continuous_basic.py +18 -12
  547. scipy/stats/tests/test_discrete_basic.py +14 -8
  548. scipy/stats/tests/test_discrete_distns.py +16 -16
  549. scipy/stats/tests/test_distributions.py +95 -75
  550. scipy/stats/tests/test_entropy.py +40 -48
  551. scipy/stats/tests/test_fit.py +4 -3
  552. scipy/stats/tests/test_hypotests.py +153 -24
  553. scipy/stats/tests/test_kdeoth.py +109 -41
  554. scipy/stats/tests/test_marray.py +289 -0
  555. scipy/stats/tests/test_morestats.py +79 -47
  556. scipy/stats/tests/test_mstats_basic.py +3 -3
  557. scipy/stats/tests/test_multivariate.py +434 -83
  558. scipy/stats/tests/test_qmc.py +13 -10
  559. scipy/stats/tests/test_quantile.py +199 -0
  560. scipy/stats/tests/test_rank.py +119 -112
  561. scipy/stats/tests/test_resampling.py +47 -56
  562. scipy/stats/tests/test_sampling.py +9 -4
  563. scipy/stats/tests/test_stats.py +799 -939
  564. scipy/stats/tests/test_variation.py +8 -6
  565. scipy/version.py +2 -2
  566. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
  567. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
  568. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +1262 -1269
  569. scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
  570. scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
  571. scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
  572. scipy/_lib/array_api_extra/_funcs.py +0 -484
  573. scipy/_lib/array_api_extra/_typing.py +0 -8
  574. scipy/interpolate/_bspl.cpython-312-aarch64-linux-musl.so +0 -0
  575. scipy/optimize/_cobyla.cpython-312-aarch64-linux-musl.so +0 -0
  576. scipy/optimize/_cython_nnls.cpython-312-aarch64-linux-musl.so +0 -0
  577. scipy/optimize/_slsqp.cpython-312-aarch64-linux-musl.so +0 -0
  578. scipy/spatial/qhull_src/COPYING.txt +0 -38
  579. scipy/special/libsf_error_state.so +0 -0
  580. scipy/special/tests/test_log_softmax.py +0 -109
  581. scipy/special/tests/test_xsf_cuda.py +0 -114
  582. scipy/special/xsf/binom.h +0 -89
  583. scipy/special/xsf/cdflib.h +0 -100
  584. scipy/special/xsf/cephes/airy.h +0 -307
  585. scipy/special/xsf/cephes/besselpoly.h +0 -51
  586. scipy/special/xsf/cephes/beta.h +0 -257
  587. scipy/special/xsf/cephes/cbrt.h +0 -131
  588. scipy/special/xsf/cephes/chbevl.h +0 -85
  589. scipy/special/xsf/cephes/chdtr.h +0 -193
  590. scipy/special/xsf/cephes/const.h +0 -87
  591. scipy/special/xsf/cephes/ellie.h +0 -293
  592. scipy/special/xsf/cephes/ellik.h +0 -251
  593. scipy/special/xsf/cephes/ellpe.h +0 -107
  594. scipy/special/xsf/cephes/ellpk.h +0 -117
  595. scipy/special/xsf/cephes/expn.h +0 -260
  596. scipy/special/xsf/cephes/gamma.h +0 -398
  597. scipy/special/xsf/cephes/hyp2f1.h +0 -596
  598. scipy/special/xsf/cephes/hyperg.h +0 -361
  599. scipy/special/xsf/cephes/i0.h +0 -149
  600. scipy/special/xsf/cephes/i1.h +0 -158
  601. scipy/special/xsf/cephes/igam.h +0 -421
  602. scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
  603. scipy/special/xsf/cephes/igami.h +0 -313
  604. scipy/special/xsf/cephes/j0.h +0 -225
  605. scipy/special/xsf/cephes/j1.h +0 -198
  606. scipy/special/xsf/cephes/jv.h +0 -715
  607. scipy/special/xsf/cephes/k0.h +0 -164
  608. scipy/special/xsf/cephes/k1.h +0 -163
  609. scipy/special/xsf/cephes/kn.h +0 -243
  610. scipy/special/xsf/cephes/lanczos.h +0 -112
  611. scipy/special/xsf/cephes/ndtr.h +0 -275
  612. scipy/special/xsf/cephes/poch.h +0 -85
  613. scipy/special/xsf/cephes/polevl.h +0 -167
  614. scipy/special/xsf/cephes/psi.h +0 -194
  615. scipy/special/xsf/cephes/rgamma.h +0 -111
  616. scipy/special/xsf/cephes/scipy_iv.h +0 -811
  617. scipy/special/xsf/cephes/shichi.h +0 -248
  618. scipy/special/xsf/cephes/sici.h +0 -224
  619. scipy/special/xsf/cephes/sindg.h +0 -221
  620. scipy/special/xsf/cephes/tandg.h +0 -139
  621. scipy/special/xsf/cephes/trig.h +0 -58
  622. scipy/special/xsf/cephes/unity.h +0 -186
  623. scipy/special/xsf/cephes/zeta.h +0 -172
  624. scipy/special/xsf/config.h +0 -304
  625. scipy/special/xsf/digamma.h +0 -205
  626. scipy/special/xsf/error.h +0 -57
  627. scipy/special/xsf/evalpoly.h +0 -47
  628. scipy/special/xsf/expint.h +0 -266
  629. scipy/special/xsf/hyp2f1.h +0 -694
  630. scipy/special/xsf/iv_ratio.h +0 -173
  631. scipy/special/xsf/lambertw.h +0 -150
  632. scipy/special/xsf/loggamma.h +0 -163
  633. scipy/special/xsf/sici.h +0 -200
  634. scipy/special/xsf/tools.h +0 -427
  635. scipy/special/xsf/trig.h +0 -164
  636. scipy/special/xsf/wright_bessel.h +0 -843
  637. scipy/special/xsf/zlog1.h +0 -35
  638. scipy/stats/_mvn.cpython-312-aarch64-linux-musl.so +0 -0
  639. scipy.libs/libgcc_s-7393e603.so.1 +0 -0
  640. scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
  641. {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
@@ -906,6 +906,50 @@ class TestAkima1DInterpolator:
906
906
  yi[:, 1, 1] = 4. * yi_
907
907
  xp_assert_close(ak(xi), yi)
908
908
 
909
+ def test_linear_interpolant_edge_case_1d(self):
910
+ x = np.array([0.0, 1.0], dtype=float)
911
+ y = np.array([0.5, 1.0])
912
+ akima = Akima1DInterpolator(x, y, axis=0, extrapolate=None)
913
+ xp_assert_close(akima(0.45), np.array(0.725))
914
+
915
+ def test_linear_interpolant_edge_case_2d(self):
916
+ x = np.array([0., 1.])
917
+ y = np.column_stack((x, 2. * x, 3. * x, 4. * x))
918
+
919
+ ak = Akima1DInterpolator(x, y)
920
+ xi = np.array([0.5, 1.])
921
+ yi = np.array([[0.5, 1., 1.5, 2. ],
922
+ [1., 2., 3., 4.]])
923
+ xp_assert_close(ak(xi), yi)
924
+
925
+ ak = Akima1DInterpolator(x, y.T, axis=1)
926
+ xp_assert_close(ak(xi), yi.T)
927
+
928
+ def test_linear_interpolant_edge_case_3d(self):
929
+ x = np.arange(0., 2.)
930
+ y_ = np.array([0., 1.])
931
+ y = np.empty((2, 2, 2))
932
+ y[:, 0, 0] = y_
933
+ y[:, 1, 0] = 2. * y_
934
+ y[:, 0, 1] = 3. * y_
935
+ y[:, 1, 1] = 4. * y_
936
+ ak = Akima1DInterpolator(x, y)
937
+ yi_ = np.array([0.5, 1.])
938
+ yi = np.empty((2, 2, 2))
939
+ yi[:, 0, 0] = yi_
940
+ yi[:, 1, 0] = 2. * yi_
941
+ yi[:, 0, 1] = 3. * yi_
942
+ yi[:, 1, 1] = 4. * yi_
943
+ xi = yi_
944
+ xp_assert_close(ak(xi), yi)
945
+
946
+ ak = Akima1DInterpolator(x, y.transpose(1, 0, 2), axis=1)
947
+ xp_assert_close(ak(xi), yi.transpose(1, 0, 2))
948
+
949
+ ak = Akima1DInterpolator(x, y.transpose(2, 1, 0), axis=2)
950
+ xp_assert_close(ak(xi), yi.transpose(2, 1, 0))
951
+
952
+
909
953
  def test_degenerate_case_multidimensional(self):
910
954
  # This test is for issue #5683.
911
955
  x = np.array([0, 1, 2])
@@ -1354,8 +1398,7 @@ class TestPPoly:
1354
1398
 
1355
1399
  xi = np.linspace(0, 1, 200)
1356
1400
  for dx in range(0, 10):
1357
- xp_assert_close(pp(xi, dx), pp.derivative(dx)(xi),
1358
- err_msg="dx=%d" % (dx,))
1401
+ xp_assert_close(pp(xi, dx), pp.derivative(dx)(xi), err_msg=f"dx={dx}")
1359
1402
 
1360
1403
  def test_antiderivative_of_constant(self):
1361
1404
  # https://github.com/scipy/scipy/issues/4216
@@ -1418,8 +1461,9 @@ class TestPPoly:
1418
1461
  r = 1e-13
1419
1462
  endpoint = r*pp2.x[:-1] + (1 - r)*pp2.x[1:]
1420
1463
 
1421
- xp_assert_close(pp2(pp2.x[1:]), pp2(endpoint),
1422
- rtol=1e-7, err_msg="dx=%d k=%d" % (dx, k))
1464
+ xp_assert_close(
1465
+ pp2(pp2.x[1:]), pp2(endpoint), rtol=1e-7, err_msg=f"dx={dx} k={k}"
1466
+ )
1423
1467
 
1424
1468
  def test_antiderivative_vs_spline(self):
1425
1469
  rng = np.random.RandomState(1234)
@@ -4,6 +4,8 @@ import pytest
4
4
  import numpy as np
5
5
 
6
6
  from numpy.testing import assert_warns
7
+ from numpy.exceptions import ComplexWarning
8
+
7
9
  from scipy._lib._array_api import (
8
10
  xp_assert_equal, xp_assert_close, assert_array_almost_equal
9
11
  )
@@ -16,7 +18,6 @@ from scipy.interpolate import (RegularGridInterpolator, interpn,
16
18
  NearestNDInterpolator, LinearNDInterpolator)
17
19
 
18
20
  from scipy.sparse._sputils import matrix
19
- from scipy._lib._util import ComplexWarning
20
21
  from scipy._lib._testutils import _run_concurrent_barrier
21
22
 
22
23
 
@@ -194,6 +194,8 @@ def _get_read_cursor(source, parallelism=None):
194
194
  source = bz2.BZ2File(path, 'rb')
195
195
  ret_stream_to_close = source
196
196
  else:
197
+ if not os.path.exists(path):
198
+ raise FileNotFoundError(f"The source file does not exist: {path}")
197
199
  return _fmm_core.open_read_file(path, parallelism), ret_stream_to_close
198
200
 
199
201
  # Stream object.
@@ -72,20 +72,20 @@ class IntFormat:
72
72
  def __repr__(self):
73
73
  r = "IntFormat("
74
74
  if self.repeat:
75
- r += "%d" % self.repeat
76
- r += "I%d" % self.width
75
+ r += f"{self.repeat}"
76
+ r += f"I{self.width}"
77
77
  if self.min:
78
- r += ".%d" % self.min
78
+ r += f".{self.min}"
79
79
  return r + ")"
80
80
 
81
81
  @property
82
82
  def fortran_format(self):
83
83
  r = "("
84
84
  if self.repeat:
85
- r += "%d" % self.repeat
86
- r += "I%d" % self.width
85
+ r += f"{self.repeat}"
86
+ r += f"I{self.width}"
87
87
  if self.min:
88
- r += ".%d" % self.min
88
+ r += f".{self.min}"
89
89
  return r + ")"
90
90
 
91
91
  @property
@@ -145,20 +145,20 @@ class ExpFormat:
145
145
  def __repr__(self):
146
146
  r = "ExpFormat("
147
147
  if self.repeat:
148
- r += "%d" % self.repeat
149
- r += "E%d.%d" % (self.width, self.significand)
148
+ r += f"{self.repeat}"
149
+ r += f"E{self.width}.{self.significand}"
150
150
  if self.min:
151
- r += "E%d" % self.min
151
+ r += f"E{self.min}"
152
152
  return r + ")"
153
153
 
154
154
  @property
155
155
  def fortran_format(self):
156
156
  r = "("
157
157
  if self.repeat:
158
- r += "%d" % self.repeat
159
- r += "E%d.%d" % (self.width, self.significand)
158
+ r += f"{self.repeat}"
159
+ r += f"E{self.width}.{self.significand}"
160
160
  if self.min:
161
- r += "E%d" % self.min
161
+ r += f"E{self.min}"
162
162
  return r + ")"
163
163
 
164
164
  @property
@@ -200,8 +200,10 @@ class Tokenizer:
200
200
  else:
201
201
  self.curpos = m.end()
202
202
  return Token(self.tokens[i], m.group(), self.curpos)
203
- raise SyntaxError("Unknown character at position %d (%s)"
204
- % (self.curpos, self.data[curpos]))
203
+ raise SyntaxError(
204
+ f"Unknown character at position {self.curpos} "
205
+ f"({self.data[self.curpos]})"
206
+ )
205
207
 
206
208
 
207
209
  # Grammar for fortran format:
@@ -263,8 +265,9 @@ class FortranFormatParser:
263
265
 
264
266
  def _parse_format(self, tokens):
265
267
  if not tokens[0].type == "LPAR":
266
- raise SyntaxError("Expected left parenthesis at position "
267
- "%d (got '%s')" % (0, tokens[0].value))
268
+ raise SyntaxError(
269
+ f"Expected left parenthesis at position {0} (got '{tokens[0].value}')"
270
+ )
268
271
  elif not tokens[-1].type == "RPAR":
269
272
  raise SyntaxError("Expected right parenthesis at position "
270
273
  f"{len(tokens)} (got '{tokens[-1].value}')")
@@ -189,9 +189,10 @@ class HBInfo:
189
189
  nnon_zeros = _expect_int(line[42:56])
190
190
  nelementals = _expect_int(line[56:70])
191
191
  if not nelementals == 0:
192
- raise ValueError("Unexpected value %d for nltvl (last entry of line 3)"
193
- % nelementals)
194
-
192
+ raise ValueError(
193
+ f"Unexpected value {nelementals} for nltvl (last entry of line 3)"
194
+ )
195
+
195
196
  # Fourth line
196
197
  line = fid.readline().strip("\n")
197
198
 
@@ -282,18 +283,13 @@ class HBInfo:
282
283
  """Gives the header corresponding to this instance as a string."""
283
284
  header = [self.title.ljust(72) + self.key.ljust(8)]
284
285
 
285
- header.append("%14d%14d%14d%14d" %
286
- (self.total_nlines, self.pointer_nlines,
287
- self.indices_nlines, self.values_nlines))
288
- header.append("%14s%14d%14d%14d%14d" %
289
- (self.mxtype.fortran_format.ljust(14), self.nrows,
290
- self.ncols, self.nnon_zeros, 0))
286
+ header.append(f"{self.total_nlines:14d}{self.pointer_nlines:14d}{self.indices_nlines:14d}{self.values_nlines:14d}")
287
+ header.append(f"{self.mxtype.fortran_format.ljust(14):14s}{self.nrows:14d}{self.ncols:14d}{self.nnon_zeros:14d}{0:14d}")
291
288
 
292
289
  pffmt = self.pointer_format.fortran_format
293
290
  iffmt = self.indices_format.fortran_format
294
291
  vffmt = self.values_format.fortran_format
295
- header.append("%16s%16s%20s" %
296
- (pffmt.ljust(16), iffmt.ljust(16), vffmt.ljust(20)))
292
+ header.append(f"{pffmt.ljust(16):16s}{iffmt.ljust(16):16s}{vffmt.ljust(20):20s}")
297
293
  return "\n".join(header)
298
294
 
299
295
 
scipy/io/_idl.py CHANGED
@@ -217,7 +217,7 @@ def _read_data(f, dtype):
217
217
  elif dtype == 15:
218
218
  return _read_uint64(f)
219
219
  else:
220
- raise Exception("Unknown IDL type: %i - please report this" % dtype)
220
+ raise Exception(f"Unknown IDL type: {dtype} - please report this")
221
221
 
222
222
 
223
223
  def _read_structure(f, array_desc, struct_desc):
@@ -238,8 +238,7 @@ def _read_structure(f, array_desc, struct_desc):
238
238
  dtype.append(((col['name'].lower(), col['name']),
239
239
  DTYPE_DICT[col['typecode']]))
240
240
  else:
241
- raise Exception("Variable type %i not implemented" %
242
- col['typecode'])
241
+ raise Exception(f"Variable type {col['typecode']} not implemented")
243
242
 
244
243
  structure = np.rec.recarray((nrows, ), dtype=dtype)
245
244
 
@@ -324,7 +323,7 @@ def _read_record(f):
324
323
  _skip_bytes(f, 4)
325
324
 
326
325
  if record['rectype'] not in RECTYPE_DICT:
327
- raise Exception("Unknown RECTYPE: %i" % record['rectype'])
326
+ raise Exception(f"Unknown RECTYPE: {record['rectype']}")
328
327
 
329
328
  record['rectype'] = RECTYPE_DICT[record['rectype']]
330
329
 
@@ -482,8 +481,7 @@ def _read_arraydesc(f):
482
481
  arraydesc['dims'].append(_read_long(f))
483
482
 
484
483
  else:
485
-
486
- raise Exception("Unknown ARRSTART: %i" % arraydesc['arrstart'])
484
+ raise Exception(f"Unknown ARRSTART: {arraydesc['arrstart']}")
487
485
 
488
486
  return arraydesc
489
487
 
@@ -902,7 +900,7 @@ def readsav(file_name, idict=None, python_dict=False,
902
900
 
903
901
  for rt in set(rectypes):
904
902
  if rt != 'END_MARKER':
905
- print(" - %i are of type %s" % (rectypes.count(rt), rt))
903
+ print(f" - {rectypes.count(rt)} are of type {rt}")
906
904
  print("-"*50)
907
905
 
908
906
  if 'VARIABLE' in rectypes:
scipy/io/_netcdf.py CHANGED
@@ -132,9 +132,13 @@ class netcdf_file:
132
132
 
133
133
  Notes
134
134
  -----
135
+ This module is derived from
136
+ `pupynere <https://bitbucket.org/robertodealmeida/pupynere/>`_.
135
137
  The major advantage of this module over other modules is that it doesn't
136
- require the code to be linked to the NetCDF libraries. This module is
137
- derived from `pupynere <https://bitbucket.org/robertodealmeida/pupynere/>`_.
138
+ require the code to be linked to the NetCDF libraries. However, for a more
139
+ recent version of the NetCDF standard and additional features, please consider
140
+ the permissively-licensed
141
+ `netcdf4-python <https://unidata.github.io/netcdf4-python/>`_.
138
142
 
139
143
  NetCDF files are a self-describing binary data format. The file contains
140
144
  metadata that describes the dimensions and variables in the file. More
@@ -563,7 +567,7 @@ class netcdf_file:
563
567
  types = [(int, NC_INT), (float, NC_FLOAT), (str, NC_CHAR)]
564
568
 
565
569
  # bytes index into scalars in py3k. Check for "string" types
566
- if isinstance(values, (str, bytes)):
570
+ if isinstance(values, str | bytes):
567
571
  sample = values
568
572
  else:
569
573
  try:
@@ -682,8 +686,8 @@ class netcdf_file:
682
686
  actual_size = reduce(mul, (1,) + shape[1:]) * size
683
687
  padding = -actual_size % 4
684
688
  if padding:
685
- dtypes['names'].append('_padding_%d' % var)
686
- dtypes['formats'].append('(%d,)>b' % padding)
689
+ dtypes['names'].append(f'_padding_{var}')
690
+ dtypes['formats'].append(f'({padding},)>b')
687
691
 
688
692
  # Data will be set later.
689
693
  data = None
@@ -856,6 +860,12 @@ class netcdf_variable:
856
860
  --------
857
861
  isrec, shape
858
862
 
863
+ Notes
864
+ -----
865
+ For a more recent version of the NetCDF standard and additional features, please
866
+ consider the permissively-licensed
867
+ `netcdf4-python <https://unidata.github.io/netcdf4-python/>`_.
868
+
859
869
  """
860
870
  def __init__(self, data, typecode, size, shape, dimensions,
861
871
  attributes=None,
@@ -40,8 +40,8 @@ expected_types = ['numeric', 'numeric', 'numeric', 'numeric', 'nominal']
40
40
  missing = pjoin(data_path, 'missing.arff')
41
41
  expect_missing_raw = np.array([[1, 5], [2, 4], [np.nan, np.nan]])
42
42
  expect_missing = np.empty(3, [('yop', float), ('yap', float)])
43
- expect_missing['yop'] = expect_missing_raw[:, 0] # type: ignore[call-overload]
44
- expect_missing['yap'] = expect_missing_raw[:, 1] # type: ignore[call-overload]
43
+ expect_missing['yop'] = expect_missing_raw[:, 0]
44
+ expect_missing['yap'] = expect_missing_raw[:, 1]
45
45
 
46
46
 
47
47
  class TestData:
@@ -147,7 +147,7 @@ class TestHeader:
147
147
  # Test numerical attributes
148
148
  assert_(len(attrs) == 5)
149
149
  for i in range(4):
150
- assert_(attrs[i].name == 'attr%d' % i)
150
+ assert_(attrs[i].name == f'attr{i}')
151
151
  assert_(attrs[i].type_name == 'numeric')
152
152
 
153
153
  # Test nominal attribute
@@ -14,6 +14,7 @@ and writing MATLAB files.
14
14
  MatReadError - Exception indicating a read issue
15
15
  MatReadWarning - Warning class for read issues
16
16
  MatWriteError - Exception indicating a write issue
17
+ MatWriteWarning - Warning class for write issues
17
18
  mat_struct - Class used when ``struct_as_record=False``
18
19
  varmats_from_mat - Pull variables out of mat 5 file as a sequence of mat file objects
19
20
 
@@ -38,7 +39,7 @@ namespace also exist in this namespace:
38
39
 
39
40
  Notes
40
41
  -----
41
- MATLAB(R) is a registered trademark of The MathWorks, Inc., 3 Apple Hill
42
+ MATLAB® is a registered trademark of The MathWorks, Inc., 3 Apple Hill
42
43
  Drive, Natick, MA 01760-2098, USA.
43
44
 
44
45
  """
@@ -47,7 +48,7 @@ from ._mio import loadmat, savemat, whosmat
47
48
  from ._mio5 import MatlabFunction, varmats_from_mat
48
49
  from ._mio5_params import MatlabObject, MatlabOpaque, mat_struct
49
50
  from ._miobase import (matfile_version, MatReadError, MatReadWarning,
50
- MatWriteError)
51
+ MatWriteError, MatWriteWarning)
51
52
 
52
53
  # Deprecated namespaces, to be removed in v2.0.0
53
54
  from .import (mio, mio5, mio5_params, mio4, byteordercodes,
@@ -56,7 +57,8 @@ from .import (mio, mio5, mio5_params, mio4, byteordercodes,
56
57
  __all__ = [
57
58
  'loadmat', 'savemat', 'whosmat', 'MatlabObject',
58
59
  'matfile_version', 'MatReadError', 'MatReadWarning',
59
- 'MatWriteError', 'mat_struct', 'MatlabOpaque', 'MatlabFunction', 'varmats_from_mat',
60
+ 'MatWriteError', 'MatWriteWarning', 'mat_struct', 'MatlabOpaque',
61
+ 'MatlabFunction', 'varmats_from_mat',
60
62
  ]
61
63
 
62
64
  from scipy._lib._testutils import PytestTester
scipy/io/matlab/_mio.py CHANGED
@@ -267,7 +267,10 @@ def savemat(file_name, mdict,
267
267
  True``).
268
268
  Can also pass open file_like object.
269
269
  mdict : dict
270
- Dictionary from which to save matfile variables.
270
+ Dictionary from which to save matfile variables. Note that if this dict
271
+ has a key starting with ``_`` or a sub-dict has a key starting with ``_``
272
+ or a digit, these key's items will not be saved in the mat file and
273
+ `MatWriteWarning` will be issued.
271
274
  appendmat : bool, optional
272
275
  True (the default) to append the .mat extension to the end of the
273
276
  given filename, if not already present.
scipy/io/matlab/_mio5.py CHANGED
@@ -87,7 +87,7 @@ from ._byteordercodes import native_code, swapped_code
87
87
 
88
88
  from ._miobase import (MatFileReader, docfiller, matdims, read_dtype,
89
89
  arr_to_chars, arr_dtype_number, MatWriteError,
90
- MatReadError, MatReadWarning)
90
+ MatReadError, MatReadWarning, MatWriteWarning)
91
91
 
92
92
  # Reader object for matlab 5 format variables
93
93
  from ._mio5_utils import VarReader5
@@ -221,7 +221,7 @@ class MatFile5Reader(MatFileReader):
221
221
  hdict['__header__'] = hdr['description'].item().strip(b' \t\n\000')
222
222
  v_major = hdr['version'] >> 8
223
223
  v_minor = hdr['version'] & 0xFF
224
- hdict['__version__'] = '%d.%d' % (v_major, v_minor)
224
+ hdict['__version__'] = f'{v_major}.{v_minor}'
225
225
  return hdict
226
226
 
227
227
  def initialize_read(self):
@@ -267,7 +267,7 @@ class MatFile5Reader(MatFileReader):
267
267
  check_stream_limit = False
268
268
  self._matrix_reader.set_stream(self.mat_stream)
269
269
  if not mdtype == miMATRIX:
270
- raise TypeError('Expecting miMATRIX type here, got %d' % mdtype)
270
+ raise TypeError(f'Expecting miMATRIX type here, got {mdtype}')
271
271
  header = self._matrix_reader.read_header(check_stream_limit)
272
272
  return header, next_pos
273
273
 
@@ -482,10 +482,14 @@ def to_writeable(source):
482
482
  dtype = []
483
483
  values = []
484
484
  for field, value in source.items():
485
- if (isinstance(field, str) and
486
- field[0] not in '_0123456789'):
487
- dtype.append((str(field), object))
488
- values.append(value)
485
+ if isinstance(field, str):
486
+ if field[0] not in '_0123456789':
487
+ dtype.append((str(field), object))
488
+ values.append(value)
489
+ else:
490
+ msg = (f"Starting field name with a underscore "
491
+ f"or a digit ({field}) is ignored")
492
+ warnings.warn(msg, MatWriteWarning, stacklevel=2)
489
493
  if dtype:
490
494
  return np.array([tuple(values)], dtype)
491
495
  else:
@@ -512,7 +516,7 @@ NDT_ARRAY_FLAGS = MDTYPES[native_code]['dtypes']['array_flags']
512
516
  class VarWriter5:
513
517
  ''' Generic matlab matrix writing class '''
514
518
  mat_tag = np.zeros((), NDT_TAG_FULL)
515
- mat_tag['mdtype'] = miMATRIX # type: ignore[call-overload]
519
+ mat_tag['mdtype'] = miMATRIX
516
520
 
517
521
  def __init__(self, file_writer):
518
522
  self.file_stream = file_writer.file_stream
@@ -789,12 +793,11 @@ class VarWriter5:
789
793
  length = max([len(fieldname) for fieldname in fieldnames])+1
790
794
  max_length = (self.long_field_names and 64) or 32
791
795
  if length > max_length:
792
- raise ValueError("Field names are restricted to %d characters" %
793
- (max_length-1))
796
+ raise ValueError(
797
+ f"Field names are restricted to {max_length - 1} characters"
798
+ )
794
799
  self.write_element(np.array([length], dtype='i4'))
795
- self.write_element(
796
- np.array(fieldnames, dtype='S%d' % (length)),
797
- mdtype=miINT8)
800
+ self.write_element(np.array(fieldnames, dtype=f'S{length}'), mdtype=miINT8)
798
801
  A = np.atleast_2d(arr).flatten('F')
799
802
  for el in A:
800
803
  for f in fieldnames:
@@ -879,6 +882,9 @@ class MatFile5Writer:
879
882
  self._matrix_writer = VarWriter5(self)
880
883
  for name, var in mdict.items():
881
884
  if name[0] == '_':
885
+ msg = (f"Starting field name with a "
886
+ f"underscore ({name}) is ignored")
887
+ warnings.warn(msg, MatWriteWarning, stacklevel=2)
882
888
  continue
883
889
  is_global = name in self.global_vars
884
890
  if self.do_compression:
@@ -14,7 +14,7 @@ from scipy._lib import doccer
14
14
  from . import _byteordercodes as boc
15
15
 
16
16
  __all__ = [
17
- 'MatReadError', 'MatReadWarning', 'MatWriteError',
17
+ 'MatReadError', 'MatReadWarning', 'MatWriteError', 'MatWriteWarning',
18
18
  ]
19
19
 
20
20
  class MatReadError(Exception):
@@ -28,6 +28,9 @@ class MatWriteError(Exception):
28
28
  class MatReadWarning(UserWarning):
29
29
  """Warning class for read issues."""
30
30
 
31
+ class MatWriteWarning(UserWarning):
32
+ """Warning class for write issues."""
33
+
31
34
 
32
35
  doc_dict = \
33
36
  {'file_arg':
@@ -22,14 +22,13 @@ from scipy.sparse import issparse, eye_array, coo_array, csc_array
22
22
  import scipy.io
23
23
  from scipy.io.matlab import MatlabOpaque, MatlabFunction, MatlabObject
24
24
  import scipy.io.matlab._byteordercodes as boc
25
- from scipy.io.matlab._miobase import (
26
- matdims, MatWriteError, MatReadError, matfile_version)
25
+ from scipy.io.matlab._miobase import (matdims, MatWriteError, MatReadError,
26
+ matfile_version, MatWriteWarning)
27
27
  from scipy.io.matlab._mio import mat_reader_factory, loadmat, savemat, whosmat
28
28
  from scipy.io.matlab._mio5 import (
29
29
  MatFile5Writer, MatFile5Reader, varmats_from_mat, to_writeable,
30
30
  EmptyStructMarker)
31
31
  import scipy.io.matlab._mio5_params as mio5p
32
- from scipy._lib._util import VisibleDeprecationWarning
33
32
 
34
33
 
35
34
  test_data_path = pjoin(dirname(__file__), 'data')
@@ -270,7 +269,7 @@ def _check_level(label, expected, actual):
270
269
  if isinstance(expected, MatlabObject):
271
270
  assert_equal(expected.classname, actual.classname)
272
271
  for i, ev in enumerate(expected):
273
- level_label = "%s, [%d], " % (label, i)
272
+ level_label = f"{label}, [{i}], "
274
273
  _check_level(level_label, ev, actual[i])
275
274
  return
276
275
  if ex_dtype.fields: # probably recarray
@@ -713,12 +712,14 @@ def test_to_writeable():
713
712
  expected2 = np.array([(2, 1)], dtype=[('b', '|O8'), ('a', '|O8')])
714
713
  alternatives = (expected1, expected2)
715
714
  assert_any_equal(to_writeable({'a':1,'b':2}), alternatives)
716
- # Fields with underscores discarded
717
- assert_any_equal(to_writeable({'a':1,'b':2, '_c':3}), alternatives)
715
+ # Fields with underscores discarded with a warning message.
716
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
717
+ assert_any_equal(to_writeable({'a':1, 'b':2, '_c':3}), alternatives)
718
718
  # Not-string fields discarded
719
719
  assert_any_equal(to_writeable({'a':1,'b':2, 100:3}), alternatives)
720
720
  # String fields that are valid Python identifiers discarded
721
- assert_any_equal(to_writeable({'a':1,'b':2, '99':3}), alternatives)
721
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
722
+ assert_any_equal(to_writeable({'a':1, 'b':2, '99':3}), alternatives)
722
723
  # Object with field names is equivalent
723
724
 
724
725
  class klass:
@@ -759,10 +760,14 @@ def test_to_writeable():
759
760
  assert_equal(res.shape, (1,))
760
761
  assert_equal(res.dtype.type, np.object_)
761
762
  # Only fields with illegal characters, falls back to EmptyStruct
762
- assert_(to_writeable({'1':1}) is EmptyStructMarker)
763
- assert_(to_writeable({'_a':1}) is EmptyStructMarker)
763
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
764
+ assert_(to_writeable({'1':1}) is EmptyStructMarker)
765
+
766
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
767
+ assert_(to_writeable({'_a':1}) is EmptyStructMarker)
764
768
  # Unless there are valid fields, in which case structured array
765
- assert_equal(to_writeable({'1':1, 'f': 2}),
769
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
770
+ assert_equal(to_writeable({'1':1, 'f': 2}),
766
771
  np.array([(2,)], dtype=[('f', '|O8')]))
767
772
 
768
773
 
@@ -975,7 +980,9 @@ def test_func_read():
975
980
  assert isinstance(d['testfunc'], MatlabFunction)
976
981
  stream = BytesIO()
977
982
  wtr = MatFile5Writer(stream)
978
- assert_raises(MatWriteError, wtr.put_variables, d)
983
+ # This test mat file has `__header__` field.
984
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
985
+ assert_raises(MatWriteError, wtr.put_variables, d)
979
986
 
980
987
 
981
988
  def test_mat_dtype():
@@ -1316,13 +1323,10 @@ def test_gh_17992(tmp_path):
1316
1323
  array_one = rng.random((5,3))
1317
1324
  array_two = rng.random((6,3))
1318
1325
  list_of_arrays = [array_one, array_two]
1319
- # warning suppression only needed for NumPy < 1.24.0
1320
- with np.testing.suppress_warnings() as sup:
1321
- sup.filter(VisibleDeprecationWarning)
1322
- savemat(outfile,
1323
- {'data': list_of_arrays},
1324
- long_field_names=True,
1325
- do_compression=True)
1326
+ savemat(outfile,
1327
+ {'data': list_of_arrays},
1328
+ long_field_names=True,
1329
+ do_compression=True)
1326
1330
  # round trip check
1327
1331
  new_dict = {}
1328
1332
  loadmat(outfile,
@@ -1360,6 +1364,30 @@ def test_large_m4():
1360
1364
  def test_gh_19223():
1361
1365
  from scipy.io.matlab import varmats_from_mat # noqa: F401
1362
1366
 
1367
+
1368
+ def test_invalid_field_name_warning():
1369
+ names_vars = (
1370
+ ('_1', mlarr(np.arange(10))),
1371
+ ('mystr', mlarr('a string')))
1372
+ check_mat_write_warning(names_vars)
1373
+
1374
+ names_vars = (('mymap', {"a": 1, "_b": 2}),)
1375
+ check_mat_write_warning(names_vars)
1376
+
1377
+ names_vars = (('mymap', {"a": 1, "1a": 2}),)
1378
+ check_mat_write_warning(names_vars)
1379
+
1380
+
1381
+ def check_mat_write_warning(names_vars):
1382
+ class C:
1383
+ def items(self):
1384
+ return names_vars
1385
+
1386
+ stream = BytesIO()
1387
+ with pytest.warns(MatWriteWarning, match='Starting field name with'):
1388
+ savemat(stream, C())
1389
+
1390
+
1363
1391
  def test_corrupt_files():
1364
1392
  # Test we can detect truncated or corrupt (all zero) files.
1365
1393
  for n in (2, 4, 10, 19):
@@ -18,7 +18,7 @@ def read_minimat_vars(rdr):
18
18
  hdr, next_position = rdr.read_var_header()
19
19
  name = 'None' if hdr.name is None else hdr.name.decode('latin1')
20
20
  if name == '':
21
- name = 'var_%d' % i
21
+ name = f'var_{i}'
22
22
  i += 1
23
23
  res = rdr.read_var_array(hdr, process=False)
24
24
  rdr.mat_stream.seek(next_position)
@@ -759,7 +759,7 @@ class TestMMIOCoordinate:
759
759
  # check for right entries in matrix
760
760
  assert_array_equal(A.row, [n-1])
761
761
  assert_array_equal(A.col, [n-1])
762
- assert_allclose(A.data, [float('%%.%dg' % precision % value)])
762
+ assert_allclose(A.data, [float(f'{value:.{precision}g}')])
763
763
 
764
764
  def test_bad_number_of_coordinate_header_fields(self):
765
765
  s = """\
@@ -823,3 +823,9 @@ def test_threadpoolctl():
823
823
 
824
824
  with threadpoolctl.threadpool_limits(limits=2, user_api='scipy'):
825
825
  assert_equal(fmm.PARALLELISM, 2)
826
+
827
+
828
+ def test_gh21999_file_not_exist():
829
+ tmpdir = mkdtemp(suffix=str(threading.get_native_id()))
830
+ wrong_fn = os.path.join(tmpdir, 'not_exist_test_file.mtx')
831
+ assert_raises(FileNotFoundError, mmread, wrong_fn)