scipy 1.15.3__cp312-cp312-macosx_14_0_arm64.whl → 1.16.0__cp312-cp312-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scipy/.dylibs/libgcc_s.1.1.dylib +0 -0
- scipy/.dylibs/libgfortran.5.dylib +0 -0
- scipy/.dylibs/libquadmath.0.dylib +0 -0
- scipy/__config__.py +5 -5
- scipy/__init__.py +3 -6
- scipy/_cyutility.cpython-312-darwin.so +0 -0
- scipy/_lib/_array_api.py +486 -161
- scipy/_lib/_array_api_compat_vendor.py +9 -0
- scipy/_lib/_bunch.py +4 -0
- scipy/_lib/_ccallback_c.cpython-312-darwin.so +0 -0
- scipy/_lib/_docscrape.py +1 -1
- scipy/_lib/_elementwise_iterative_method.py +15 -26
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_deprecation_call.cpython-312-darwin.so +0 -0
- scipy/_lib/_test_deprecation_def.cpython-312-darwin.so +0 -0
- scipy/_lib/_testutils.py +6 -2
- scipy/_lib/_util.py +222 -125
- scipy/_lib/array_api_compat/__init__.py +4 -4
- scipy/_lib/array_api_compat/_internal.py +19 -6
- scipy/_lib/array_api_compat/common/__init__.py +1 -1
- scipy/_lib/array_api_compat/common/_aliases.py +365 -193
- scipy/_lib/array_api_compat/common/_fft.py +94 -64
- scipy/_lib/array_api_compat/common/_helpers.py +413 -180
- scipy/_lib/array_api_compat/common/_linalg.py +116 -40
- scipy/_lib/array_api_compat/common/_typing.py +179 -10
- scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
- scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
- scipy/_lib/array_api_compat/cupy/_info.py +16 -6
- scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
- scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
- scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
- scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
- scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
- scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
- scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
- scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
- scipy/_lib/array_api_compat/numpy/_info.py +36 -16
- scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
- scipy/_lib/array_api_compat/numpy/fft.py +11 -5
- scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
- scipy/_lib/array_api_compat/torch/__init__.py +3 -5
- scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
- scipy/_lib/array_api_compat/torch/_info.py +27 -16
- scipy/_lib/array_api_compat/torch/_typing.py +3 -0
- scipy/_lib/array_api_compat/torch/fft.py +17 -18
- scipy/_lib/array_api_compat/torch/linalg.py +16 -16
- scipy/_lib/array_api_extra/__init__.py +26 -3
- scipy/_lib/array_api_extra/_delegation.py +171 -0
- scipy/_lib/array_api_extra/_lib/__init__.py +1 -0
- scipy/_lib/array_api_extra/_lib/_at.py +463 -0
- scipy/_lib/array_api_extra/_lib/_backends.py +46 -0
- scipy/_lib/array_api_extra/_lib/_funcs.py +937 -0
- scipy/_lib/array_api_extra/_lib/_lazy.py +357 -0
- scipy/_lib/array_api_extra/_lib/_testing.py +278 -0
- scipy/_lib/array_api_extra/_lib/_utils/__init__.py +1 -0
- scipy/_lib/array_api_extra/_lib/_utils/_compat.py +74 -0
- scipy/_lib/array_api_extra/_lib/_utils/_compat.pyi +45 -0
- scipy/_lib/array_api_extra/_lib/_utils/_helpers.py +559 -0
- scipy/_lib/array_api_extra/_lib/_utils/_typing.py +10 -0
- scipy/_lib/array_api_extra/_lib/_utils/_typing.pyi +105 -0
- scipy/_lib/array_api_extra/testing.py +359 -0
- scipy/_lib/decorator.py +2 -2
- scipy/_lib/doccer.py +1 -7
- scipy/_lib/messagestream.cpython-312-darwin.so +0 -0
- scipy/_lib/pyprima/__init__.py +212 -0
- scipy/_lib/pyprima/cobyla/__init__.py +0 -0
- scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
- scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
- scipy/_lib/pyprima/cobyla/geometry.py +226 -0
- scipy/_lib/pyprima/cobyla/initialize.py +215 -0
- scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
- scipy/_lib/pyprima/cobyla/update.py +289 -0
- scipy/_lib/pyprima/common/__init__.py +0 -0
- scipy/_lib/pyprima/common/_bounds.py +34 -0
- scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
- scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
- scipy/_lib/pyprima/common/_project.py +173 -0
- scipy/_lib/pyprima/common/checkbreak.py +93 -0
- scipy/_lib/pyprima/common/consts.py +47 -0
- scipy/_lib/pyprima/common/evaluate.py +99 -0
- scipy/_lib/pyprima/common/history.py +38 -0
- scipy/_lib/pyprima/common/infos.py +30 -0
- scipy/_lib/pyprima/common/linalg.py +435 -0
- scipy/_lib/pyprima/common/message.py +290 -0
- scipy/_lib/pyprima/common/powalg.py +131 -0
- scipy/_lib/pyprima/common/preproc.py +277 -0
- scipy/_lib/pyprima/common/present.py +5 -0
- scipy/_lib/pyprima/common/ratio.py +54 -0
- scipy/_lib/pyprima/common/redrho.py +47 -0
- scipy/_lib/pyprima/common/selectx.py +296 -0
- scipy/_lib/tests/test__util.py +105 -121
- scipy/_lib/tests/test_array_api.py +166 -35
- scipy/_lib/tests/test_bunch.py +7 -0
- scipy/_lib/tests/test_ccallback.py +2 -10
- scipy/_lib/tests/test_public_api.py +13 -0
- scipy/cluster/_hierarchy.cpython-312-darwin.so +0 -0
- scipy/cluster/_optimal_leaf_ordering.cpython-312-darwin.so +0 -0
- scipy/cluster/_vq.cpython-312-darwin.so +0 -0
- scipy/cluster/hierarchy.py +393 -223
- scipy/cluster/tests/test_hierarchy.py +273 -335
- scipy/cluster/tests/test_vq.py +45 -61
- scipy/cluster/vq.py +39 -35
- scipy/conftest.py +282 -151
- scipy/constants/_constants.py +4 -1
- scipy/constants/tests/test_codata.py +2 -2
- scipy/constants/tests/test_constants.py +11 -18
- scipy/datasets/_download_all.py +15 -1
- scipy/datasets/_fetchers.py +7 -1
- scipy/datasets/_utils.py +1 -1
- scipy/differentiate/_differentiate.py +25 -25
- scipy/differentiate/tests/test_differentiate.py +24 -25
- scipy/fft/_basic.py +20 -0
- scipy/fft/_helper.py +3 -34
- scipy/fft/_pocketfft/helper.py +29 -1
- scipy/fft/_pocketfft/tests/test_basic.py +2 -4
- scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
- scipy/fft/_realtransforms.py +13 -0
- scipy/fft/tests/test_basic.py +27 -25
- scipy/fft/tests/test_fftlog.py +16 -7
- scipy/fft/tests/test_helper.py +18 -34
- scipy/fft/tests/test_real_transforms.py +8 -10
- scipy/fftpack/convolve.cpython-312-darwin.so +0 -0
- scipy/fftpack/tests/test_basic.py +2 -4
- scipy/fftpack/tests/test_real_transforms.py +8 -9
- scipy/integrate/_bvp.py +9 -3
- scipy/integrate/_cubature.py +3 -2
- scipy/integrate/_dop.cpython-312-darwin.so +0 -0
- scipy/integrate/_lsoda.cpython-312-darwin.so +0 -0
- scipy/integrate/_ode.py +9 -2
- scipy/integrate/_odepack.cpython-312-darwin.so +0 -0
- scipy/integrate/_quad_vec.py +21 -29
- scipy/integrate/_quadpack.cpython-312-darwin.so +0 -0
- scipy/integrate/_quadpack_py.py +11 -7
- scipy/integrate/_quadrature.py +3 -3
- scipy/integrate/_rules/_base.py +2 -2
- scipy/integrate/_tanhsinh.py +48 -47
- scipy/integrate/_test_odeint_banded.cpython-312-darwin.so +0 -0
- scipy/integrate/_vode.cpython-312-darwin.so +0 -0
- scipy/integrate/tests/test__quad_vec.py +0 -6
- scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
- scipy/integrate/tests/test_cubature.py +21 -35
- scipy/integrate/tests/test_quadrature.py +6 -8
- scipy/integrate/tests/test_tanhsinh.py +56 -48
- scipy/interpolate/__init__.py +70 -58
- scipy/interpolate/_bary_rational.py +22 -22
- scipy/interpolate/_bsplines.py +119 -66
- scipy/interpolate/_cubic.py +65 -50
- scipy/interpolate/_dfitpack.cpython-312-darwin.so +0 -0
- scipy/interpolate/_dierckx.cpython-312-darwin.so +0 -0
- scipy/interpolate/_fitpack.cpython-312-darwin.so +0 -0
- scipy/interpolate/_fitpack2.py +9 -6
- scipy/interpolate/_fitpack_impl.py +32 -26
- scipy/interpolate/_fitpack_repro.py +23 -19
- scipy/interpolate/_interpnd.cpython-312-darwin.so +0 -0
- scipy/interpolate/_interpolate.py +30 -12
- scipy/interpolate/_ndbspline.py +13 -18
- scipy/interpolate/_ndgriddata.py +5 -8
- scipy/interpolate/_polyint.py +95 -31
- scipy/interpolate/_ppoly.cpython-312-darwin.so +0 -0
- scipy/interpolate/_rbf.py +2 -2
- scipy/interpolate/_rbfinterp.py +1 -1
- scipy/interpolate/_rbfinterp_pythran.cpython-312-darwin.so +0 -0
- scipy/interpolate/_rgi.py +31 -26
- scipy/interpolate/_rgi_cython.cpython-312-darwin.so +0 -0
- scipy/interpolate/dfitpack.py +0 -20
- scipy/interpolate/interpnd.py +1 -2
- scipy/interpolate/tests/test_bary_rational.py +2 -2
- scipy/interpolate/tests/test_bsplines.py +97 -1
- scipy/interpolate/tests/test_fitpack2.py +39 -1
- scipy/interpolate/tests/test_interpnd.py +32 -20
- scipy/interpolate/tests/test_interpolate.py +48 -4
- scipy/interpolate/tests/test_rgi.py +2 -1
- scipy/io/_fast_matrix_market/__init__.py +2 -0
- scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
- scipy/io/_harwell_boeing/hb.py +7 -11
- scipy/io/_idl.py +5 -7
- scipy/io/_netcdf.py +15 -5
- scipy/io/_test_fortran.cpython-312-darwin.so +0 -0
- scipy/io/arff/tests/test_arffread.py +3 -3
- scipy/io/matlab/__init__.py +5 -3
- scipy/io/matlab/_mio.py +4 -1
- scipy/io/matlab/_mio5.py +19 -13
- scipy/io/matlab/_mio5_utils.cpython-312-darwin.so +0 -0
- scipy/io/matlab/_mio_utils.cpython-312-darwin.so +0 -0
- scipy/io/matlab/_miobase.py +4 -1
- scipy/io/matlab/_streams.cpython-312-darwin.so +0 -0
- scipy/io/matlab/tests/test_mio.py +46 -18
- scipy/io/matlab/tests/test_mio_funcs.py +1 -1
- scipy/io/tests/test_mmio.py +7 -1
- scipy/io/tests/test_wavfile.py +41 -0
- scipy/io/wavfile.py +57 -10
- scipy/linalg/_basic.py +113 -86
- scipy/linalg/_cythonized_array_utils.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp.py +22 -9
- scipy/linalg/_decomp_cholesky.py +28 -13
- scipy/linalg/_decomp_cossin.py +45 -30
- scipy/linalg/_decomp_interpolative.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp_ldl.py +4 -1
- scipy/linalg/_decomp_lu.py +18 -6
- scipy/linalg/_decomp_lu_cython.cpython-312-darwin.so +0 -0
- scipy/linalg/_decomp_polar.py +2 -0
- scipy/linalg/_decomp_qr.py +6 -2
- scipy/linalg/_decomp_qz.py +3 -0
- scipy/linalg/_decomp_schur.py +3 -1
- scipy/linalg/_decomp_svd.py +13 -2
- scipy/linalg/_decomp_update.cpython-312-darwin.so +0 -0
- scipy/linalg/_expm_frechet.py +4 -0
- scipy/linalg/_fblas.cpython-312-darwin.so +0 -0
- scipy/linalg/_flapack.cpython-312-darwin.so +0 -0
- scipy/linalg/_linalg_pythran.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs.py +187 -4
- scipy/linalg/_matfuncs_expm.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-darwin.so +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +1 -99
- scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-darwin.so +0 -0
- scipy/linalg/_procrustes.py +2 -0
- scipy/linalg/_sketches.py +17 -6
- scipy/linalg/_solve_toeplitz.cpython-312-darwin.so +0 -0
- scipy/linalg/_solvers.py +7 -2
- scipy/linalg/_special_matrices.py +26 -36
- scipy/linalg/blas.py +35 -24
- scipy/linalg/cython_blas.cpython-312-darwin.so +0 -0
- scipy/linalg/cython_lapack.cpython-312-darwin.so +0 -0
- scipy/linalg/lapack.py +22 -2
- scipy/linalg/tests/_cython_examples/meson.build +7 -0
- scipy/linalg/tests/test_basic.py +31 -16
- scipy/linalg/tests/test_batch.py +588 -0
- scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
- scipy/linalg/tests/test_decomp.py +40 -3
- scipy/linalg/tests/test_decomp_cossin.py +14 -0
- scipy/linalg/tests/test_decomp_ldl.py +1 -1
- scipy/linalg/tests/test_lapack.py +115 -7
- scipy/linalg/tests/test_matfuncs.py +157 -102
- scipy/linalg/tests/test_procrustes.py +0 -7
- scipy/linalg/tests/test_solve_toeplitz.py +1 -1
- scipy/linalg/tests/test_special_matrices.py +1 -5
- scipy/ndimage/__init__.py +1 -0
- scipy/ndimage/_cytest.cpython-312-darwin.so +0 -0
- scipy/ndimage/_delegators.py +8 -2
- scipy/ndimage/_filters.py +453 -5
- scipy/ndimage/_interpolation.py +36 -6
- scipy/ndimage/_measurements.py +4 -2
- scipy/ndimage/_morphology.py +5 -0
- scipy/ndimage/_nd_image.cpython-312-darwin.so +0 -0
- scipy/ndimage/_ni_docstrings.py +5 -1
- scipy/ndimage/_ni_label.cpython-312-darwin.so +0 -0
- scipy/ndimage/_ni_support.py +1 -5
- scipy/ndimage/_rank_filter_1d.cpython-312-darwin.so +0 -0
- scipy/ndimage/_support_alternative_backends.py +18 -6
- scipy/ndimage/tests/test_filters.py +370 -259
- scipy/ndimage/tests/test_fourier.py +7 -9
- scipy/ndimage/tests/test_interpolation.py +68 -61
- scipy/ndimage/tests/test_measurements.py +18 -35
- scipy/ndimage/tests/test_morphology.py +143 -131
- scipy/ndimage/tests/test_splines.py +1 -3
- scipy/odr/__odrpack.cpython-312-darwin.so +0 -0
- scipy/optimize/_basinhopping.py +13 -7
- scipy/optimize/_bglu_dense.cpython-312-darwin.so +0 -0
- scipy/optimize/_bracket.py +17 -24
- scipy/optimize/_chandrupatla.py +9 -10
- scipy/optimize/_cobyla_py.py +104 -123
- scipy/optimize/_constraints.py +14 -10
- scipy/optimize/_differentiable_functions.py +371 -230
- scipy/optimize/_differentialevolution.py +4 -3
- scipy/optimize/_direct.cpython-312-darwin.so +0 -0
- scipy/optimize/_dual_annealing.py +1 -1
- scipy/optimize/_elementwise.py +1 -4
- scipy/optimize/_group_columns.cpython-312-darwin.so +0 -0
- scipy/optimize/_lbfgsb.cpython-312-darwin.so +0 -0
- scipy/optimize/_lbfgsb_py.py +80 -24
- scipy/optimize/_linprog_doc.py +2 -2
- scipy/optimize/_linprog_highs.py +2 -2
- scipy/optimize/_linprog_ip.py +25 -10
- scipy/optimize/_linprog_util.py +14 -16
- scipy/optimize/_lsap.cpython-312-darwin.so +0 -0
- scipy/optimize/_lsq/common.py +3 -3
- scipy/optimize/_lsq/dogbox.py +16 -2
- scipy/optimize/_lsq/givens_elimination.cpython-312-darwin.so +0 -0
- scipy/optimize/_lsq/least_squares.py +198 -126
- scipy/optimize/_lsq/lsq_linear.py +6 -6
- scipy/optimize/_lsq/trf.py +35 -8
- scipy/optimize/_milp.py +3 -1
- scipy/optimize/_minimize.py +105 -36
- scipy/optimize/_minpack.cpython-312-darwin.so +0 -0
- scipy/optimize/_minpack_py.py +21 -14
- scipy/optimize/_moduleTNC.cpython-312-darwin.so +0 -0
- scipy/optimize/_nnls.py +20 -21
- scipy/optimize/_nonlin.py +34 -3
- scipy/optimize/_numdiff.py +288 -110
- scipy/optimize/_optimize.py +86 -48
- scipy/optimize/_pava_pybind.cpython-312-darwin.so +0 -0
- scipy/optimize/_remove_redundancy.py +5 -5
- scipy/optimize/_root_scalar.py +1 -1
- scipy/optimize/_shgo.py +6 -0
- scipy/optimize/_shgo_lib/_complex.py +1 -1
- scipy/optimize/_slsqp_py.py +216 -124
- scipy/optimize/_slsqplib.cpython-312-darwin.so +0 -0
- scipy/optimize/_spectral.py +1 -1
- scipy/optimize/_tnc.py +8 -1
- scipy/optimize/_trlib/_trlib.cpython-312-darwin.so +0 -0
- scipy/optimize/_trustregion.py +20 -6
- scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
- scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
- scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
- scipy/optimize/_trustregion_constr/projections.py +12 -8
- scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
- scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
- scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
- scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
- scipy/optimize/_trustregion_exact.py +0 -1
- scipy/optimize/_zeros.cpython-312-darwin.so +0 -0
- scipy/optimize/_zeros_py.py +97 -17
- scipy/optimize/cython_optimize/_zeros.cpython-312-darwin.so +0 -0
- scipy/optimize/slsqp.py +0 -1
- scipy/optimize/tests/test__basinhopping.py +1 -1
- scipy/optimize/tests/test__differential_evolution.py +4 -4
- scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
- scipy/optimize/tests/test__numdiff.py +66 -22
- scipy/optimize/tests/test__remove_redundancy.py +2 -2
- scipy/optimize/tests/test__shgo.py +9 -1
- scipy/optimize/tests/test_bracket.py +36 -46
- scipy/optimize/tests/test_chandrupatla.py +133 -135
- scipy/optimize/tests/test_cobyla.py +74 -45
- scipy/optimize/tests/test_constraints.py +1 -1
- scipy/optimize/tests/test_differentiable_functions.py +226 -6
- scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
- scipy/optimize/tests/test_least_squares.py +125 -13
- scipy/optimize/tests/test_linear_assignment.py +3 -3
- scipy/optimize/tests/test_linprog.py +3 -3
- scipy/optimize/tests/test_lsq_linear.py +6 -6
- scipy/optimize/tests/test_minimize_constrained.py +2 -2
- scipy/optimize/tests/test_minpack.py +4 -4
- scipy/optimize/tests/test_nnls.py +43 -3
- scipy/optimize/tests/test_nonlin.py +36 -0
- scipy/optimize/tests/test_optimize.py +98 -20
- scipy/optimize/tests/test_slsqp.py +36 -4
- scipy/optimize/tests/test_zeros.py +34 -1
- scipy/signal/__init__.py +12 -23
- scipy/signal/_delegators.py +568 -0
- scipy/signal/_filter_design.py +459 -241
- scipy/signal/_fir_filter_design.py +262 -90
- scipy/signal/_lti_conversion.py +3 -2
- scipy/signal/_ltisys.py +118 -91
- scipy/signal/_max_len_seq_inner.cpython-312-darwin.so +0 -0
- scipy/signal/_peak_finding_utils.cpython-312-darwin.so +0 -0
- scipy/signal/_polyutils.py +172 -0
- scipy/signal/_short_time_fft.py +519 -70
- scipy/signal/_signal_api.py +30 -0
- scipy/signal/_signaltools.py +719 -399
- scipy/signal/_sigtools.cpython-312-darwin.so +0 -0
- scipy/signal/_sosfilt.cpython-312-darwin.so +0 -0
- scipy/signal/_spectral_py.py +230 -50
- scipy/signal/_spline.cpython-312-darwin.so +0 -0
- scipy/signal/_spline_filters.py +108 -68
- scipy/signal/_support_alternative_backends.py +73 -0
- scipy/signal/_upfirdn.py +4 -1
- scipy/signal/_upfirdn_apply.cpython-312-darwin.so +0 -0
- scipy/signal/_waveforms.py +2 -11
- scipy/signal/_wavelets.py +1 -1
- scipy/signal/fir_filter_design.py +1 -0
- scipy/signal/spline.py +4 -11
- scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
- scipy/signal/tests/test_bsplines.py +114 -79
- scipy/signal/tests/test_cont2discrete.py +9 -2
- scipy/signal/tests/test_filter_design.py +721 -481
- scipy/signal/tests/test_fir_filter_design.py +332 -140
- scipy/signal/tests/test_savitzky_golay.py +4 -3
- scipy/signal/tests/test_short_time_fft.py +221 -3
- scipy/signal/tests/test_signaltools.py +2145 -1349
- scipy/signal/tests/test_spectral.py +50 -6
- scipy/signal/tests/test_splines.py +161 -96
- scipy/signal/tests/test_upfirdn.py +84 -50
- scipy/signal/tests/test_waveforms.py +20 -0
- scipy/signal/tests/test_windows.py +607 -466
- scipy/signal/windows/_windows.py +287 -148
- scipy/sparse/__init__.py +23 -4
- scipy/sparse/_base.py +270 -108
- scipy/sparse/_bsr.py +7 -4
- scipy/sparse/_compressed.py +59 -231
- scipy/sparse/_construct.py +90 -38
- scipy/sparse/_coo.py +115 -181
- scipy/sparse/_csc.py +4 -4
- scipy/sparse/_csparsetools.cpython-312-darwin.so +0 -0
- scipy/sparse/_csr.py +2 -2
- scipy/sparse/_data.py +48 -48
- scipy/sparse/_dia.py +105 -18
- scipy/sparse/_dok.py +0 -23
- scipy/sparse/_index.py +4 -4
- scipy/sparse/_matrix.py +23 -0
- scipy/sparse/_sparsetools.cpython-312-darwin.so +0 -0
- scipy/sparse/_sputils.py +37 -22
- scipy/sparse/base.py +0 -9
- scipy/sparse/bsr.py +0 -14
- scipy/sparse/compressed.py +0 -23
- scipy/sparse/construct.py +0 -6
- scipy/sparse/coo.py +0 -14
- scipy/sparse/csc.py +0 -3
- scipy/sparse/csgraph/_flow.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_matching.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_reordering.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_shortest_path.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_tools.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/_traversal.cpython-312-darwin.so +0 -0
- scipy/sparse/csgraph/tests/test_matching.py +14 -2
- scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
- scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
- scipy/sparse/csr.py +0 -5
- scipy/sparse/data.py +1 -6
- scipy/sparse/dia.py +0 -7
- scipy/sparse/dok.py +0 -10
- scipy/sparse/linalg/_dsolve/_superlu.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
- scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
- scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
- scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
- scipy/sparse/linalg/_interface.py +17 -18
- scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
- scipy/sparse/linalg/_isolve/iterative.py +51 -45
- scipy/sparse/linalg/_isolve/lgmres.py +6 -6
- scipy/sparse/linalg/_isolve/minres.py +5 -5
- scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
- scipy/sparse/linalg/_isolve/utils.py +2 -8
- scipy/sparse/linalg/_matfuncs.py +1 -1
- scipy/sparse/linalg/_norm.py +1 -1
- scipy/sparse/linalg/_propack/_cpropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_spropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cpython-312-darwin.so +0 -0
- scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
- scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
- scipy/sparse/tests/test_arithmetic1d.py +5 -2
- scipy/sparse/tests/test_base.py +214 -42
- scipy/sparse/tests/test_common1d.py +7 -7
- scipy/sparse/tests/test_construct.py +1 -1
- scipy/sparse/tests/test_coo.py +272 -4
- scipy/sparse/tests/test_sparsetools.py +5 -0
- scipy/sparse/tests/test_sputils.py +36 -7
- scipy/spatial/_ckdtree.cpython-312-darwin.so +0 -0
- scipy/spatial/_distance_pybind.cpython-312-darwin.so +0 -0
- scipy/spatial/_distance_wrap.cpython-312-darwin.so +0 -0
- scipy/spatial/_hausdorff.cpython-312-darwin.so +0 -0
- scipy/spatial/_qhull.cpython-312-darwin.so +0 -0
- scipy/spatial/_voronoi.cpython-312-darwin.so +0 -0
- scipy/spatial/distance.py +49 -42
- scipy/spatial/tests/test_distance.py +15 -1
- scipy/spatial/tests/test_kdtree.py +1 -0
- scipy/spatial/tests/test_qhull.py +7 -2
- scipy/spatial/transform/__init__.py +5 -3
- scipy/spatial/transform/_rigid_transform.cpython-312-darwin.so +0 -0
- scipy/spatial/transform/_rotation.cpython-312-darwin.so +0 -0
- scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
- scipy/spatial/transform/tests/test_rotation.py +1213 -832
- scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
- scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
- scipy/special/__init__.py +1 -47
- scipy/special/_add_newdocs.py +34 -772
- scipy/special/_basic.py +22 -25
- scipy/special/_comb.cpython-312-darwin.so +0 -0
- scipy/special/_ellip_harm_2.cpython-312-darwin.so +0 -0
- scipy/special/_gufuncs.cpython-312-darwin.so +0 -0
- scipy/special/_logsumexp.py +67 -58
- scipy/special/_orthogonal.pyi +1 -1
- scipy/special/_specfun.cpython-312-darwin.so +0 -0
- scipy/special/_special_ufuncs.cpython-312-darwin.so +0 -0
- scipy/special/_spherical_bessel.py +4 -4
- scipy/special/_support_alternative_backends.py +212 -119
- scipy/special/_test_internal.cpython-312-darwin.so +0 -0
- scipy/special/_testutils.py +4 -4
- scipy/special/_ufuncs.cpython-312-darwin.so +0 -0
- scipy/special/_ufuncs.pyi +1 -0
- scipy/special/_ufuncs.pyx +215 -1400
- scipy/special/_ufuncs_cxx.cpython-312-darwin.so +0 -0
- scipy/special/_ufuncs_cxx.pxd +2 -15
- scipy/special/_ufuncs_cxx.pyx +5 -44
- scipy/special/_ufuncs_cxx_defs.h +2 -16
- scipy/special/_ufuncs_defs.h +0 -8
- scipy/special/cython_special.cpython-312-darwin.so +0 -0
- scipy/special/cython_special.pxd +1 -1
- scipy/special/tests/_cython_examples/meson.build +10 -1
- scipy/special/tests/test_basic.py +153 -20
- scipy/special/tests/test_boost_ufuncs.py +3 -0
- scipy/special/tests/test_cdflib.py +35 -11
- scipy/special/tests/test_gammainc.py +16 -0
- scipy/special/tests/test_hyp2f1.py +2 -2
- scipy/special/tests/test_log1mexp.py +85 -0
- scipy/special/tests/test_logsumexp.py +206 -64
- scipy/special/tests/test_mpmath.py +1 -0
- scipy/special/tests/test_nan_inputs.py +1 -1
- scipy/special/tests/test_orthogonal.py +17 -18
- scipy/special/tests/test_sf_error.py +3 -2
- scipy/special/tests/test_sph_harm.py +6 -7
- scipy/special/tests/test_support_alternative_backends.py +211 -76
- scipy/stats/__init__.py +4 -1
- scipy/stats/_ansari_swilk_statistics.cpython-312-darwin.so +0 -0
- scipy/stats/_axis_nan_policy.py +5 -12
- scipy/stats/_biasedurn.cpython-312-darwin.so +0 -0
- scipy/stats/_continued_fraction.py +387 -0
- scipy/stats/_continuous_distns.py +277 -310
- scipy/stats/_correlation.py +1 -1
- scipy/stats/_covariance.py +6 -3
- scipy/stats/_discrete_distns.py +39 -32
- scipy/stats/_distn_infrastructure.py +39 -12
- scipy/stats/_distribution_infrastructure.py +920 -238
- scipy/stats/_entropy.py +9 -10
- scipy/{_lib → stats}/_finite_differences.py +1 -1
- scipy/stats/_hypotests.py +83 -50
- scipy/stats/_kde.py +53 -49
- scipy/stats/_ksstats.py +1 -1
- scipy/stats/_levy_stable/__init__.py +7 -15
- scipy/stats/_levy_stable/levyst.cpython-312-darwin.so +0 -0
- scipy/stats/_morestats.py +118 -73
- scipy/stats/_mstats_basic.py +13 -17
- scipy/stats/_mstats_extras.py +8 -8
- scipy/stats/_multivariate.py +89 -113
- scipy/stats/_new_distributions.py +97 -20
- scipy/stats/_page_trend_test.py +12 -5
- scipy/stats/_probability_distribution.py +265 -43
- scipy/stats/_qmc.py +14 -9
- scipy/stats/_qmc_cy.cpython-312-darwin.so +0 -0
- scipy/stats/_qmvnt.py +16 -95
- scipy/stats/_qmvnt_cy.cpython-312-darwin.so +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/rcont.cpython-312-darwin.so +0 -0
- scipy/stats/_resampling.py +5 -30
- scipy/stats/_sampling.py +1 -1
- scipy/stats/_sobol.cpython-312-darwin.so +0 -0
- scipy/stats/_stats.cpython-312-darwin.so +0 -0
- scipy/stats/_stats_mstats_common.py +21 -2
- scipy/stats/_stats_py.py +551 -477
- scipy/stats/_stats_pythran.cpython-312-darwin.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.cpython-312-darwin.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
- scipy/stats/_variation.py +6 -8
- scipy/stats/_wilcoxon.py +13 -7
- scipy/stats/tests/common_tests.py +6 -4
- scipy/stats/tests/test_axis_nan_policy.py +62 -24
- scipy/stats/tests/test_continued_fraction.py +173 -0
- scipy/stats/tests/test_continuous.py +379 -60
- scipy/stats/tests/test_continuous_basic.py +18 -12
- scipy/stats/tests/test_discrete_basic.py +14 -8
- scipy/stats/tests/test_discrete_distns.py +16 -16
- scipy/stats/tests/test_distributions.py +95 -75
- scipy/stats/tests/test_entropy.py +40 -48
- scipy/stats/tests/test_fit.py +4 -3
- scipy/stats/tests/test_hypotests.py +153 -24
- scipy/stats/tests/test_kdeoth.py +109 -41
- scipy/stats/tests/test_marray.py +289 -0
- scipy/stats/tests/test_morestats.py +81 -49
- scipy/stats/tests/test_mstats_basic.py +3 -3
- scipy/stats/tests/test_multivariate.py +434 -83
- scipy/stats/tests/test_qmc.py +13 -10
- scipy/stats/tests/test_quantile.py +199 -0
- scipy/stats/tests/test_rank.py +119 -112
- scipy/stats/tests/test_resampling.py +47 -56
- scipy/stats/tests/test_sampling.py +9 -4
- scipy/stats/tests/test_stats.py +799 -939
- scipy/stats/tests/test_variation.py +8 -6
- scipy/version.py +2 -2
- {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/LICENSE.txt +4 -4
- {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/METADATA +11 -11
- {scipy-1.15.3.dist-info → scipy-1.16.0.dist-info}/RECORD +564 -571
- scipy-1.16.0.dist-info/WHEEL +6 -0
- scipy/_lib/array_api_extra/_funcs.py +0 -484
- scipy/_lib/array_api_extra/_typing.py +0 -8
- scipy/interpolate/_bspl.cpython-312-darwin.so +0 -0
- scipy/optimize/_cobyla.cpython-312-darwin.so +0 -0
- scipy/optimize/_cython_nnls.cpython-312-darwin.so +0 -0
- scipy/optimize/_slsqp.cpython-312-darwin.so +0 -0
- scipy/spatial/qhull_src/COPYING.txt +0 -38
- scipy/special/libsf_error_state.dylib +0 -0
- scipy/special/tests/test_log_softmax.py +0 -109
- scipy/special/tests/test_xsf_cuda.py +0 -114
- scipy/special/xsf/binom.h +0 -89
- scipy/special/xsf/cdflib.h +0 -100
- scipy/special/xsf/cephes/airy.h +0 -307
- scipy/special/xsf/cephes/besselpoly.h +0 -51
- scipy/special/xsf/cephes/beta.h +0 -257
- scipy/special/xsf/cephes/cbrt.h +0 -131
- scipy/special/xsf/cephes/chbevl.h +0 -85
- scipy/special/xsf/cephes/chdtr.h +0 -193
- scipy/special/xsf/cephes/const.h +0 -87
- scipy/special/xsf/cephes/ellie.h +0 -293
- scipy/special/xsf/cephes/ellik.h +0 -251
- scipy/special/xsf/cephes/ellpe.h +0 -107
- scipy/special/xsf/cephes/ellpk.h +0 -117
- scipy/special/xsf/cephes/expn.h +0 -260
- scipy/special/xsf/cephes/gamma.h +0 -398
- scipy/special/xsf/cephes/hyp2f1.h +0 -596
- scipy/special/xsf/cephes/hyperg.h +0 -361
- scipy/special/xsf/cephes/i0.h +0 -149
- scipy/special/xsf/cephes/i1.h +0 -158
- scipy/special/xsf/cephes/igam.h +0 -421
- scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
- scipy/special/xsf/cephes/igami.h +0 -313
- scipy/special/xsf/cephes/j0.h +0 -225
- scipy/special/xsf/cephes/j1.h +0 -198
- scipy/special/xsf/cephes/jv.h +0 -715
- scipy/special/xsf/cephes/k0.h +0 -164
- scipy/special/xsf/cephes/k1.h +0 -163
- scipy/special/xsf/cephes/kn.h +0 -243
- scipy/special/xsf/cephes/lanczos.h +0 -112
- scipy/special/xsf/cephes/ndtr.h +0 -275
- scipy/special/xsf/cephes/poch.h +0 -85
- scipy/special/xsf/cephes/polevl.h +0 -167
- scipy/special/xsf/cephes/psi.h +0 -194
- scipy/special/xsf/cephes/rgamma.h +0 -111
- scipy/special/xsf/cephes/scipy_iv.h +0 -811
- scipy/special/xsf/cephes/shichi.h +0 -248
- scipy/special/xsf/cephes/sici.h +0 -224
- scipy/special/xsf/cephes/sindg.h +0 -221
- scipy/special/xsf/cephes/tandg.h +0 -139
- scipy/special/xsf/cephes/trig.h +0 -58
- scipy/special/xsf/cephes/unity.h +0 -186
- scipy/special/xsf/cephes/zeta.h +0 -172
- scipy/special/xsf/config.h +0 -304
- scipy/special/xsf/digamma.h +0 -205
- scipy/special/xsf/error.h +0 -57
- scipy/special/xsf/evalpoly.h +0 -47
- scipy/special/xsf/expint.h +0 -266
- scipy/special/xsf/hyp2f1.h +0 -694
- scipy/special/xsf/iv_ratio.h +0 -173
- scipy/special/xsf/lambertw.h +0 -150
- scipy/special/xsf/loggamma.h +0 -163
- scipy/special/xsf/sici.h +0 -200
- scipy/special/xsf/tools.h +0 -427
- scipy/special/xsf/trig.h +0 -164
- scipy/special/xsf/wright_bessel.h +0 -843
- scipy/special/xsf/zlog1.h +0 -35
- scipy/stats/_mvn.cpython-312-darwin.so +0 -0
- scipy-1.15.3.dist-info/WHEEL +0 -4
scipy/conftest.py
CHANGED
@@ -4,6 +4,7 @@ import os
|
|
4
4
|
import warnings
|
5
5
|
import tempfile
|
6
6
|
from contextlib import contextmanager
|
7
|
+
from typing import Literal
|
7
8
|
|
8
9
|
import numpy as np
|
9
10
|
import numpy.testing as npt
|
@@ -11,8 +12,12 @@ import pytest
|
|
11
12
|
import hypothesis
|
12
13
|
|
13
14
|
from scipy._lib._fpumode import get_fpu_mode
|
15
|
+
from scipy._lib._array_api import (
|
16
|
+
SCIPY_ARRAY_API, SCIPY_DEVICE, array_namespace, default_xp,
|
17
|
+
is_cupy, is_dask, is_jax,
|
18
|
+
)
|
14
19
|
from scipy._lib._testutils import FPUModeChangeWarning
|
15
|
-
from scipy._lib.
|
20
|
+
from scipy._lib.array_api_extra.testing import patch_lazy_xp_functions
|
16
21
|
from scipy._lib import _pep440
|
17
22
|
|
18
23
|
try:
|
@@ -29,12 +34,31 @@ except Exception:
|
|
29
34
|
|
30
35
|
|
31
36
|
def pytest_configure(config):
|
37
|
+
"""
|
38
|
+
Add pytest markers to avoid PytestUnknownMarkWarning
|
39
|
+
|
40
|
+
This needs to contain all markers that are SciPy-specific, as well as
|
41
|
+
dummy fallbacks for markers defined in optional test packages.
|
42
|
+
|
43
|
+
Note that we need both the registration here *and* in `pytest.ini`.
|
44
|
+
"""
|
32
45
|
config.addinivalue_line("markers",
|
33
46
|
"slow: Tests that are very slow.")
|
34
47
|
config.addinivalue_line("markers",
|
35
48
|
"xslow: mark test as extremely slow (not run unless explicitly requested)")
|
36
49
|
config.addinivalue_line("markers",
|
37
50
|
"xfail_on_32bit: mark test as failing on 32-bit platforms")
|
51
|
+
config.addinivalue_line("markers",
|
52
|
+
"array_api_backends: test iterates on all array API backends")
|
53
|
+
config.addinivalue_line("markers",
|
54
|
+
("skip_xp_backends(backends, reason=None, np_only=False, cpu_only=False, " +
|
55
|
+
"eager_only=False, exceptions=None): mark the desired skip configuration " +
|
56
|
+
"for the `skip_xp_backends` fixture"))
|
57
|
+
config.addinivalue_line("markers",
|
58
|
+
("xfail_xp_backends(backends, reason=None, np_only=False, cpu_only=False, " +
|
59
|
+
"eager_only=False, exceptions=None): mark the desired xfail configuration " +
|
60
|
+
"for the `xfail_xp_backends` fixture"))
|
61
|
+
|
38
62
|
try:
|
39
63
|
import pytest_timeout # noqa:F401
|
40
64
|
except Exception:
|
@@ -47,14 +71,7 @@ def pytest_configure(config):
|
|
47
71
|
except Exception:
|
48
72
|
config.addinivalue_line(
|
49
73
|
"markers", 'fail_slow: mark a test for a non-default timeout failure')
|
50
|
-
|
51
|
-
"skip_xp_backends(backends, reason=None, np_only=False, cpu_only=False, "
|
52
|
-
"exceptions=None): "
|
53
|
-
"mark the desired skip configuration for the `skip_xp_backends` fixture.")
|
54
|
-
config.addinivalue_line("markers",
|
55
|
-
"xfail_xp_backends(backends, reason=None, np_only=False, cpu_only=False, "
|
56
|
-
"exceptions=None): "
|
57
|
-
"mark the desired xfail configuration for the `xfail_xp_backends` fixture.")
|
74
|
+
|
58
75
|
if not PARALLEL_RUN_AVAILABLE:
|
59
76
|
config.addinivalue_line(
|
60
77
|
'markers',
|
@@ -141,17 +158,21 @@ if not PARALLEL_RUN_AVAILABLE:
|
|
141
158
|
|
142
159
|
|
143
160
|
# Array API backend handling
|
161
|
+
xp_known_backends = {'numpy', 'array_api_strict', 'torch', 'cupy', 'jax.numpy',
|
162
|
+
'dask.array'}
|
144
163
|
xp_available_backends = {'numpy': np}
|
164
|
+
xp_skip_cpu_only_backends = set()
|
165
|
+
xp_skip_eager_only_backends = set()
|
145
166
|
|
146
|
-
if SCIPY_ARRAY_API
|
167
|
+
if SCIPY_ARRAY_API:
|
147
168
|
# fill the dict of backends with available libraries
|
148
169
|
try:
|
149
170
|
import array_api_strict
|
150
171
|
xp_available_backends.update({'array_api_strict': array_api_strict})
|
151
|
-
if _pep440.parse(array_api_strict.__version__) < _pep440.Version('2.
|
152
|
-
raise ImportError("array-api-strict must be >= version 2.
|
172
|
+
if _pep440.parse(array_api_strict.__version__) < _pep440.Version('2.3'):
|
173
|
+
raise ImportError("array-api-strict must be >= version 2.3")
|
153
174
|
array_api_strict.set_array_api_strict_flags(
|
154
|
-
api_version='
|
175
|
+
api_version='2024.12'
|
155
176
|
)
|
156
177
|
except ImportError:
|
157
178
|
pass
|
@@ -159,14 +180,35 @@ if SCIPY_ARRAY_API and isinstance(SCIPY_ARRAY_API, str):
|
|
159
180
|
try:
|
160
181
|
import torch # type: ignore[import-not-found]
|
161
182
|
xp_available_backends.update({'torch': torch})
|
162
|
-
# can use `mps` or `cpu`
|
163
183
|
torch.set_default_device(SCIPY_DEVICE)
|
184
|
+
if SCIPY_DEVICE != "cpu":
|
185
|
+
xp_skip_cpu_only_backends.add('torch')
|
186
|
+
|
187
|
+
# default to float64 unless explicitly requested
|
188
|
+
default = os.getenv('SCIPY_DEFAULT_DTYPE', default='float64')
|
189
|
+
if default == 'float64':
|
190
|
+
torch.set_default_dtype(torch.float64)
|
191
|
+
elif default != "float32":
|
192
|
+
raise ValueError(
|
193
|
+
"SCIPY_DEFAULT_DTYPE env var, if set, can only be either 'float64' "
|
194
|
+
f"or 'float32'. Got '{default}' instead."
|
195
|
+
)
|
164
196
|
except ImportError:
|
165
197
|
pass
|
166
198
|
|
167
199
|
try:
|
168
200
|
import cupy # type: ignore[import-not-found]
|
201
|
+
# Note: cupy disregards SCIPY_DEVICE and always runs on cuda.
|
202
|
+
# It will fail to import if you don't have CUDA hardware and drivers.
|
169
203
|
xp_available_backends.update({'cupy': cupy})
|
204
|
+
xp_skip_cpu_only_backends.add('cupy')
|
205
|
+
|
206
|
+
# this is annoying in CuPy 13.x
|
207
|
+
warnings.filterwarnings(
|
208
|
+
'ignore', 'cupyx.jit.rawkernel is experimental', category=FutureWarning
|
209
|
+
)
|
210
|
+
from cupyx.scipy import signal
|
211
|
+
del signal
|
170
212
|
except ImportError:
|
171
213
|
pass
|
172
214
|
|
@@ -175,16 +217,35 @@ if SCIPY_ARRAY_API and isinstance(SCIPY_ARRAY_API, str):
|
|
175
217
|
xp_available_backends.update({'jax.numpy': jax.numpy})
|
176
218
|
jax.config.update("jax_enable_x64", True)
|
177
219
|
jax.config.update("jax_default_device", jax.devices(SCIPY_DEVICE)[0])
|
220
|
+
if SCIPY_DEVICE != "cpu":
|
221
|
+
xp_skip_cpu_only_backends.add('jax.numpy')
|
222
|
+
# JAX can be eager or lazy (when wrapped in jax.jit). However it is
|
223
|
+
# recommended by upstream devs to assume it's always lazy.
|
224
|
+
xp_skip_eager_only_backends.add('jax.numpy')
|
225
|
+
except ImportError:
|
226
|
+
pass
|
227
|
+
|
228
|
+
try:
|
229
|
+
import dask.array as da
|
230
|
+
xp_available_backends.update({'dask.array': da})
|
231
|
+
# Dask can wrap around cupy. However, this is untested in scipy
|
232
|
+
# (and will almost surely not work as delegation will misbehave).
|
233
|
+
|
234
|
+
# Dask, strictly speaking, can be eager, in the sense that
|
235
|
+
# __array__, __bool__ etc. are implemented and do not raise.
|
236
|
+
# However, calling them triggers an extra computation of the whole graph
|
237
|
+
# until that point, which is highly destructive for performance.
|
238
|
+
xp_skip_eager_only_backends.add('dask.array')
|
178
239
|
except ImportError:
|
179
240
|
pass
|
180
241
|
|
181
242
|
# by default, use all available backends
|
182
|
-
if
|
243
|
+
if (
|
244
|
+
isinstance(SCIPY_ARRAY_API, str)
|
245
|
+
and SCIPY_ARRAY_API.lower() not in ("1", "true", "all")
|
246
|
+
):
|
183
247
|
SCIPY_ARRAY_API_ = json.loads(SCIPY_ARRAY_API)
|
184
|
-
|
185
|
-
if 'all' in SCIPY_ARRAY_API_:
|
186
|
-
pass # same as True
|
187
|
-
else:
|
248
|
+
if SCIPY_ARRAY_API_ != ['all']:
|
188
249
|
# only select a subset of backend by filtering out the dict
|
189
250
|
try:
|
190
251
|
xp_available_backends = {
|
@@ -192,166 +253,220 @@ if SCIPY_ARRAY_API and isinstance(SCIPY_ARRAY_API, str):
|
|
192
253
|
for backend in SCIPY_ARRAY_API_
|
193
254
|
}
|
194
255
|
except KeyError:
|
195
|
-
msg =
|
256
|
+
msg = ("'--array-api-backend' must be in "
|
257
|
+
f"{list(xp_available_backends)}; got {SCIPY_ARRAY_API_}")
|
196
258
|
raise ValueError(msg)
|
197
259
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
array_api_compatible = pytest.mark.parametrize("xp", xp_available_backends.values())
|
202
|
-
|
203
|
-
skip_xp_invalid_arg = pytest.mark.skipif(SCIPY_ARRAY_API,
|
204
|
-
reason = ('Test involves masked arrays, object arrays, or other types '
|
205
|
-
'that are not valid input when `SCIPY_ARRAY_API` is used.'))
|
260
|
+
assert not set(xp_available_backends) - xp_known_backends
|
261
|
+
xp_skip_np_only_backends = set(xp_available_backends) - {"numpy"}
|
206
262
|
|
207
263
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
# and we do not allow ('numpy', 'cupy')
|
215
|
-
raise ValueError(f"multiple backends: {args_}")
|
264
|
+
@pytest.fixture(params=[
|
265
|
+
pytest.param(v, id=k, marks=pytest.mark.array_api_backends)
|
266
|
+
for k, v in xp_available_backends.items()
|
267
|
+
])
|
268
|
+
def xp(request, monkeypatch):
|
269
|
+
"""Run the test that uses this fixture on each available array API library.
|
216
270
|
|
217
|
-
|
218
|
-
|
219
|
-
kwargs = {}
|
220
|
-
for marker in markers:
|
221
|
-
if marker.kwargs.get('np_only'):
|
222
|
-
kwargs['np_only'] = True
|
223
|
-
kwargs['exceptions'] = marker.kwargs.get('exceptions', [])
|
224
|
-
elif marker.kwargs.get('cpu_only'):
|
225
|
-
if not kwargs.get('np_only'):
|
226
|
-
# if np_only is given, it is certainly cpu only
|
227
|
-
kwargs['cpu_only'] = True
|
228
|
-
kwargs['exceptions'] = marker.kwargs.get('exceptions', [])
|
271
|
+
You can select all and only the tests that use the `xp` fixture by
|
272
|
+
passing `-m array_api_backends` to pytest.
|
229
273
|
|
230
|
-
|
231
|
-
|
232
|
-
backend = marker.args[0] # was a tuple, ('numpy',) etc
|
233
|
-
backends.append(backend)
|
234
|
-
kwargs.update(**{backend: marker.kwargs})
|
274
|
+
You can select where individual tests run through the `@skip_xp_backends`,
|
275
|
+
`@xfail_xp_backends`, and `@skip_xp_invalid_arg` pytest markers.
|
235
276
|
|
236
|
-
|
277
|
+
Please read: https://docs.scipy.org/doc/scipy/dev/api-dev/array_api.html#adding-tests
|
278
|
+
"""
|
279
|
+
# Read all @pytest.marks.skip_xp_backends markers that decorate to the test,
|
280
|
+
# if any, and raise pytest.skip() if the current xp is in the list.
|
281
|
+
skip_or_xfail_xp_backends(request, "skip")
|
282
|
+
# Read all @pytest.marks.xfail_xp_backends markers that decorate the test,
|
283
|
+
# if any, and raise pytest.xfail() if the current xp is in the list.
|
284
|
+
skip_or_xfail_xp_backends(request, "xfail")
|
285
|
+
|
286
|
+
xp = request.param
|
287
|
+
# Potentially wrap namespace with array_api_compat
|
288
|
+
xp = array_namespace(xp.empty(0))
|
289
|
+
|
290
|
+
if SCIPY_ARRAY_API:
|
291
|
+
# If request.param==jax.numpy, wrap tested functions in jax.jit
|
292
|
+
patch_lazy_xp_functions(
|
293
|
+
xp=request.param, request=request, monkeypatch=monkeypatch
|
294
|
+
)
|
237
295
|
|
296
|
+
# Throughout all calls to assert_almost_equal, assert_array_almost_equal, and
|
297
|
+
# xp_assert_* functions, test that the array namespace is xp in both the
|
298
|
+
# expected and actual arrays. This is to detect the case where both arrays are
|
299
|
+
# erroneously just plain numpy while xp is something else.
|
300
|
+
with default_xp(xp):
|
301
|
+
yield xp
|
302
|
+
else:
|
303
|
+
yield xp
|
238
304
|
|
239
|
-
@pytest.fixture
|
240
|
-
def skip_xp_backends(xp, request):
|
241
|
-
"""skip_xp_backends(backend=None, reason=None, np_only=False, cpu_only=False, exceptions=None)
|
242
305
|
|
243
|
-
|
306
|
+
skip_xp_invalid_arg = pytest.mark.skipif(SCIPY_ARRAY_API,
|
307
|
+
reason = ('Test involves masked arrays, object arrays, or other types '
|
308
|
+
'that are not valid input when `SCIPY_ARRAY_API` is used.'))
|
244
309
|
|
245
|
-
See ``skip_or_xfail_backends`` docstring for details. Note that, contrary to
|
246
|
-
``skip_or_xfail_backends``, the ``backend`` and ``reason`` arguments are optional
|
247
|
-
single strings: this function only skips a single backend at a time.
|
248
|
-
To skip multiple backends, provide multiple decorators.
|
249
|
-
""" # noqa: E501
|
250
|
-
if "skip_xp_backends" not in request.keywords:
|
251
|
-
return
|
252
310
|
|
253
|
-
|
254
|
-
|
311
|
+
def _backends_kwargs_from_request(request, skip_or_xfail):
|
312
|
+
"""A helper for {skip,xfail}_xp_backends.
|
255
313
|
|
314
|
+
Return dict of {backend to skip/xfail: top reason to skip/xfail it}
|
315
|
+
"""
|
316
|
+
markers = list(request.node.iter_markers(f'{skip_or_xfail}_xp_backends'))
|
317
|
+
reasons = {backend: [] for backend in xp_known_backends}
|
256
318
|
|
257
|
-
|
258
|
-
|
259
|
-
|
319
|
+
for marker in markers:
|
320
|
+
invalid_kwargs = set(marker.kwargs) - {
|
321
|
+
"cpu_only", "np_only", "eager_only", "reason", "exceptions"}
|
322
|
+
if invalid_kwargs:
|
323
|
+
raise TypeError(f"Invalid kwargs: {invalid_kwargs}")
|
324
|
+
|
325
|
+
exceptions = set(marker.kwargs.get('exceptions', []))
|
326
|
+
invalid_exceptions = exceptions - xp_known_backends
|
327
|
+
if (invalid_exceptions := list(exceptions - xp_known_backends)):
|
328
|
+
raise ValueError(f"Unknown backend(s): {invalid_exceptions}; "
|
329
|
+
f"must be a subset of {list(xp_known_backends)}")
|
330
|
+
|
331
|
+
if marker.kwargs.get('np_only', False):
|
332
|
+
reason = marker.kwargs.get("reason") or "do not run with non-NumPy backends"
|
333
|
+
for backend in xp_skip_np_only_backends - exceptions:
|
334
|
+
reasons[backend].append(reason)
|
335
|
+
|
336
|
+
elif marker.kwargs.get('cpu_only', False):
|
337
|
+
reason = marker.kwargs.get("reason") or (
|
338
|
+
"no array-agnostic implementation or delegation available "
|
339
|
+
"for this backend and device")
|
340
|
+
for backend in xp_skip_cpu_only_backends - exceptions:
|
341
|
+
reasons[backend].append(reason)
|
342
|
+
|
343
|
+
elif marker.kwargs.get('eager_only', False):
|
344
|
+
reason = marker.kwargs.get("reason") or (
|
345
|
+
"eager checks not executed on lazy backends")
|
346
|
+
for backend in xp_skip_eager_only_backends - exceptions:
|
347
|
+
reasons[backend].append(reason)
|
260
348
|
|
261
|
-
|
349
|
+
# add backends, if any
|
350
|
+
if len(marker.args) == 1:
|
351
|
+
backend = marker.args[0]
|
352
|
+
if backend not in xp_known_backends:
|
353
|
+
raise ValueError(f"Unknown backend: {backend}; "
|
354
|
+
f"must be one of {list(xp_known_backends)}")
|
355
|
+
reason = marker.kwargs.get("reason") or (
|
356
|
+
f"do not run with array API backend: {backend}")
|
357
|
+
# reason overrides the ones from cpu_only, np_only, and eager_only.
|
358
|
+
# This is regardless of order of appearence of the markers.
|
359
|
+
reasons[backend].insert(0, reason)
|
360
|
+
|
361
|
+
for kwarg in ("cpu_only", "np_only", "eager_only", "exceptions"):
|
362
|
+
if kwarg in marker.kwargs:
|
363
|
+
raise ValueError(f"{kwarg} is mutually exclusive with {backend}")
|
364
|
+
|
365
|
+
elif len(marker.args) > 1:
|
366
|
+
raise ValueError(
|
367
|
+
f"Please specify only one backend per marker: {marker.args}"
|
368
|
+
)
|
369
|
+
|
370
|
+
return {backend: backend_reasons[0]
|
371
|
+
for backend, backend_reasons in reasons.items()
|
372
|
+
if backend_reasons}
|
373
|
+
|
374
|
+
|
375
|
+
def skip_or_xfail_xp_backends(request: pytest.FixtureRequest,
|
376
|
+
skip_or_xfail: Literal['skip', 'xfail']) -> None:
|
377
|
+
"""
|
378
|
+
Helper of the `xp` fixture.
|
379
|
+
Skip or xfail based on the ``skip_xp_backends`` or ``xfail_xp_backends`` markers.
|
262
380
|
|
263
|
-
See
|
264
|
-
``skip_or_xfail_backends``, the ``backend`` and ``reason`` arguments are optional
|
265
|
-
single strings: this function only xfails a single backend at a time.
|
266
|
-
To xfail multiple backends, provide multiple decorators.
|
267
|
-
""" # noqa: E501
|
268
|
-
if "xfail_xp_backends" not in request.keywords:
|
269
|
-
return
|
270
|
-
backends, kwargs = _backends_kwargs_from_request(request, skip_or_xfail='xfail')
|
271
|
-
skip_or_xfail_xp_backends(xp, backends, kwargs, skip_or_xfail='xfail')
|
381
|
+
See the "Support for the array API standard" docs page for usage examples.
|
272
382
|
|
383
|
+
Usage
|
384
|
+
-----
|
385
|
+
::
|
386
|
+
skip_xp_backends = pytest.mark.skip_xp_backends
|
387
|
+
xfail_xp_backends = pytest.mark.xfail_xp_backends
|
388
|
+
...
|
273
389
|
|
274
|
-
|
275
|
-
|
276
|
-
|
390
|
+
@skip_xp_backends(backend, *, reason=None)
|
391
|
+
@skip_xp_backends(*, cpu_only=True, exceptions=(), reason=None)
|
392
|
+
@skip_xp_backends(*, eager_only=True, exceptions=(), reason=None)
|
393
|
+
@skip_xp_backends(*, np_only=True, exceptions=(), reason=None)
|
277
394
|
|
278
|
-
|
395
|
+
@xfail_xp_backends(backend, *, reason=None)
|
396
|
+
@xfail_xp_backends(*, cpu_only=True, exceptions=(), reason=None)
|
397
|
+
@xfail_xp_backends(*, eager_only=True, exceptions=(), reason=None)
|
398
|
+
@xfail_xp_backends(*, np_only=True, exceptions=(), reason=None)
|
279
399
|
|
280
400
|
Parameters
|
281
401
|
----------
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
402
|
+
backend : str, optional
|
403
|
+
Backend to skip/xfail, e.g. ``"torch"``.
|
404
|
+
Mutually exclusive with ``cpu_only``, ``eager_only``, and ``np_only``.
|
405
|
+
cpu_only : bool, optional
|
406
|
+
When ``True``, the test is skipped/xfailed on non-CPU devices,
|
407
|
+
minus exceptions. Mutually exclusive with ``backend``.
|
408
|
+
eager_only : bool, optional
|
409
|
+
When ``True``, the test is skipped/xfailed for lazy backends, e.g. those
|
410
|
+
with major caveats when invoking ``__array__``, ``__bool__``, ``__float__``,
|
411
|
+
or ``__complex__``, minus exceptions. Mutually exclusive with ``backend``.
|
292
412
|
np_only : bool, optional
|
293
413
|
When ``True``, the test is skipped/xfailed for all backends other
|
294
|
-
than the default NumPy backend
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
but any ``backends`` will also be skipped on the CPU.
|
301
|
-
Default: ``False``.
|
302
|
-
exceptions : list, optional
|
303
|
-
A list of exceptions for use with ``cpu_only`` or ``np_only``.
|
414
|
+
than the default NumPy backend and the exceptions.
|
415
|
+
Mutually exclusive with ``backend``. Implies ``cpu_only`` and ``eager_only``.
|
416
|
+
reason : str, optional
|
417
|
+
A reason for the skip/xfail. If omitted, a default reason is used.
|
418
|
+
exceptions : list[str], optional
|
419
|
+
A list of exceptions for use with ``cpu_only``, ``eager_only``, or ``np_only``.
|
304
420
|
This should be provided when delegation is implemented for some,
|
305
421
|
but not all, non-CPU/non-NumPy backends.
|
306
|
-
skip_or_xfail : str
|
307
|
-
``'skip'`` to skip, ``'xfail'`` to xfail.
|
308
422
|
"""
|
309
|
-
skip_or_xfail
|
310
|
-
np_only = kwargs.get("np_only", False)
|
311
|
-
cpu_only = kwargs.get("cpu_only", False)
|
312
|
-
exceptions = kwargs.get("exceptions", [])
|
313
|
-
|
314
|
-
if reasons := kwargs.get("reasons"):
|
315
|
-
raise ValueError(f"provide a single `reason=` kwarg; got {reasons=} instead")
|
316
|
-
|
317
|
-
# input validation
|
318
|
-
if np_only and cpu_only:
|
319
|
-
# np_only is a stricter subset of cpu_only
|
320
|
-
cpu_only = False
|
321
|
-
if exceptions and not (cpu_only or np_only):
|
322
|
-
raise ValueError("`exceptions` is only valid alongside `cpu_only` or `np_only`")
|
323
|
-
|
324
|
-
if np_only:
|
325
|
-
reason = kwargs.get("reason", "do not run with non-NumPy backends.")
|
326
|
-
if not isinstance(reason, str) and len(reason) > 1:
|
327
|
-
raise ValueError("please provide a singleton `reason` "
|
328
|
-
"when using `np_only`")
|
329
|
-
if xp.__name__ != 'numpy' and xp.__name__ not in exceptions:
|
330
|
-
skip_or_xfail(reason=reason)
|
423
|
+
if f"{skip_or_xfail}_xp_backends" not in request.keywords:
|
331
424
|
return
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
425
|
+
|
426
|
+
skip_xfail_reasons = _backends_kwargs_from_request(
|
427
|
+
request, skip_or_xfail=skip_or_xfail
|
428
|
+
)
|
429
|
+
xp = request.param
|
430
|
+
if xp.__name__ in skip_xfail_reasons:
|
431
|
+
reason = skip_xfail_reasons[xp.__name__]
|
432
|
+
assert reason # Default reason applied above
|
433
|
+
skip_or_xfail = getattr(pytest, skip_or_xfail)
|
434
|
+
skip_or_xfail(reason=reason)
|
435
|
+
|
436
|
+
|
437
|
+
@pytest.fixture
|
438
|
+
def devices(xp):
|
439
|
+
"""Fixture that returns a list of all devices for the backend, plus None.
|
440
|
+
Used to test input->output device propagation.
|
441
|
+
|
442
|
+
Usage
|
443
|
+
-----
|
444
|
+
from scipy._lib._array_api import xp_device
|
445
|
+
|
446
|
+
def test_device(xp, devices):
|
447
|
+
for d in devices:
|
448
|
+
x = xp.asarray(..., device=d)
|
449
|
+
y = f(x)
|
450
|
+
assert xp_device(y) == xp_device(x)
|
451
|
+
"""
|
452
|
+
if is_cupy(xp):
|
453
|
+
# CuPy does not support devices other than the current one
|
454
|
+
# data-apis/array-api-compat#293
|
455
|
+
pytest.xfail(reason="data-apis/array-api-compat#293")
|
456
|
+
if is_dask(xp):
|
457
|
+
# Skip dummy DASK_DEVICE from array-api-compat, which does not propagate
|
458
|
+
return ["cpu", None]
|
459
|
+
if is_jax(xp):
|
460
|
+
# The .device attribute is not accessible inside jax.jit; the consequence
|
461
|
+
# (downstream of array-api-compat hacks) is that a non-default device in
|
462
|
+
# input is not guaranteed to propagate to the output even if the scipy code
|
463
|
+
# states `device=xp_device(arg)`` in all array creation functions.
|
464
|
+
# While this issue is specific to jax.jit, it would be unnecessarily
|
465
|
+
# verbose to skip the test for each jit-capable function and run it for
|
466
|
+
# those that only support eager mode.
|
467
|
+
pytest.xfail(reason="jax-ml/jax#26000")
|
468
|
+
|
469
|
+
return xp.__array_namespace_info__().devices() + [None]
|
355
470
|
|
356
471
|
|
357
472
|
# Following the approach of NumPy's conftest.py...
|
@@ -521,12 +636,25 @@ if HAVE_SCPDT:
|
|
521
636
|
# equivalent to "pytest --ignore=path/to/file"
|
522
637
|
"scipy/special/_precompute",
|
523
638
|
"scipy/interpolate/_interpnd_info.py",
|
639
|
+
"scipy/interpolate/_rbfinterp_pythran.py",
|
640
|
+
"scipy/_build_utils/tempita.py",
|
524
641
|
"scipy/_lib/array_api_compat",
|
525
642
|
"scipy/_lib/highs",
|
526
643
|
"scipy/_lib/unuran",
|
527
644
|
"scipy/_lib/_gcutils.py",
|
528
645
|
"scipy/_lib/doccer.py",
|
529
646
|
"scipy/_lib/_uarray",
|
647
|
+
"scipy/linalg/_cython_signature_generator.py",
|
648
|
+
"scipy/linalg/_generate_pyx.py",
|
649
|
+
"scipy/linalg/_linalg_pythran.py",
|
650
|
+
"scipy/linalg/_matfuncs_sqrtm_triu.py",
|
651
|
+
"scipy/ndimage/utils/generate_label_testvectors.py",
|
652
|
+
"scipy/optimize/_group_columns.py",
|
653
|
+
"scipy/optimize/_max_len_seq_inner.py",
|
654
|
+
"scipy/signal/_max_len_seq_inner.py",
|
655
|
+
"scipy/sparse/_generate_sparsetools.py",
|
656
|
+
"scipy/special/_generate_pyx.py",
|
657
|
+
"scipy/stats/_stats_pythran.py",
|
530
658
|
]
|
531
659
|
|
532
660
|
dt_config.pytest_extra_xfail = {
|
@@ -549,4 +677,7 @@ if HAVE_SCPDT:
|
|
549
677
|
}
|
550
678
|
|
551
679
|
dt_config.strict_check = True
|
680
|
+
|
681
|
+
# ignore Matplotlib's `ax.text`:
|
682
|
+
dt_config.stopwords.add('.text(')
|
552
683
|
############################################################################
|
scipy/constants/_constants.py
CHANGED
@@ -15,7 +15,7 @@ from ._codata import value as _cd
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
import numpy.typing as npt
|
17
17
|
|
18
|
-
from scipy._lib._array_api import array_namespace, _asarray
|
18
|
+
from scipy._lib._array_api import array_namespace, _asarray, xp_capabilities
|
19
19
|
|
20
20
|
|
21
21
|
"""
|
@@ -225,6 +225,7 @@ kgf = kilogram_force = g # * 1 kg
|
|
225
225
|
# functions for conversions that are not linear
|
226
226
|
|
227
227
|
|
228
|
+
@xp_capabilities()
|
228
229
|
def convert_temperature(
|
229
230
|
val: "npt.ArrayLike",
|
230
231
|
old_scale: str,
|
@@ -304,6 +305,7 @@ def convert_temperature(
|
|
304
305
|
# optics
|
305
306
|
|
306
307
|
|
308
|
+
@xp_capabilities()
|
307
309
|
def lambda2nu(lambda_: "npt.ArrayLike") -> Any:
|
308
310
|
"""
|
309
311
|
Convert wavelength to optical frequency
|
@@ -335,6 +337,7 @@ def lambda2nu(lambda_: "npt.ArrayLike") -> Any:
|
|
335
337
|
return c / _asarray(lambda_, xp=xp, subok=True)
|
336
338
|
|
337
339
|
|
340
|
+
@xp_capabilities()
|
338
341
|
def nu2lambda(nu: "npt.ArrayLike") -> Any:
|
339
342
|
"""
|
340
343
|
Convert optical frequency to wavelength.
|
@@ -31,8 +31,8 @@ def test_basic_table_parse():
|
|
31
31
|
|
32
32
|
|
33
33
|
def test_basic_lookup():
|
34
|
-
assert_equal('
|
35
|
-
|
34
|
+
assert_equal('{} {}'.format(int(_cd.value('speed of light in vacuum')),
|
35
|
+
_cd.unit('speed of light in vacuum')),
|
36
36
|
'299792458 m s^-1')
|
37
37
|
|
38
38
|
|