scipy 1.15.2__cp313-cp313-win_amd64.whl → 1.16.0rc1__cp313-cp313-win_amd64.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/__config__.py +7 -7
- scipy/__init__.py +6 -9
- scipy/_cyutility.cp313-win_amd64.dll.a +0 -0
- scipy/_cyutility.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_array_api.py +497 -161
- scipy/_lib/_array_api_compat_vendor.py +9 -0
- scipy/_lib/_bunch.py +4 -0
- scipy/_lib/_ccallback_c.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_ccallback_c.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_docscrape.py +1 -1
- scipy/_lib/_elementwise_iterative_method.py +15 -26
- scipy/_lib/_fpumode.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_fpumode.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_ccallback.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_test_ccallback.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_test_deprecation_call.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_test_deprecation_def.cp313-win_amd64.pyd +0 -0
- scipy/_lib/_testutils.py +6 -2
- scipy/_lib/_uarray/_uarray.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/_uarray/_uarray.cp313-win_amd64.pyd +0 -0
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/_lib/messagestream.cp313-win_amd64.pyd +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 +169 -34
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/cluster/_hierarchy.cp313-win_amd64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.dll.a +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp313-win_amd64.pyd +0 -0
- scipy/cluster/_vq.cp313-win_amd64.dll.a +0 -0
- scipy/cluster/_vq.cp313-win_amd64.pyd +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 +263 -157
- 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/pypocketfft.cp313-win_amd64.dll.a +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp313-win_amd64.pyd +0 -0
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/fftpack/convolve.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_dop.cp313-win_amd64.pyd +0 -0
- scipy/integrate/_ivp/common.py +3 -3
- scipy/integrate/_ivp/ivp.py +9 -2
- scipy/integrate/_ivp/tests/test_ivp.py +19 -0
- scipy/integrate/_lsoda.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_lsoda.cp313-win_amd64.pyd +0 -0
- scipy/integrate/_ode.py +9 -2
- scipy/integrate/_odepack.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_odepack.cp313-win_amd64.pyd +0 -0
- scipy/integrate/_quad_vec.py +21 -29
- scipy/integrate/_quadpack.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_quadpack.cp313-win_amd64.pyd +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 +57 -54
- scipy/integrate/_test_multivariate.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_test_multivariate.cp313-win_amd64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_test_odeint_banded.cp313-win_amd64.pyd +0 -0
- scipy/integrate/_vode.cp313-win_amd64.dll.a +0 -0
- scipy/integrate/_vode.cp313-win_amd64.pyd +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 +61 -43
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_dfitpack.cp313-win_amd64.pyd +0 -0
- scipy/interpolate/_dierckx.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_dierckx.cp313-win_amd64.pyd +0 -0
- scipy/interpolate/_fitpack.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_fitpack.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_interpnd.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_ppoly.cp313-win_amd64.pyd +0 -0
- scipy/interpolate/_rbf.py +2 -2
- scipy/interpolate/_rbfinterp.py +1 -1
- scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp313-win_amd64.pyd +0 -0
- scipy/interpolate/_rgi.py +31 -26
- scipy/interpolate/_rgi_cython.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_rgi_cython.cp313-win_amd64.pyd +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/_fast_matrix_market/_fmm_core.cp313-win_amd64.dll.a +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp313-win_amd64.pyd +0 -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.cp313-win_amd64.dll.a +0 -0
- scipy/io/_test_fortran.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/io/matlab/_mio5_utils.cp313-win_amd64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp313-win_amd64.dll.a +0 -0
- scipy/io/matlab/_mio_utils.cp313-win_amd64.pyd +0 -0
- scipy/io/matlab/_miobase.py +4 -1
- scipy/io/matlab/_streams.cp313-win_amd64.dll.a +0 -0
- scipy/io/matlab/_streams.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_cythonized_array_utils.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_interpolative.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +4 -1
- scipy/linalg/_decomp_lu.py +18 -6
- scipy/linalg/_decomp_lu_cython.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_lu_cython.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_update.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +4 -0
- scipy/linalg/_fblas.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_fblas.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_flapack.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_flapack.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_linalg_pythran.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_linalg_pythran.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs.py +187 -4
- scipy/linalg/_matfuncs_expm.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_expm.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +1 -99
- scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_procrustes.py +2 -0
- scipy/linalg/_sketches.py +17 -6
- scipy/linalg/_solve_toeplitz.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/_solve_toeplitz.cp313-win_amd64.pyd +0 -0
- scipy/linalg/_solvers.py +7 -2
- scipy/linalg/_special_matrices.py +26 -36
- scipy/linalg/cython_blas.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/cython_blas.cp313-win_amd64.pyd +0 -0
- scipy/linalg/cython_lapack.cp313-win_amd64.dll.a +0 -0
- scipy/linalg/cython_lapack.cp313-win_amd64.pyd +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_interpolative.py +17 -0
- 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/_ctest.cp313-win_amd64.dll.a +0 -0
- scipy/ndimage/_ctest.cp313-win_amd64.pyd +0 -0
- scipy/ndimage/_cytest.cp313-win_amd64.dll.a +0 -0
- scipy/ndimage/_cytest.cp313-win_amd64.pyd +0 -0
- scipy/ndimage/_delegators.py +8 -2
- scipy/ndimage/_filters.py +433 -5
- scipy/ndimage/_interpolation.py +36 -6
- scipy/ndimage/_measurements.py +4 -2
- scipy/ndimage/_morphology.py +5 -0
- scipy/ndimage/_nd_image.cp313-win_amd64.dll.a +0 -0
- scipy/ndimage/_nd_image.cp313-win_amd64.pyd +0 -0
- scipy/ndimage/_ndimage_api.py +2 -1
- scipy/ndimage/_ni_docstrings.py +5 -1
- scipy/ndimage/_ni_label.cp313-win_amd64.dll.a +0 -0
- scipy/ndimage/_ni_label.cp313-win_amd64.pyd +0 -0
- scipy/ndimage/_ni_support.py +1 -5
- scipy/ndimage/_rank_filter_1d.cp313-win_amd64.dll.a +0 -0
- scipy/ndimage/_rank_filter_1d.cp313-win_amd64.pyd +0 -0
- scipy/ndimage/_support_alternative_backends.py +18 -6
- scipy/ndimage/tests/test_filters.py +351 -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.cp313-win_amd64.dll.a +0 -0
- scipy/odr/__odrpack.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_basinhopping.py +13 -7
- scipy/optimize/_bglu_dense.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_bglu_dense.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_bracket.py +46 -26
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_direct.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_dual_annealing.py +1 -1
- scipy/optimize/_elementwise.py +1 -4
- scipy/optimize/_group_columns.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_group_columns.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_highspy/_core.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_highspy/_core.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_highspy/_highs_options.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_highspy/_highs_wrapper.py +6 -4
- scipy/optimize/_lbfgsb.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_lbfgsb.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_lbfgsb_py.py +57 -16
- scipy/optimize/_linprog_doc.py +2 -2
- scipy/optimize/_linprog_highs.py +11 -11
- scipy/optimize/_linprog_ip.py +25 -10
- scipy/optimize/_linprog_util.py +18 -19
- scipy/optimize/_lsap.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_lsap.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_lsq/common.py +3 -3
- scipy/optimize/_lsq/dogbox.py +16 -2
- scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_lsq/givens_elimination.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_minpack.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_minpack_py.py +21 -14
- scipy/optimize/_moduleTNC.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_moduleTNC.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_pava_pybind.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_slsqplib.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_spectral.py +1 -1
- scipy/optimize/_tnc.py +8 -1
- scipy/optimize/_trlib/_trlib.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_trlib/_trlib.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_zeros.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_zeros_py.py +97 -17
- scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/cython_optimize/_zeros.cp313-win_amd64.pyd +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 +71 -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 +5 -5
- 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 +95 -17
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_max_len_seq_inner.cp313-win_amd64.pyd +0 -0
- scipy/signal/_peak_finding_utils.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_peak_finding_utils.cp313-win_amd64.pyd +0 -0
- scipy/signal/_polyutils.py +172 -0
- scipy/signal/_short_time_fft.py +553 -76
- scipy/signal/_signal_api.py +30 -0
- scipy/signal/_signaltools.py +719 -396
- scipy/signal/_sigtools.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_sigtools.cp313-win_amd64.pyd +0 -0
- scipy/signal/_sosfilt.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_sosfilt.cp313-win_amd64.pyd +0 -0
- scipy/signal/_spectral_py.py +221 -50
- scipy/signal/_spline.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_spline.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/signal/_upfirdn_apply.cp313-win_amd64.pyd +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 +5 -182
- 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 +231 -5
- scipy/signal/tests/test_signaltools.py +2149 -1348
- scipy/signal/tests/test_spectral.py +19 -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 +269 -120
- scipy/sparse/_bsr.py +7 -4
- scipy/sparse/_compressed.py +59 -234
- scipy/sparse/_construct.py +90 -38
- scipy/sparse/_coo.py +115 -181
- scipy/sparse/_csc.py +4 -4
- scipy/sparse/_csparsetools.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/_csparsetools.cp313-win_amd64.pyd +0 -0
- scipy/sparse/_csr.py +2 -2
- scipy/sparse/_data.py +48 -48
- scipy/sparse/_dia.py +105 -21
- scipy/sparse/_dok.py +0 -23
- scipy/sparse/_index.py +4 -4
- scipy/sparse/_matrix.py +23 -0
- scipy/sparse/_sparsetools.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/_sparsetools.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_flow.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_matching.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_matching.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_reordering.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_shortest_path.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_tools.cp313-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_traversal.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp313-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_eigen/arpack/arpack.py +28 -20
- scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
- scipy/sparse/linalg/_expm_multiply.py +8 -3
- scipy/sparse/linalg/_interface.py +29 -26
- scipy/sparse/linalg/_isolve/_gcrotmk.py +6 -5
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp313-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp313-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp313-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp313-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
- scipy/sparse/linalg/tests/test_expm_multiply.py +10 -0
- scipy/sparse/linalg/tests/test_interface.py +35 -0
- scipy/sparse/linalg/tests/test_pydata_sparse.py +18 -0
- scipy/sparse/tests/test_arithmetic1d.py +5 -2
- scipy/sparse/tests/test_base.py +217 -40
- scipy/sparse/tests/test_common1d.py +17 -12
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_ckdtree.cp313-win_amd64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_distance_pybind.cp313-win_amd64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_distance_wrap.cp313-win_amd64.pyd +0 -0
- scipy/spatial/_hausdorff.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_hausdorff.cp313-win_amd64.pyd +0 -0
- scipy/spatial/_qhull.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_qhull.cp313-win_amd64.pyd +0 -0
- scipy/spatial/_voronoi.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/_voronoi.cp313-win_amd64.pyd +0 -0
- scipy/spatial/distance.py +49 -42
- scipy/spatial/tests/test_distance.py +3 -1
- scipy/spatial/tests/test_kdtree.py +1 -0
- scipy/spatial/tests/test_qhull.py +106 -2
- scipy/spatial/transform/__init__.py +5 -3
- scipy/spatial/transform/_rigid_transform.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/transform/_rigid_transform.cp313-win_amd64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp313-win_amd64.dll.a +0 -0
- scipy/spatial/transform/_rotation.cp313-win_amd64.pyd +0 -0
- scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
- scipy/spatial/transform/tests/test_rotation.py +1342 -790
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/special/_comb.cp313-win_amd64.pyd +0 -0
- scipy/special/_ellip_harm_2.cp313-win_amd64.dll.a +0 -0
- scipy/special/_ellip_harm_2.cp313-win_amd64.pyd +0 -0
- scipy/special/_gufuncs.cp313-win_amd64.dll.a +0 -0
- scipy/special/_gufuncs.cp313-win_amd64.pyd +0 -0
- scipy/special/_logsumexp.py +83 -69
- scipy/special/_orthogonal.pyi +1 -1
- scipy/special/_specfun.cp313-win_amd64.dll.a +0 -0
- scipy/special/_specfun.cp313-win_amd64.pyd +0 -0
- scipy/special/_special_ufuncs.cp313-win_amd64.dll.a +0 -0
- scipy/special/_special_ufuncs.cp313-win_amd64.pyd +0 -0
- scipy/special/_spherical_bessel.py +4 -4
- scipy/special/_support_alternative_backends.py +212 -119
- scipy/special/_test_internal.cp313-win_amd64.dll.a +0 -0
- scipy/special/_test_internal.cp313-win_amd64.pyd +0 -0
- scipy/special/_testutils.py +4 -4
- scipy/special/_ufuncs.cp313-win_amd64.dll.a +0 -0
- scipy/special/_ufuncs.cp313-win_amd64.pyd +0 -0
- scipy/special/_ufuncs.pyi +1 -0
- scipy/special/_ufuncs.pyx +215 -1400
- scipy/special/_ufuncs_cxx.cp313-win_amd64.dll.a +0 -0
- scipy/special/_ufuncs_cxx.cp313-win_amd64.pyd +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.cp313-win_amd64.dll.a +0 -0
- scipy/special/cython_special.cp313-win_amd64.pyd +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 +23 -2
- scipy/special/tests/test_log1mexp.py +85 -0
- scipy/special/tests/test_logsumexp.py +220 -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.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_ansari_swilk_statistics.cp313-win_amd64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +4 -3
- scipy/stats/_biasedurn.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_biasedurn.cp313-win_amd64.pyd +0 -0
- scipy/stats/_continued_fraction.py +387 -0
- scipy/stats/_continuous_distns.py +296 -319
- 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 +900 -238
- scipy/stats/_entropy.py +7 -8
- scipy/{_lib → stats}/_finite_differences.py +1 -1
- scipy/stats/_hypotests.py +82 -49
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_levy_stable/levyst.cp313-win_amd64.pyd +0 -0
- scipy/stats/_morestats.py +112 -67
- 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.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_qmc_cy.cp313-win_amd64.pyd +0 -0
- scipy/stats/_qmvnt.py +16 -95
- scipy/stats/_qmvnt_cy.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_qmvnt_cy.cp313-win_amd64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/rcont.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_rcont/rcont.cp313-win_amd64.pyd +0 -0
- scipy/stats/_resampling.py +4 -29
- scipy/stats/_sampling.py +1 -1
- scipy/stats/_sobol.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_sobol.cp313-win_amd64.pyd +0 -0
- scipy/stats/_stats.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_stats.cp313-win_amd64.pyd +0 -0
- scipy/stats/_stats_mstats_common.py +19 -2
- scipy/stats/_stats_py.py +534 -460
- scipy/stats/_stats_pythran.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_stats_pythran.cp313-win_amd64.pyd +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp313-win_amd64.pyd +0 -0
- scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
- scipy/stats/_variation.py +5 -7
- 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 +117 -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 +79 -47
- 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.16.0rc1.dist-info/DELVEWHEEL +2 -0
- {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/LICENSE.txt +1 -1
- {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/METADATA +9 -9
- {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/RECORD +693 -701
- scipy/_lib/array_api_extra/_funcs.py +0 -484
- scipy/_lib/array_api_extra/_typing.py +0 -8
- scipy/interpolate/_bspl.cp313-win_amd64.dll.a +0 -0
- scipy/interpolate/_bspl.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_cobyla.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_cobyla.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_cython_nnls.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_cython_nnls.cp313-win_amd64.pyd +0 -0
- scipy/optimize/_slsqp.cp313-win_amd64.dll.a +0 -0
- scipy/optimize/_slsqp.cp313-win_amd64.pyd +0 -0
- scipy/spatial/qhull_src/COPYING.txt +0 -38
- scipy/special/libsf_error_state.dll +0 -0
- scipy/special/libsf_error_state.dll.a +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.cp313-win_amd64.dll.a +0 -0
- scipy/stats/_mvn.cp313-win_amd64.pyd +0 -0
- scipy-1.15.2.dist-info/DELVEWHEEL +0 -2
- /scipy-1.15.2-cp313-cp313-win_amd64.whl → /scipy-1.16.0rc1-cp313-cp313-win_amd64.whl +0 -0
- {scipy-1.15.2.dist-info → scipy-1.16.0rc1.dist-info}/WHEEL +0 -0
@@ -2,10 +2,14 @@
|
|
2
2
|
import functools
|
3
3
|
import itertools
|
4
4
|
import re
|
5
|
+
import contextlib
|
5
6
|
|
6
7
|
import numpy as np
|
7
8
|
import pytest
|
8
9
|
from numpy.testing import suppress_warnings, assert_allclose, assert_array_equal
|
10
|
+
from hypothesis import strategies as st
|
11
|
+
from hypothesis import given
|
12
|
+
import hypothesis.extra.numpy as npst
|
9
13
|
from pytest import raises as assert_raises
|
10
14
|
from scipy import ndimage
|
11
15
|
from scipy._lib._array_api import (
|
@@ -14,8 +18,8 @@ from scipy._lib._array_api import (
|
|
14
18
|
xp_assert_close,
|
15
19
|
xp_assert_equal,
|
16
20
|
)
|
17
|
-
from scipy._lib._array_api import is_cupy,
|
18
|
-
|
21
|
+
from scipy._lib._array_api import (is_cupy, is_torch, is_dask, is_jax, array_namespace,
|
22
|
+
is_array_api_strict, xp_copy)
|
19
23
|
from scipy.ndimage._filters import _gaussian_kernel1d
|
20
24
|
|
21
25
|
from . import types, float_types, complex_types
|
@@ -23,9 +27,18 @@ from . import types, float_types, complex_types
|
|
23
27
|
|
24
28
|
skip_xp_backends = pytest.mark.skip_xp_backends
|
25
29
|
xfail_xp_backends = pytest.mark.xfail_xp_backends
|
26
|
-
pytestmark = [
|
27
|
-
|
28
|
-
|
30
|
+
pytestmark = [skip_xp_backends(cpu_only=True, exceptions=['cupy', 'jax.numpy'])]
|
31
|
+
|
32
|
+
uses_output_dtype = skip_xp_backends(
|
33
|
+
np_only=True, exceptions=["cupy"],
|
34
|
+
reason="output=dtype is numpy-specific"
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
def uses_output_array(f):
|
39
|
+
return skip_xp_backends("dask.array", reason="output=array requires buffer view")(
|
40
|
+
skip_xp_backends("jax.numpy", reason="output=array requires buffer view")(f))
|
41
|
+
|
29
42
|
|
30
43
|
|
31
44
|
def sumsq(a, b, xp=None):
|
@@ -41,9 +54,8 @@ def _complex_correlate(xp, array, kernel, real_dtype, convolve=False,
|
|
41
54
|
"""
|
42
55
|
array = xp.asarray(array)
|
43
56
|
kernel = xp.asarray(kernel)
|
44
|
-
|
45
|
-
|
46
|
-
complex_kernel = isdtype(kernel.dtype, 'complex floating')
|
57
|
+
complex_array = xp.isdtype(array.dtype, 'complex floating')
|
58
|
+
complex_kernel = xp.isdtype(kernel.dtype, 'complex floating')
|
47
59
|
if array.ndim == 1:
|
48
60
|
func = ndimage.convolve1d if convolve else ndimage.correlate1d
|
49
61
|
else:
|
@@ -194,7 +206,7 @@ class TestNdimageFilters:
|
|
194
206
|
assert_array_almost_equal(output, expected)
|
195
207
|
|
196
208
|
@xfail_xp_backends('cupy', reason="Differs by a factor of two?")
|
197
|
-
@
|
209
|
+
@uses_output_array
|
198
210
|
def test_correlate01_overlap(self, xp):
|
199
211
|
array = xp.reshape(xp.arange(256), (16, 16))
|
200
212
|
weights = xp.asarray([2])
|
@@ -345,9 +357,7 @@ class TestNdimageFilters:
|
|
345
357
|
output = ndimage.convolve(array, kernel)
|
346
358
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
347
359
|
|
348
|
-
@
|
349
|
-
reason="output=dtype is numpy-specific",
|
350
|
-
exceptions=['cupy'],)
|
360
|
+
@uses_output_dtype
|
351
361
|
@pytest.mark.parametrize('dtype_array', types)
|
352
362
|
@pytest.mark.parametrize('dtype_kernel', types)
|
353
363
|
def test_correlate13(self, dtype_array, dtype_kernel, xp):
|
@@ -367,9 +377,7 @@ class TestNdimageFilters:
|
|
367
377
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
368
378
|
assert output.dtype.type == dtype_kernel
|
369
379
|
|
370
|
-
@
|
371
|
-
reason="output=dtype is numpy-specific",
|
372
|
-
exceptions=['cupy'],)
|
380
|
+
@uses_output_array
|
373
381
|
@pytest.mark.parametrize('dtype_array', types)
|
374
382
|
@pytest.mark.parametrize('dtype_output', types)
|
375
383
|
def test_correlate14(self, dtype_array, dtype_output, xp):
|
@@ -383,15 +391,13 @@ class TestNdimageFilters:
|
|
383
391
|
output = xp.zeros(array.shape, dtype=dtype_output)
|
384
392
|
ndimage.correlate(array, kernel, output=output)
|
385
393
|
assert_array_almost_equal(xp.asarray([[2, 3, 5], [5, 6, 8]]), output)
|
386
|
-
assert output.dtype
|
394
|
+
assert output.dtype == dtype_output
|
387
395
|
|
388
396
|
ndimage.convolve(array, kernel, output=output)
|
389
397
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
390
|
-
assert output.dtype
|
398
|
+
assert output.dtype == dtype_output
|
391
399
|
|
392
|
-
@
|
393
|
-
reason="output=dtype is numpy-specific",
|
394
|
-
exceptions=['cupy'],)
|
400
|
+
@uses_output_dtype
|
395
401
|
@pytest.mark.parametrize('dtype_array', types)
|
396
402
|
def test_correlate15(self, dtype_array, xp):
|
397
403
|
dtype_array = getattr(xp, dtype_array)
|
@@ -408,9 +414,7 @@ class TestNdimageFilters:
|
|
408
414
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
409
415
|
assert output.dtype.type == xp.float32
|
410
416
|
|
411
|
-
@
|
412
|
-
reason="output=dtype is numpy-specific",
|
413
|
-
exceptions=['cupy'],)
|
417
|
+
@uses_output_dtype
|
414
418
|
@pytest.mark.parametrize('dtype_array', types)
|
415
419
|
def test_correlate16(self, dtype_array, xp):
|
416
420
|
dtype_array = getattr(xp, dtype_array)
|
@@ -440,9 +444,7 @@ class TestNdimageFilters:
|
|
440
444
|
output = ndimage.convolve1d(array, kernel, origin=-1)
|
441
445
|
assert_array_almost_equal(tcov, output)
|
442
446
|
|
443
|
-
@
|
444
|
-
reason="output=dtype is numpy-specific",
|
445
|
-
exceptions=['cupy'],)
|
447
|
+
@uses_output_dtype
|
446
448
|
@pytest.mark.parametrize('dtype_array', types)
|
447
449
|
def test_correlate18(self, dtype_array, xp):
|
448
450
|
dtype_array = getattr(xp, dtype_array)
|
@@ -471,9 +473,7 @@ class TestNdimageFilters:
|
|
471
473
|
with assert_raises(RuntimeError):
|
472
474
|
ndimage.convolve(array, kernel, mode=['nearest', 'reflect'])
|
473
475
|
|
474
|
-
@
|
475
|
-
reason="output=dtype is numpy-specific",
|
476
|
-
exceptions=['cupy'],)
|
476
|
+
@uses_output_dtype
|
477
477
|
@pytest.mark.parametrize('dtype_array', types)
|
478
478
|
def test_correlate19(self, dtype_array, xp):
|
479
479
|
dtype_array = getattr(xp, dtype_array)
|
@@ -494,9 +494,7 @@ class TestNdimageFilters:
|
|
494
494
|
assert_array_almost_equal(xp.asarray([[3, 5, 6], [6, 8, 9]]), output)
|
495
495
|
assert output.dtype.type == xp.float32
|
496
496
|
|
497
|
-
@
|
498
|
-
reason="output=dtype is numpy-specific",
|
499
|
-
exceptions=['cupy'],)
|
497
|
+
@uses_output_array
|
500
498
|
@pytest.mark.parametrize('dtype_array', types)
|
501
499
|
@pytest.mark.parametrize('dtype_output', types)
|
502
500
|
def test_correlate20(self, dtype_array, dtype_output, xp):
|
@@ -523,9 +521,7 @@ class TestNdimageFilters:
|
|
523
521
|
output = ndimage.convolve1d(array, weights, axis=0)
|
524
522
|
assert_array_almost_equal(output, expected)
|
525
523
|
|
526
|
-
@
|
527
|
-
reason="output=dtype is numpy-specific",
|
528
|
-
exceptions=['cupy'],)
|
524
|
+
@uses_output_array
|
529
525
|
@pytest.mark.parametrize('dtype_array', types)
|
530
526
|
@pytest.mark.parametrize('dtype_output', types)
|
531
527
|
def test_correlate22(self, dtype_array, dtype_output, xp):
|
@@ -544,7 +540,7 @@ class TestNdimageFilters:
|
|
544
540
|
mode='wrap', output=output)
|
545
541
|
assert_array_almost_equal(output, expected)
|
546
542
|
|
547
|
-
@
|
543
|
+
@uses_output_array
|
548
544
|
@pytest.mark.parametrize('dtype_array', types)
|
549
545
|
@pytest.mark.parametrize('dtype_output', types)
|
550
546
|
def test_correlate23(self, dtype_array, dtype_output, xp):
|
@@ -563,7 +559,7 @@ class TestNdimageFilters:
|
|
563
559
|
mode='nearest', output=output)
|
564
560
|
assert_array_almost_equal(output, expected)
|
565
561
|
|
566
|
-
@
|
562
|
+
@uses_output_array
|
567
563
|
@pytest.mark.parametrize('dtype_array', types)
|
568
564
|
@pytest.mark.parametrize('dtype_output', types)
|
569
565
|
def test_correlate24(self, dtype_array, dtype_output, xp):
|
@@ -583,7 +579,7 @@ class TestNdimageFilters:
|
|
583
579
|
mode='nearest', output=output, origin=-1)
|
584
580
|
assert_array_almost_equal(output, tcov)
|
585
581
|
|
586
|
-
@
|
582
|
+
@uses_output_array
|
587
583
|
@pytest.mark.parametrize('dtype_array', types)
|
588
584
|
@pytest.mark.parametrize('dtype_output', types)
|
589
585
|
def test_correlate25(self, dtype_array, dtype_output, xp):
|
@@ -611,9 +607,7 @@ class TestNdimageFilters:
|
|
611
607
|
y = ndimage.correlate1d(xp.ones(1), xp.ones(5), mode='mirror')
|
612
608
|
xp_assert_equal(y, xp.asarray([5.]))
|
613
609
|
|
614
|
-
@
|
615
|
-
reason="output=dtype is numpy-specific",
|
616
|
-
exceptions=['cupy'],)
|
610
|
+
@uses_output_dtype
|
617
611
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
618
612
|
@pytest.mark.parametrize('dtype_input', types)
|
619
613
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -630,9 +624,7 @@ class TestNdimageFilters:
|
|
630
624
|
self._validate_complex(xp, array, kernel, dtype_output,
|
631
625
|
check_warnings=num_parallel_threads == 1)
|
632
626
|
|
633
|
-
@
|
634
|
-
reason="output=dtype is numpy-specific",
|
635
|
-
exceptions=['cupy'],)
|
627
|
+
@uses_output_dtype
|
636
628
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
637
629
|
@pytest.mark.parametrize('dtype_input', types)
|
638
630
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -645,7 +637,7 @@ class TestNdimageFilters:
|
|
645
637
|
dtype_output = getattr(xp, dtype_output)
|
646
638
|
|
647
639
|
if is_cupy(xp) and mode == 'grid-constant':
|
648
|
-
pytest.xfail('
|
640
|
+
pytest.xfail('cupy/cupy#8404')
|
649
641
|
|
650
642
|
# test use of non-zero cval with complex inputs
|
651
643
|
# also verifies that mode 'grid-constant' does not segfault
|
@@ -677,7 +669,7 @@ class TestNdimageFilters:
|
|
677
669
|
func(array, kernel, mode='constant', cval=5.0 + 1.0j,
|
678
670
|
output=xp.complex64)
|
679
671
|
|
680
|
-
@
|
672
|
+
@uses_output_dtype
|
681
673
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
682
674
|
@pytest.mark.parametrize('dtype_input', types)
|
683
675
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -692,7 +684,7 @@ class TestNdimageFilters:
|
|
692
684
|
self._validate_complex(xp, array, kernel, dtype_output,
|
693
685
|
check_warnings=num_parallel_threads == 1)
|
694
686
|
|
695
|
-
@
|
687
|
+
@uses_output_dtype
|
696
688
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
697
689
|
@pytest.mark.parametrize('dtype_input', types)
|
698
690
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -709,7 +701,7 @@ class TestNdimageFilters:
|
|
709
701
|
cval=5.0,
|
710
702
|
check_warnings=num_parallel_threads == 1)
|
711
703
|
|
712
|
-
@
|
704
|
+
@uses_output_dtype
|
713
705
|
@pytest.mark.parametrize('dtype_kernel', types)
|
714
706
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
715
707
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -726,7 +718,7 @@ class TestNdimageFilters:
|
|
726
718
|
self._validate_complex(xp, array, kernel, dtype_output,
|
727
719
|
check_warnings=num_parallel_threads == 1)
|
728
720
|
|
729
|
-
@
|
721
|
+
@uses_output_dtype
|
730
722
|
@pytest.mark.parametrize('dtype_kernel', types)
|
731
723
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
732
724
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -741,10 +733,8 @@ class TestNdimageFilters:
|
|
741
733
|
self._validate_complex(xp, array, kernel, dtype_output,
|
742
734
|
check_warnings=num_parallel_threads == 1)
|
743
735
|
|
744
|
-
@
|
745
|
-
@
|
746
|
-
reason='output=dtype is numpy-specific',
|
747
|
-
exceptions=['cupy'])
|
736
|
+
@uses_output_dtype
|
737
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
748
738
|
@pytest.mark.parametrize('dtype_kernel', types)
|
749
739
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
750
740
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -761,7 +751,8 @@ class TestNdimageFilters:
|
|
761
751
|
cval=5 - 3j,
|
762
752
|
check_warnings=num_parallel_threads == 1)
|
763
753
|
|
764
|
-
@
|
754
|
+
@uses_output_dtype
|
755
|
+
@xfail_xp_backends("cupy", reason="unhashable type: 'ndarray'")
|
765
756
|
@pytest.mark.parametrize('dtype', complex_types)
|
766
757
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
767
758
|
def test_correlate_complex_input_and_kernel(self, dtype, dtype_output, xp,
|
@@ -776,10 +767,8 @@ class TestNdimageFilters:
|
|
776
767
|
self._validate_complex(xp, array, kernel, dtype_output,
|
777
768
|
check_warnings=num_parallel_threads == 1)
|
778
769
|
|
779
|
-
@
|
780
|
-
@
|
781
|
-
reason="output=dtype is numpy-specific",
|
782
|
-
exceptions=['cupy'],)
|
770
|
+
@uses_output_dtype
|
771
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
783
772
|
@pytest.mark.parametrize('dtype', complex_types)
|
784
773
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
785
774
|
def test_correlate_complex_input_and_kernel_cval(self, dtype,
|
@@ -796,7 +785,8 @@ class TestNdimageFilters:
|
|
796
785
|
cval=5.0 + 2.0j,
|
797
786
|
check_warnings=num_parallel_threads == 1)
|
798
787
|
|
799
|
-
@
|
788
|
+
@uses_output_dtype
|
789
|
+
@xfail_xp_backends("cupy", reason="unhashable type: 'ndarray'")
|
800
790
|
@pytest.mark.parametrize('dtype', complex_types)
|
801
791
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
802
792
|
@pytest.mark.thread_unsafe
|
@@ -810,20 +800,17 @@ class TestNdimageFilters:
|
|
810
800
|
self._validate_complex(xp, array, kernel, dtype_output,
|
811
801
|
check_warnings=num_parallel_threads == 1)
|
812
802
|
|
803
|
+
@uses_output_dtype
|
804
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
813
805
|
@pytest.mark.parametrize('dtype', complex_types)
|
814
806
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
815
807
|
def test_correlate1d_complex_input_and_kernel_cval(self, dtype,
|
816
808
|
dtype_output, xp,
|
817
809
|
num_parallel_threads):
|
818
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
819
|
-
pytest.xfail("output=dtype is numpy-specific")
|
820
810
|
|
821
811
|
dtype = getattr(xp, dtype)
|
822
812
|
dtype_output = getattr(xp, dtype_output)
|
823
813
|
|
824
|
-
if is_cupy(xp):
|
825
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8405")
|
826
|
-
|
827
814
|
kernel = xp.asarray([1, 1 + 1j], dtype=dtype)
|
828
815
|
array = xp.asarray([1, 2j, 3, 1 + 4j, 5, 6j], dtype=dtype)
|
829
816
|
self._validate_complex(xp, array, kernel, dtype_output, mode='constant',
|
@@ -843,10 +830,8 @@ class TestNdimageFilters:
|
|
843
830
|
assert input.dtype == output.dtype
|
844
831
|
assert input.shape == output.shape
|
845
832
|
|
833
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8403")
|
846
834
|
def test_gauss03(self, xp):
|
847
|
-
if is_cupy(xp):
|
848
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8403")
|
849
|
-
|
850
835
|
# single precision data
|
851
836
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
852
837
|
input = xp.reshape(input, (100, 100))
|
@@ -862,10 +847,8 @@ class TestNdimageFilters:
|
|
862
847
|
assert_almost_equal(o_sum, i_sum, decimal=0)
|
863
848
|
assert sumsq(input, output) > 1.0
|
864
849
|
|
850
|
+
@uses_output_dtype
|
865
851
|
def test_gauss04(self, xp):
|
866
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
867
|
-
pytest.xfail("output=dtype is numpy-specific")
|
868
|
-
|
869
852
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
870
853
|
input = xp.reshape(input, (100, 100))
|
871
854
|
otype = xp.float64
|
@@ -874,10 +857,8 @@ class TestNdimageFilters:
|
|
874
857
|
assert input.shape == output.shape
|
875
858
|
assert sumsq(input, output) > 1.0
|
876
859
|
|
860
|
+
@uses_output_dtype
|
877
861
|
def test_gauss05(self, xp):
|
878
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
879
|
-
pytest.xfail("output=dtype is numpy-specific")
|
880
|
-
|
881
862
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
882
863
|
input = xp.reshape(input, (100, 100))
|
883
864
|
otype = xp.float64
|
@@ -887,10 +868,8 @@ class TestNdimageFilters:
|
|
887
868
|
assert input.shape == output.shape
|
888
869
|
assert sumsq(input, output) > 1.0
|
889
870
|
|
871
|
+
@uses_output_dtype
|
890
872
|
def test_gauss06(self, xp):
|
891
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
892
|
-
pytest.xfail("output=dtype is numpy-specific")
|
893
|
-
|
894
873
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
895
874
|
input = xp.reshape(input, (100, 100))
|
896
875
|
otype = xp.float64
|
@@ -898,7 +877,7 @@ class TestNdimageFilters:
|
|
898
877
|
output2 = ndimage.gaussian_filter(input, 1.0, output=otype)
|
899
878
|
assert_array_almost_equal(output1, output2)
|
900
879
|
|
901
|
-
@
|
880
|
+
@uses_output_array
|
902
881
|
def test_gauss_memory_overlap(self, xp):
|
903
882
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
904
883
|
input = xp.reshape(input, (100, 100))
|
@@ -906,6 +885,7 @@ class TestNdimageFilters:
|
|
906
885
|
ndimage.gaussian_filter(input, 1.0, output=input)
|
907
886
|
assert_array_almost_equal(output1, input)
|
908
887
|
|
888
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
909
889
|
@pytest.mark.parametrize(('filter_func', 'extra_args', 'size0', 'size'),
|
910
890
|
[(ndimage.gaussian_filter, (), 0, 1.0),
|
911
891
|
(ndimage.uniform_filter, (), 1, 3),
|
@@ -920,9 +900,6 @@ class TestNdimageFilters:
|
|
920
900
|
+ tuple(itertools.combinations(range(-3, 3), 2))
|
921
901
|
+ ((0, 1, 2),))
|
922
902
|
def test_filter_axes(self, filter_func, extra_args, size0, size, axes, xp):
|
923
|
-
if is_cupy(xp):
|
924
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
925
|
-
|
926
903
|
# Note: `size` is called `sigma` in `gaussian_filter`
|
927
904
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
928
905
|
array = xp.reshape(array, (6, 8, 12))
|
@@ -942,8 +919,7 @@ class TestNdimageFilters:
|
|
942
919
|
xp_assert_close(output, expected)
|
943
920
|
|
944
921
|
@skip_xp_backends("cupy",
|
945
|
-
reason="these filters do not yet have axes support"
|
946
|
-
)
|
922
|
+
reason="these filters do not yet have axes support")
|
947
923
|
@pytest.mark.parametrize(('filter_func', 'kwargs'),
|
948
924
|
[(ndimage.laplace, {}),
|
949
925
|
(ndimage.gaussian_gradient_magnitude,
|
@@ -984,8 +960,7 @@ class TestNdimageFilters:
|
|
984
960
|
xp_assert_close(output, expected)
|
985
961
|
|
986
962
|
@skip_xp_backends("cupy",
|
987
|
-
reason="generic_filter does not yet have axes support"
|
988
|
-
)
|
963
|
+
reason="generic_filter does not yet have axes support")
|
989
964
|
@pytest.mark.parametrize(
|
990
965
|
'axes',
|
991
966
|
tuple(itertools.combinations(range(-3, 3), 1))
|
@@ -1007,8 +982,7 @@ class TestNdimageFilters:
|
|
1007
982
|
xp_assert_close(output, expected)
|
1008
983
|
|
1009
984
|
@skip_xp_backends("cupy",
|
1010
|
-
reason="https://github.com/cupy/cupy/pull/8339"
|
1011
|
-
)
|
985
|
+
reason="https://github.com/cupy/cupy/pull/8339")
|
1012
986
|
@pytest.mark.parametrize('func', [ndimage.correlate, ndimage.convolve])
|
1013
987
|
@pytest.mark.parametrize(
|
1014
988
|
'dtype', [np.float32, np.float64, np.complex64, np.complex128]
|
@@ -1048,9 +1022,7 @@ class TestNdimageFilters:
|
|
1048
1022
|
mode=['reflect', 'nearest', 'constant'])
|
1049
1023
|
kwargs_rank = dict(origin=(-1, 0, 1))
|
1050
1024
|
|
1051
|
-
@
|
1052
|
-
reason="fancy indexing is only available in 2024 version",
|
1053
|
-
)
|
1025
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1054
1026
|
@pytest.mark.parametrize("filter_func, size0, size, kwargs",
|
1055
1027
|
[(ndimage.gaussian_filter, 0, 1.0, kwargs_gauss),
|
1056
1028
|
(ndimage.uniform_filter, 1, 3, kwargs_other),
|
@@ -1061,10 +1033,6 @@ class TestNdimageFilters:
|
|
1061
1033
|
(ndimage.percentile_filter, 1, 3, kwargs_rank)])
|
1062
1034
|
@pytest.mark.parametrize('axes', itertools.combinations(range(-3, 3), 2))
|
1063
1035
|
def test_filter_axes_kwargs(self, filter_func, size0, size, kwargs, axes, xp):
|
1064
|
-
|
1065
|
-
if is_cupy(xp):
|
1066
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1067
|
-
|
1068
1036
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1069
1037
|
array = xp.reshape(array, (6, 8, 12))
|
1070
1038
|
|
@@ -1105,6 +1073,7 @@ class TestNdimageFilters:
|
|
1105
1073
|
xp_assert_close(output, expected)
|
1106
1074
|
|
1107
1075
|
|
1076
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1108
1077
|
@pytest.mark.parametrize("filter_func, kwargs",
|
1109
1078
|
[(ndimage.convolve, {}),
|
1110
1079
|
(ndimage.correlate, {}),
|
@@ -1114,9 +1083,6 @@ class TestNdimageFilters:
|
|
1114
1083
|
(ndimage.rank_filter, {"rank": 1}),
|
1115
1084
|
(ndimage.percentile_filter, {"percentile": 30})])
|
1116
1085
|
def test_filter_weights_subset_axes_origins(self, filter_func, kwargs, xp):
|
1117
|
-
if is_cupy(xp):
|
1118
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1119
|
-
|
1120
1086
|
axes = (-2, -1)
|
1121
1087
|
origins = (0, 1)
|
1122
1088
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
@@ -1149,6 +1115,7 @@ class TestNdimageFilters:
|
|
1149
1115
|
output[:, :, origins[1]:], output0[:, :, :-origins[1]])
|
1150
1116
|
|
1151
1117
|
|
1118
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1152
1119
|
@pytest.mark.parametrize(
|
1153
1120
|
'filter_func, args',
|
1154
1121
|
[(ndimage.convolve, (np.ones((3, 3, 3)),)), # args = (weights,)
|
@@ -1164,9 +1131,6 @@ class TestNdimageFilters:
|
|
1164
1131
|
'axes', [(1.5,), (0, 1, 2, 3), (3,), (-4,)]
|
1165
1132
|
)
|
1166
1133
|
def test_filter_invalid_axes(self, filter_func, args, axes, xp):
|
1167
|
-
if is_cupy(xp):
|
1168
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1169
|
-
|
1170
1134
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1171
1135
|
array = xp.reshape(array, (6, 8, 12))
|
1172
1136
|
args = [
|
@@ -1182,6 +1146,7 @@ class TestNdimageFilters:
|
|
1182
1146
|
with pytest.raises(error_class, match=match):
|
1183
1147
|
filter_func(array, *args, axes=axes)
|
1184
1148
|
|
1149
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1185
1150
|
@pytest.mark.parametrize(
|
1186
1151
|
'filter_func, kwargs',
|
1187
1152
|
[(ndimage.convolve, {}),
|
@@ -1197,9 +1162,6 @@ class TestNdimageFilters:
|
|
1197
1162
|
@pytest.mark.parametrize('separable_footprint', [False, True])
|
1198
1163
|
def test_filter_invalid_footprint_ndim(self, filter_func, kwargs, axes,
|
1199
1164
|
separable_footprint, xp):
|
1200
|
-
if is_cupy(xp):
|
1201
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1202
|
-
|
1203
1165
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1204
1166
|
array = xp.reshape(array, (6, 8, 12))
|
1205
1167
|
# create a footprint with one too many dimensions
|
@@ -1223,14 +1185,12 @@ class TestNdimageFilters:
|
|
1223
1185
|
with pytest.raises(RuntimeError, match=match):
|
1224
1186
|
filter_func(array, axes=axes, **kwargs)
|
1225
1187
|
|
1188
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1226
1189
|
@pytest.mark.parametrize('n_mismatch', [1, 3])
|
1227
1190
|
@pytest.mark.parametrize('filter_func, kwargs, key, val',
|
1228
1191
|
_cases_axes_tuple_length_mismatch())
|
1229
1192
|
def test_filter_tuple_length_mismatch(self, n_mismatch, filter_func,
|
1230
1193
|
kwargs, key, val, xp):
|
1231
|
-
if is_cupy(xp):
|
1232
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1233
|
-
|
1234
1194
|
# Test for the intended RuntimeError when a kwargs has an invalid size
|
1235
1195
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1236
1196
|
array = xp.reshape(array, (6, 8, 12))
|
@@ -1245,9 +1205,6 @@ class TestNdimageFilters:
|
|
1245
1205
|
|
1246
1206
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1247
1207
|
def test_prewitt01(self, dtype, xp):
|
1248
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1249
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1250
|
-
|
1251
1208
|
dtype = getattr(xp, dtype)
|
1252
1209
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1253
1210
|
[5, 8, 3, 7, 1],
|
@@ -1257,12 +1214,9 @@ class TestNdimageFilters:
|
|
1257
1214
|
output = ndimage.prewitt(array, 0)
|
1258
1215
|
assert_array_almost_equal(t, output)
|
1259
1216
|
|
1260
|
-
@
|
1217
|
+
@uses_output_array
|
1261
1218
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1262
1219
|
def test_prewitt02(self, dtype, xp):
|
1263
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1264
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1265
|
-
|
1266
1220
|
dtype = getattr(xp, dtype)
|
1267
1221
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1268
1222
|
[5, 8, 3, 7, 1],
|
@@ -1275,14 +1229,9 @@ class TestNdimageFilters:
|
|
1275
1229
|
|
1276
1230
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1277
1231
|
def test_prewitt03(self, dtype, xp):
|
1278
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1279
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1280
|
-
|
1281
1232
|
dtype = getattr(xp, dtype)
|
1282
1233
|
if is_cupy(xp) and dtype in [xp.uint32, xp.uint64]:
|
1283
1234
|
pytest.xfail("uint UB? XXX")
|
1284
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1285
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1286
1235
|
|
1287
1236
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1288
1237
|
[5, 8, 3, 7, 1],
|
@@ -1294,9 +1243,6 @@ class TestNdimageFilters:
|
|
1294
1243
|
|
1295
1244
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1296
1245
|
def test_prewitt04(self, dtype, xp):
|
1297
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1298
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1299
|
-
|
1300
1246
|
dtype = getattr(xp, dtype)
|
1301
1247
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1302
1248
|
[5, 8, 3, 7, 1],
|
@@ -1307,9 +1253,6 @@ class TestNdimageFilters:
|
|
1307
1253
|
|
1308
1254
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1309
1255
|
def test_sobel01(self, dtype, xp):
|
1310
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1311
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1312
|
-
|
1313
1256
|
dtype = getattr(xp, dtype)
|
1314
1257
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1315
1258
|
[5, 8, 3, 7, 1],
|
@@ -1319,12 +1262,9 @@ class TestNdimageFilters:
|
|
1319
1262
|
output = ndimage.sobel(array, 0)
|
1320
1263
|
assert_array_almost_equal(t, output)
|
1321
1264
|
|
1322
|
-
@
|
1265
|
+
@uses_output_array
|
1323
1266
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1324
1267
|
def test_sobel02(self, dtype, xp):
|
1325
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1326
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1327
|
-
|
1328
1268
|
dtype = getattr(xp, dtype)
|
1329
1269
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1330
1270
|
[5, 8, 3, 7, 1],
|
@@ -1339,8 +1279,6 @@ class TestNdimageFilters:
|
|
1339
1279
|
def test_sobel03(self, dtype, xp):
|
1340
1280
|
if is_cupy(xp) and dtype in ["uint32", "uint64"]:
|
1341
1281
|
pytest.xfail("uint UB? XXX")
|
1342
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1343
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1344
1282
|
|
1345
1283
|
dtype = getattr(xp, dtype)
|
1346
1284
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
@@ -1354,9 +1292,6 @@ class TestNdimageFilters:
|
|
1354
1292
|
|
1355
1293
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1356
1294
|
def test_sobel04(self, dtype, xp):
|
1357
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1358
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1359
|
-
|
1360
1295
|
dtype = getattr(xp, dtype)
|
1361
1296
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1362
1297
|
[5, 8, 3, 7, 1],
|
@@ -1379,7 +1314,7 @@ class TestNdimageFilters:
|
|
1379
1314
|
output = ndimage.laplace(array)
|
1380
1315
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1381
1316
|
|
1382
|
-
@
|
1317
|
+
@uses_output_array
|
1383
1318
|
@pytest.mark.parametrize('dtype',
|
1384
1319
|
["int32", "float32", "float64",
|
1385
1320
|
"complex64", "complex128"])
|
@@ -1409,7 +1344,7 @@ class TestNdimageFilters:
|
|
1409
1344
|
output = ndimage.gaussian_laplace(array, 1.0)
|
1410
1345
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1411
1346
|
|
1412
|
-
@
|
1347
|
+
@uses_output_array
|
1413
1348
|
@pytest.mark.parametrize('dtype',
|
1414
1349
|
["int32", "float32", "float64",
|
1415
1350
|
"complex64", "complex128"])
|
@@ -1425,12 +1360,9 @@ class TestNdimageFilters:
|
|
1425
1360
|
ndimage.gaussian_laplace(array, 1.0, output)
|
1426
1361
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1427
1362
|
|
1428
|
-
@
|
1363
|
+
@uses_output_array
|
1429
1364
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1430
1365
|
def test_generic_laplace01(self, dtype, xp):
|
1431
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1432
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1433
|
-
|
1434
1366
|
def derivative2(input, axis, output, mode, cval, a, b):
|
1435
1367
|
sigma = np.asarray([a, b / 2.0])
|
1436
1368
|
order = [0] * input.ndim
|
@@ -1450,7 +1382,6 @@ class TestNdimageFilters:
|
|
1450
1382
|
ndimage.gaussian_laplace(array, 1.0, output)
|
1451
1383
|
assert_array_almost_equal(tmp, output)
|
1452
1384
|
|
1453
|
-
@skip_xp_backends("jax.numpy", reason="output array is read-only")
|
1454
1385
|
@pytest.mark.parametrize('dtype',
|
1455
1386
|
["int32", "float32", "float64",
|
1456
1387
|
"complex64", "complex128"])
|
@@ -1466,12 +1397,11 @@ class TestNdimageFilters:
|
|
1466
1397
|
output = ndimage.gaussian_gradient_magnitude(array, 1.0)
|
1467
1398
|
expected = tmp1 * tmp1 + tmp2 * tmp2
|
1468
1399
|
|
1469
|
-
|
1470
|
-
|
1471
|
-
expected = astype(xp.sqrt(expected_float), dtype)
|
1400
|
+
expected_float = xp.astype(expected, xp.float64) if is_int_dtype else expected
|
1401
|
+
expected = xp.astype(xp.sqrt(expected_float), dtype)
|
1472
1402
|
xp_assert_close(output, expected, rtol=1e-6, atol=1e-6)
|
1473
1403
|
|
1474
|
-
@
|
1404
|
+
@uses_output_array
|
1475
1405
|
@pytest.mark.parametrize('dtype',
|
1476
1406
|
["int32", "float32", "float64",
|
1477
1407
|
"complex64", "complex128"])
|
@@ -1488,10 +1418,9 @@ class TestNdimageFilters:
|
|
1488
1418
|
ndimage.gaussian_gradient_magnitude(array, 1.0, output)
|
1489
1419
|
expected = tmp1 * tmp1 + tmp2 * tmp2
|
1490
1420
|
|
1491
|
-
|
1492
|
-
fl_expected = astype(expected, xp.float64) if is_int_dtype else expected
|
1421
|
+
fl_expected = xp.astype(expected, xp.float64) if is_int_dtype else expected
|
1493
1422
|
|
1494
|
-
expected = astype(xp.sqrt(fl_expected), dtype)
|
1423
|
+
expected = xp.astype(xp.sqrt(fl_expected), dtype)
|
1495
1424
|
xp_assert_close(output, expected, rtol=1e-6, atol=1e-6)
|
1496
1425
|
|
1497
1426
|
def test_generic_gradient_magnitude01(self, xp):
|
@@ -1511,18 +1440,12 @@ class TestNdimageFilters:
|
|
1511
1440
|
extra_keywords={'b': 2.0})
|
1512
1441
|
assert_array_almost_equal(tmp1, tmp2)
|
1513
1442
|
|
1514
|
-
@skip_xp_backends("cupy",
|
1515
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1516
|
-
)
|
1517
1443
|
def test_uniform01(self, xp):
|
1518
1444
|
array = xp.asarray([2, 4, 6])
|
1519
1445
|
size = 2
|
1520
1446
|
output = ndimage.uniform_filter1d(array, size, origin=-1)
|
1521
1447
|
assert_array_almost_equal(xp.asarray([3, 5, 6]), output)
|
1522
1448
|
|
1523
|
-
@skip_xp_backends("cupy",
|
1524
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1525
|
-
)
|
1526
1449
|
def test_uniform01_complex(self, xp):
|
1527
1450
|
array = xp.asarray([2 + 1j, 4 + 2j, 6 + 3j], dtype=xp.complex128)
|
1528
1451
|
size = 2
|
@@ -1542,9 +1465,6 @@ class TestNdimageFilters:
|
|
1542
1465
|
output = ndimage.uniform_filter(array, filter_shape)
|
1543
1466
|
assert_array_almost_equal(array, output)
|
1544
1467
|
|
1545
|
-
@skip_xp_backends("cupy",
|
1546
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1547
|
-
)
|
1548
1468
|
def test_uniform04(self, xp):
|
1549
1469
|
array = xp.asarray([2, 4, 6])
|
1550
1470
|
filter_shape = [2]
|
@@ -1557,15 +1477,10 @@ class TestNdimageFilters:
|
|
1557
1477
|
output = ndimage.uniform_filter(array, filter_shape)
|
1558
1478
|
assert_array_almost_equal(xp.asarray([]), output)
|
1559
1479
|
|
1560
|
-
@
|
1561
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1562
|
-
)
|
1480
|
+
@uses_output_dtype
|
1563
1481
|
@pytest.mark.parametrize('dtype_array', types)
|
1564
1482
|
@pytest.mark.parametrize('dtype_output', types)
|
1565
1483
|
def test_uniform06(self, dtype_array, dtype_output, xp):
|
1566
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
1567
|
-
pytest.xfail("output=dtype is numpy-specific")
|
1568
|
-
|
1569
1484
|
dtype_array = getattr(xp, dtype_array)
|
1570
1485
|
dtype_output = getattr(xp, dtype_output)
|
1571
1486
|
|
@@ -1577,15 +1492,10 @@ class TestNdimageFilters:
|
|
1577
1492
|
assert_array_almost_equal(xp.asarray([[4, 6, 10], [10, 12, 16]]), output)
|
1578
1493
|
assert output.dtype.type == dtype_output
|
1579
1494
|
|
1580
|
-
@
|
1581
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1582
|
-
)
|
1495
|
+
@uses_output_dtype
|
1583
1496
|
@pytest.mark.parametrize('dtype_array', complex_types)
|
1584
1497
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
1585
1498
|
def test_uniform06_complex(self, dtype_array, dtype_output, xp):
|
1586
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
1587
|
-
pytest.xfail("output=dtype is numpy-specific")
|
1588
|
-
|
1589
1499
|
dtype_array = getattr(xp, dtype_array)
|
1590
1500
|
dtype_output = getattr(xp, dtype_output)
|
1591
1501
|
|
@@ -1631,7 +1541,7 @@ class TestNdimageFilters:
|
|
1631
1541
|
[2, 2, 1, 1, 1],
|
1632
1542
|
[5, 3, 3, 1, 1]]), output)
|
1633
1543
|
|
1634
|
-
@
|
1544
|
+
@uses_output_array
|
1635
1545
|
def test_minimum_filter05_overlap(self, xp):
|
1636
1546
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1637
1547
|
[7, 6, 9, 3, 5],
|
@@ -1773,6 +1683,7 @@ class TestNdimageFilters:
|
|
1773
1683
|
[7, 9, 8, 9, 7],
|
1774
1684
|
[8, 8, 8, 7, 7]]), output)
|
1775
1685
|
|
1686
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1776
1687
|
@pytest.mark.parametrize(
|
1777
1688
|
'axes', tuple(itertools.combinations(range(-3, 3), 2))
|
1778
1689
|
)
|
@@ -1785,9 +1696,6 @@ class TestNdimageFilters:
|
|
1785
1696
|
(ndimage.percentile_filter, dict(percentile=60))]
|
1786
1697
|
)
|
1787
1698
|
def test_minmax_nonseparable_axes(self, filter_func, axes, kwargs, xp):
|
1788
|
-
if is_cupy(xp):
|
1789
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1790
|
-
|
1791
1699
|
array = xp.arange(6 * 8 * 12, dtype=xp.float32)
|
1792
1700
|
array = xp.reshape(array, (6, 8, 12))
|
1793
1701
|
# use 2D triangular footprint because it is non-separable
|
@@ -1803,8 +1711,7 @@ class TestNdimageFilters:
|
|
1803
1711
|
|
1804
1712
|
missing_axis = tuple(set(range(3)) - set(axes % array.ndim))[0]
|
1805
1713
|
|
1806
|
-
|
1807
|
-
footprint_3d = expand_dims(footprint, axis=missing_axis)
|
1714
|
+
footprint_3d = xp.expand_dims(footprint, axis=missing_axis)
|
1808
1715
|
expected = filter_func(array, footprint=footprint_3d, **kwargs)
|
1809
1716
|
xp_assert_close(output, expected)
|
1810
1717
|
|
@@ -1862,18 +1769,14 @@ class TestNdimageFilters:
|
|
1862
1769
|
output = ndimage.percentile_filter(array, 17, size=(2, 3))
|
1863
1770
|
xp_assert_equal(expected, output)
|
1864
1771
|
|
1865
|
-
@
|
1866
|
-
|
1867
|
-
)
|
1772
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8406")
|
1773
|
+
@uses_output_array
|
1868
1774
|
def test_rank06_overlap(self, xp):
|
1869
|
-
if is_cupy(xp):
|
1870
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8406")
|
1871
1775
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1872
1776
|
[5, 8, 3, 7, 1],
|
1873
1777
|
[5, 6, 9, 3, 5]])
|
1874
1778
|
|
1875
|
-
|
1876
|
-
array_copy = asarray(array, copy=True)
|
1779
|
+
array_copy = xp.asarray(array, copy=True)
|
1877
1780
|
expected = [[2, 2, 1, 1, 1],
|
1878
1781
|
[3, 3, 2, 1, 1],
|
1879
1782
|
[5, 5, 3, 3, 1]]
|
@@ -1966,9 +1869,6 @@ class TestNdimageFilters:
|
|
1966
1869
|
|
1967
1870
|
@pytest.mark.parametrize('dtype', types)
|
1968
1871
|
def test_rank12(self, dtype, xp):
|
1969
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1970
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1971
|
-
|
1972
1872
|
dtype = getattr(xp, dtype)
|
1973
1873
|
expected = [[3, 3, 2, 4, 4],
|
1974
1874
|
[3, 5, 2, 5, 1],
|
@@ -1988,9 +1888,6 @@ class TestNdimageFilters:
|
|
1988
1888
|
|
1989
1889
|
@pytest.mark.parametrize('dtype', types)
|
1990
1890
|
def test_rank13(self, dtype, xp):
|
1991
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1992
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1993
|
-
|
1994
1891
|
dtype = getattr(xp, dtype)
|
1995
1892
|
expected = [[5, 2, 5, 1, 1],
|
1996
1893
|
[5, 8, 3, 5, 5],
|
@@ -2006,9 +1903,6 @@ class TestNdimageFilters:
|
|
2006
1903
|
|
2007
1904
|
@pytest.mark.parametrize('dtype', types)
|
2008
1905
|
def test_rank14(self, dtype, xp):
|
2009
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2010
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2011
|
-
|
2012
1906
|
dtype = getattr(xp, dtype)
|
2013
1907
|
expected = [[3, 5, 2, 5, 1],
|
2014
1908
|
[5, 5, 8, 3, 5],
|
@@ -2024,9 +1918,6 @@ class TestNdimageFilters:
|
|
2024
1918
|
|
2025
1919
|
@pytest.mark.parametrize('dtype', types)
|
2026
1920
|
def test_rank15(self, dtype, xp):
|
2027
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2028
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2029
|
-
|
2030
1921
|
dtype = getattr(xp, dtype)
|
2031
1922
|
expected = [[2, 3, 1, 4, 1],
|
2032
1923
|
[5, 3, 7, 1, 1],
|
@@ -2040,7 +1931,8 @@ class TestNdimageFilters:
|
|
2040
1931
|
origin=[-1, 0])
|
2041
1932
|
xp_assert_equal(expected, output)
|
2042
1933
|
|
2043
|
-
|
1934
|
+
# NumPy-only because test is for list input
|
1935
|
+
def test_rank16(self):
|
2044
1936
|
# test that lists are accepted and interpreted as numpy arrays
|
2045
1937
|
array = [3, 2, 5, 1, 4]
|
2046
1938
|
# expected values are: median(3, 2, 5) = 3, median(2, 5, 1) = 2, etc
|
@@ -2077,20 +1969,20 @@ class TestNdimageFilters:
|
|
2077
1969
|
y = ndimage.rank_filter(x, -2, size=3)
|
2078
1970
|
assert y.dtype == x.dtype
|
2079
1971
|
|
2080
|
-
@skip_xp_backends(np_only=True,
|
1972
|
+
@skip_xp_backends(np_only=True, exceptions=["cupy"],
|
1973
|
+
reason="off-by-ones on alt backends")
|
1974
|
+
@xfail_xp_backends("cupy", reason="does not support extra_arguments")
|
2081
1975
|
@pytest.mark.parametrize('dtype', types)
|
2082
1976
|
def test_generic_filter1d01(self, dtype, xp):
|
2083
1977
|
weights = xp.asarray([1.1, 2.2, 3.3])
|
2084
1978
|
|
2085
|
-
if is_cupy(xp):
|
2086
|
-
pytest.xfail("CuPy does not support extra_arguments")
|
2087
|
-
|
2088
1979
|
def _filter_func(input, output, fltr, total):
|
2089
1980
|
fltr = fltr / total
|
2090
1981
|
for ii in range(input.shape[0] - 2):
|
2091
1982
|
output[ii] = input[ii] * fltr[0]
|
2092
1983
|
output[ii] += input[ii + 1] * fltr[1]
|
2093
1984
|
output[ii] += input[ii + 2] * fltr[2]
|
1985
|
+
|
2094
1986
|
a = np.arange(12, dtype=dtype).reshape(3, 4)
|
2095
1987
|
a = xp.asarray(a)
|
2096
1988
|
dtype = getattr(xp, dtype)
|
@@ -2102,10 +1994,9 @@ class TestNdimageFilters:
|
|
2102
1994
|
extra_keywords={'total': xp.sum(weights)})
|
2103
1995
|
assert_array_almost_equal(r1, r2)
|
2104
1996
|
|
1997
|
+
@xfail_xp_backends("cupy", reason="does not support extra_arguments")
|
2105
1998
|
@pytest.mark.parametrize('dtype', types)
|
2106
1999
|
def test_generic_filter01(self, dtype, xp):
|
2107
|
-
if is_cupy(xp):
|
2108
|
-
pytest.xfail("CuPy does not support extra_arguments")
|
2109
2000
|
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2110
2001
|
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2111
2002
|
|
@@ -2294,10 +2185,8 @@ class TestNdimageFilters:
|
|
2294
2185
|
xp_assert_equal(output, expected_value)
|
2295
2186
|
|
2296
2187
|
|
2188
|
+
@xfail_xp_backends("cupy", reason="TypeError")
|
2297
2189
|
def test_ticket_701(xp):
|
2298
|
-
if is_cupy(xp):
|
2299
|
-
pytest.xfail("CuPy raises a TypeError.")
|
2300
|
-
|
2301
2190
|
# Test generic filter sizes
|
2302
2191
|
arr = xp.asarray(np.arange(4).reshape(2, 2))
|
2303
2192
|
def func(x):
|
@@ -2337,9 +2226,8 @@ def test_gh_5430():
|
|
2337
2226
|
ndimage._ni_support._normalize_sequence(x, 0)
|
2338
2227
|
|
2339
2228
|
|
2229
|
+
@skip_xp_backends("cupy", reason="tests a private scipy utility")
|
2340
2230
|
def test_gaussian_kernel1d(xp):
|
2341
|
-
if is_cupy(xp):
|
2342
|
-
pytest.skip("This test tests a private scipy utility.")
|
2343
2231
|
radius = 10
|
2344
2232
|
sigma = 2
|
2345
2233
|
sigma2 = sigma * sigma
|
@@ -2370,13 +2258,12 @@ def test_orders_gauss(xp):
|
|
2370
2258
|
assert_raises(ValueError, ndimage.gaussian_filter1d, arr, 1, -1, -1)
|
2371
2259
|
|
2372
2260
|
|
2261
|
+
@xfail_xp_backends("cupy", reason="TypeError")
|
2373
2262
|
def test_valid_origins(xp):
|
2374
2263
|
"""Regression test for #1311."""
|
2375
|
-
if is_cupy(xp):
|
2376
|
-
pytest.xfail("CuPy raises a TypeError.")
|
2377
|
-
|
2378
2264
|
def func(x):
|
2379
2265
|
return xp.mean(x)
|
2266
|
+
|
2380
2267
|
data = xp.asarray([1, 2, 3, 4, 5], dtype=xp.float64)
|
2381
2268
|
assert_raises(ValueError, ndimage.generic_filter, data, func, size=3,
|
2382
2269
|
origin=2)
|
@@ -2415,9 +2302,7 @@ def test_bad_convolve_and_correlate_origins(xp):
|
|
2415
2302
|
assert_raises(ValueError, ndimage.convolve,
|
2416
2303
|
xp.ones((3, 5)), xp.ones((2, 2)), origin=[0, -2])
|
2417
2304
|
|
2418
|
-
@skip_xp_backends("cupy",
|
2419
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
2420
|
-
)
|
2305
|
+
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2421
2306
|
def test_multiple_modes(xp):
|
2422
2307
|
# Test that the filters with multiple mode capabilities for different
|
2423
2308
|
# dimensions give the same result as applying a single mode.
|
@@ -2449,14 +2334,13 @@ def test_multiple_modes(xp):
|
|
2449
2334
|
|
2450
2335
|
|
2451
2336
|
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2452
|
-
@skip_xp_backends("jax.numpy", reason="output array is read-only.")
|
2453
2337
|
def test_multiple_modes_sequentially(xp):
|
2454
2338
|
# Test that the filters with multiple mode capabilities for different
|
2455
2339
|
# dimensions give the same result as applying the filters with
|
2456
2340
|
# different modes sequentially
|
2457
2341
|
arr = xp.asarray([[1., 0., 0.],
|
2458
|
-
|
2459
|
-
|
2342
|
+
[1., 1., 0.],
|
2343
|
+
[0., 0., 0.]])
|
2460
2344
|
|
2461
2345
|
modes = ['reflect', 'wrap']
|
2462
2346
|
|
@@ -2564,9 +2448,7 @@ def test_multiple_modes_gaussian_gradient_magnitude(xp):
|
|
2564
2448
|
|
2565
2449
|
assert_almost_equal(expected, calculated)
|
2566
2450
|
|
2567
|
-
@skip_xp_backends("cupy",
|
2568
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
2569
|
-
)
|
2451
|
+
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2570
2452
|
def test_multiple_modes_uniform(xp):
|
2571
2453
|
# Test uniform filter for multiple extrapolation modes
|
2572
2454
|
arr = xp.asarray([[1., 0., 0.],
|
@@ -2607,8 +2489,6 @@ def test_gaussian_truncate(xp):
|
|
2607
2489
|
)
|
2608
2490
|
assert num_nonzeros_5 == 51**2
|
2609
2491
|
|
2610
|
-
nnz_kw = {'as_tuple': True} if is_torch(xp) else {}
|
2611
|
-
|
2612
2492
|
# Test truncate when sigma is a sequence.
|
2613
2493
|
f = ndimage.gaussian_filter(arr, [0.5, 2.5], truncate=3.5)
|
2614
2494
|
fpos = f > 0
|
@@ -2627,22 +2507,20 @@ def test_gaussian_truncate(xp):
|
|
2627
2507
|
|
2628
2508
|
# Test gaussian_laplace
|
2629
2509
|
y = ndimage.gaussian_laplace(x, sigma=2, truncate=3.5)
|
2630
|
-
nonzero_indices = xp.nonzero(y != 0
|
2510
|
+
nonzero_indices = xp.nonzero(y != 0)[0]
|
2631
2511
|
|
2632
2512
|
n = xp.max(nonzero_indices) - xp.min(nonzero_indices) + 1
|
2633
2513
|
assert n == 15
|
2634
2514
|
|
2635
2515
|
# Test gaussian_gradient_magnitude
|
2636
2516
|
y = ndimage.gaussian_gradient_magnitude(x, sigma=2, truncate=3.5)
|
2637
|
-
nonzero_indices = xp.nonzero(y != 0
|
2517
|
+
nonzero_indices = xp.nonzero(y != 0)[0]
|
2638
2518
|
n = xp.max(nonzero_indices) - xp.min(nonzero_indices) + 1
|
2639
2519
|
assert n == 15
|
2640
2520
|
|
2641
2521
|
|
2522
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8402")
|
2642
2523
|
def test_gaussian_radius(xp):
|
2643
|
-
if is_cupy(xp):
|
2644
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8402")
|
2645
|
-
|
2646
2524
|
# Test that Gaussian filters with radius argument produce the same
|
2647
2525
|
# results as the filters with corresponding truncate argument.
|
2648
2526
|
# radius = int(truncate * sigma + 0.5)
|
@@ -2671,10 +2549,8 @@ def test_gaussian_radius(xp):
|
|
2671
2549
|
xp_assert_equal(f1, f2)
|
2672
2550
|
|
2673
2551
|
|
2552
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8402")
|
2674
2553
|
def test_gaussian_radius_invalid(xp):
|
2675
|
-
if is_cupy(xp):
|
2676
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8402")
|
2677
|
-
|
2678
2554
|
# radius must be a nonnegative integer
|
2679
2555
|
with assert_raises(ValueError):
|
2680
2556
|
ndimage.gaussian_filter1d(xp.zeros(8), sigma=1, radius=-1)
|
@@ -2682,7 +2558,7 @@ def test_gaussian_radius_invalid(xp):
|
|
2682
2558
|
ndimage.gaussian_filter1d(xp.zeros(8), sigma=1, radius=1.1)
|
2683
2559
|
|
2684
2560
|
|
2685
|
-
@
|
2561
|
+
@uses_output_array
|
2686
2562
|
class TestThreading:
|
2687
2563
|
def check_func_thread(self, n, fun, args, out):
|
2688
2564
|
from threading import Thread
|
@@ -2695,10 +2571,9 @@ class TestThreading:
|
|
2695
2571
|
for i in range(n):
|
2696
2572
|
fun(*args, output=out[i, ...])
|
2697
2573
|
|
2574
|
+
@xfail_xp_backends("cupy",
|
2575
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2698
2576
|
def test_correlate1d(self, xp):
|
2699
|
-
if is_cupy(xp):
|
2700
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2701
|
-
|
2702
2577
|
d = np.random.randn(5000)
|
2703
2578
|
os = np.empty((4, d.size))
|
2704
2579
|
ot = np.empty_like(os)
|
@@ -2710,10 +2585,9 @@ class TestThreading:
|
|
2710
2585
|
self.check_func_thread(4, ndimage.correlate1d, (d, k), ot)
|
2711
2586
|
xp_assert_equal(os, ot)
|
2712
2587
|
|
2588
|
+
@xfail_xp_backends("cupy",
|
2589
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2713
2590
|
def test_correlate(self, xp):
|
2714
|
-
if is_cupy(xp):
|
2715
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2716
|
-
|
2717
2591
|
d = xp.asarray(np.random.randn(500, 500))
|
2718
2592
|
k = xp.asarray(np.random.randn(10, 10))
|
2719
2593
|
os = xp.empty([4] + list(d.shape))
|
@@ -2722,10 +2596,9 @@ class TestThreading:
|
|
2722
2596
|
self.check_func_thread(4, ndimage.correlate, (d, k), ot)
|
2723
2597
|
xp_assert_equal(os, ot)
|
2724
2598
|
|
2599
|
+
@xfail_xp_backends("cupy",
|
2600
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2725
2601
|
def test_median_filter(self, xp):
|
2726
|
-
if is_cupy(xp):
|
2727
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2728
|
-
|
2729
2602
|
d = xp.asarray(np.random.randn(500, 500))
|
2730
2603
|
os = xp.empty([4] + list(d.shape))
|
2731
2604
|
ot = xp.empty_like(os)
|
@@ -2733,10 +2606,9 @@ class TestThreading:
|
|
2733
2606
|
self.check_func_thread(4, ndimage.median_filter, (d, 3), ot)
|
2734
2607
|
xp_assert_equal(os, ot)
|
2735
2608
|
|
2609
|
+
@xfail_xp_backends("cupy",
|
2610
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2736
2611
|
def test_uniform_filter1d(self, xp):
|
2737
|
-
if is_cupy(xp):
|
2738
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2739
|
-
|
2740
2612
|
d = np.random.randn(5000)
|
2741
2613
|
os = np.empty((4, d.size))
|
2742
2614
|
ot = np.empty_like(os)
|
@@ -2747,10 +2619,9 @@ class TestThreading:
|
|
2747
2619
|
self.check_func_thread(4, ndimage.uniform_filter1d, (d, 5), ot)
|
2748
2620
|
xp_assert_equal(os, ot)
|
2749
2621
|
|
2622
|
+
@xfail_xp_backends("cupy",
|
2623
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2750
2624
|
def test_minmax_filter(self, xp):
|
2751
|
-
if is_cupy(xp):
|
2752
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2753
|
-
|
2754
2625
|
d = xp.asarray(np.random.randn(500, 500))
|
2755
2626
|
os = xp.empty([4] + list(d.shape))
|
2756
2627
|
ot = xp.empty_like(os)
|
@@ -2791,9 +2662,8 @@ def test_minmaximum_filter1d(xp):
|
|
2791
2662
|
xp_assert_equal(xp.asarray([9, 9, 4, 5, 6, 7, 8, 9, 9, 9]), out)
|
2792
2663
|
|
2793
2664
|
|
2665
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8401")
|
2794
2666
|
def test_uniform_filter1d_roundoff_errors(xp):
|
2795
|
-
if is_cupy(xp):
|
2796
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8401")
|
2797
2667
|
# gh-6930
|
2798
2668
|
in_ = np.repeat([0, 1, 0], [9, 9, 9])
|
2799
2669
|
in_ = xp.asarray(in_)
|
@@ -2811,14 +2681,10 @@ def test_footprint_all_zeros(xp):
|
|
2811
2681
|
ndimage.maximum_filter(arr, footprint=kernel)
|
2812
2682
|
|
2813
2683
|
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
if not hasattr(xp, "float16"):
|
2819
|
-
pytest.xfail(f"{xp} does not have float16")
|
2820
|
-
|
2821
|
-
# Test gaussian filter with xp.float16
|
2684
|
+
@xfail_xp_backends("cupy", reason="does not raise")
|
2685
|
+
@skip_xp_backends("array_api_strict", reason="no float16")
|
2686
|
+
@skip_xp_backends("dask.array", reason="no float16")
|
2687
|
+
def test_gaussian_filter_float16(xp):
|
2822
2688
|
# gh-8207
|
2823
2689
|
data = xp.asarray([1], dtype=xp.float16)
|
2824
2690
|
sigma = 1.0
|
@@ -2826,10 +2692,8 @@ def test_gaussian_filter(xp):
|
|
2826
2692
|
ndimage.gaussian_filter(data, sigma)
|
2827
2693
|
|
2828
2694
|
|
2695
|
+
@xfail_xp_backends("cupy", reason="does not raise")
|
2829
2696
|
def test_rank_filter_noninteger_rank(xp):
|
2830
|
-
if is_cupy(xp):
|
2831
|
-
pytest.xfail("CuPy does not raise")
|
2832
|
-
|
2833
2697
|
# regression test for issue 9388: ValueError for
|
2834
2698
|
# non integer rank when performing rank_filter
|
2835
2699
|
arr = xp.asarray(np.random.random((10, 20, 30)))
|
@@ -2851,12 +2715,12 @@ def test_size_footprint_both_set(xp):
|
|
2851
2715
|
)
|
2852
2716
|
|
2853
2717
|
|
2854
|
-
|
2855
|
-
def test_byte_order_median(
|
2718
|
+
# NumPy-only because 'byteorder is numpy-specific'
|
2719
|
+
def test_byte_order_median():
|
2856
2720
|
"""Regression test for #413: median_filter does not handle bytes orders."""
|
2857
|
-
a =
|
2721
|
+
a = np.arange(9, dtype='<f4').reshape(3, 3)
|
2858
2722
|
ref = ndimage.median_filter(a, (3, 3))
|
2859
|
-
b =
|
2723
|
+
b = np.arange(9, dtype='>f4').reshape(3, 3)
|
2860
2724
|
t = ndimage.median_filter(b, (3, 3))
|
2861
2725
|
assert_array_almost_equal(ref, t)
|
2862
2726
|
|
@@ -2904,3 +2768,231 @@ def test_gh_22333():
|
|
2904
2768
|
expected = [58, 67, 87, 108, 163, 108, 108, 108, 87]
|
2905
2769
|
actual = ndimage.median_filter(x, size=9, mode='constant')
|
2906
2770
|
assert_array_equal(actual, expected)
|
2771
|
+
|
2772
|
+
|
2773
|
+
@pytest.mark.filterwarnings("ignore:The given NumPy array is not writable:UserWarning")
|
2774
|
+
@pytest.mark.skip_xp_backends(cpu_only=True, exceptions=['cupy'])
|
2775
|
+
class TestVectorizedFilter:
|
2776
|
+
@pytest.mark.parametrize("axes, size",
|
2777
|
+
[(None, (3, 4, 5)), ((0, 2), (3, 4)), ((-1,), (5,))])
|
2778
|
+
@pytest.mark.parametrize("origin", [-1, 0, 1])
|
2779
|
+
@pytest.mark.parametrize("mode",
|
2780
|
+
['reflect', 'nearest', 'mirror', 'wrap', 'constant'])
|
2781
|
+
@pytest.mark.parametrize("use_output", [False, True])
|
2782
|
+
def test_against_generic_filter(self, axes, size, origin, mode, use_output, xp):
|
2783
|
+
rng = np.random.default_rng(435982456983456987356)
|
2784
|
+
|
2785
|
+
if use_output and (is_dask(xp) or is_jax(xp)):
|
2786
|
+
pytest.skip("Requires mutable arrays.")
|
2787
|
+
|
2788
|
+
input = rng.random(size=(11, 12, 13))
|
2789
|
+
input_copy = input.copy() # check that it is not modified
|
2790
|
+
output = xp.zeros(input.shape) if use_output else None
|
2791
|
+
|
2792
|
+
kwargs = dict(axes=axes, size=size, origin=origin, mode=mode)
|
2793
|
+
ref = ndimage.generic_filter(input, np.mean, **kwargs)
|
2794
|
+
kwargs['output'] = output
|
2795
|
+
res = ndimage.vectorized_filter(xp.asarray(input.tolist()),
|
2796
|
+
xp.mean, **kwargs)
|
2797
|
+
xp_assert_close(res, xp.asarray(ref.tolist()), atol=1e-15)
|
2798
|
+
if use_output:
|
2799
|
+
xp_assert_equal(output, res)
|
2800
|
+
|
2801
|
+
if not (is_array_api_strict(xp) or is_dask(xp)):
|
2802
|
+
# currently requires support for [..., mask] indexing
|
2803
|
+
kwargs.pop('size')
|
2804
|
+
kwargs.pop('output')
|
2805
|
+
kwargs['footprint'] = rng.random(size=size or input.shape) > 0.5
|
2806
|
+
ref = ndimage.generic_filter(input, np.mean, **kwargs)
|
2807
|
+
kwargs['footprint'] = xp.asarray(kwargs['footprint'])
|
2808
|
+
kwargs['output'] = output
|
2809
|
+
res = ndimage.vectorized_filter(xp.asarray(input.tolist()),
|
2810
|
+
xp.mean, **kwargs)
|
2811
|
+
xp_assert_close(res, xp.asarray(ref.tolist()), atol=1e-15)
|
2812
|
+
if use_output:
|
2813
|
+
xp_assert_equal(output, res)
|
2814
|
+
|
2815
|
+
xp_assert_equal(xp.asarray(input), xp.asarray(input_copy))
|
2816
|
+
|
2817
|
+
@pytest.mark.parametrize("dtype",
|
2818
|
+
["uint8", "uint16", "uint32", "uint64",
|
2819
|
+
"int8", "int16", "int32", "int64",
|
2820
|
+
"float32", "float64", "complex64", "complex128"])
|
2821
|
+
@pytest.mark.parametrize("batch_memory", [1, 16*3, np.inf])
|
2822
|
+
@pytest.mark.parametrize("use_footprint", [False, True])
|
2823
|
+
def test_dtype_batch_memory(self, dtype, batch_memory, use_footprint, xp):
|
2824
|
+
rng = np.random.default_rng(435982456983456987356)
|
2825
|
+
w = 3
|
2826
|
+
|
2827
|
+
if is_jax(xp) and not (batch_memory == 1):
|
2828
|
+
pytest.skip("Requires mutable array.")
|
2829
|
+
if is_torch(xp) and dtype in {'uint16', 'uint32', 'uint64'}:
|
2830
|
+
pytest.skip("Needs uint support.")
|
2831
|
+
|
2832
|
+
dtype = getattr(xp, dtype)
|
2833
|
+
|
2834
|
+
if use_footprint:
|
2835
|
+
if (is_dask(xp) or is_array_api_strict(xp)):
|
2836
|
+
pytest.skip("Requires [..., mask] indexing.")
|
2837
|
+
footprint = xp.asarray([True, False, True])
|
2838
|
+
kwargs = dict(footprint=footprint, batch_memory=batch_memory)
|
2839
|
+
else:
|
2840
|
+
footprint = xp.asarray([True, True, True])
|
2841
|
+
kwargs = dict(size=w, batch_memory=batch_memory)
|
2842
|
+
|
2843
|
+
# The intent here is to exercise all the code paths involved in `batch_memory`
|
2844
|
+
# and `output` handling. To test the limited-memory case, `batch_memory=16*3`
|
2845
|
+
# is chosen to be just large enough for a *single* window of `complex128` to
|
2846
|
+
# fit, and `n` is large enough that a whole sliding window view of `uint8`s
|
2847
|
+
# *won't* fit.
|
2848
|
+
n = 16*3 + 1
|
2849
|
+
input = rng.integers(0, 42, size=(n,))
|
2850
|
+
input = input + input*1j if xp.isdtype(dtype, 'complex floating') else input
|
2851
|
+
input_padded = xp.asarray(np.pad(input, [(1, 1)], mode='symmetric'),
|
2852
|
+
dtype=dtype)
|
2853
|
+
input = xp.asarray(input, dtype=dtype)
|
2854
|
+
|
2855
|
+
ref = [xp.sum(input_padded[i: i + w][footprint]) for i in range(n)]
|
2856
|
+
sum_dtype = xp.sum(input_padded).dtype
|
2857
|
+
|
2858
|
+
message = "`batch_memory` is insufficient for minimum chunk size."
|
2859
|
+
context = (pytest.raises(ValueError, match=message)
|
2860
|
+
if batch_memory == 1 else contextlib.nullcontext())
|
2861
|
+
with context:
|
2862
|
+
res = ndimage.vectorized_filter(input, xp.sum, **kwargs)
|
2863
|
+
xp_assert_close(res, xp.astype(xp.stack(ref), sum_dtype))
|
2864
|
+
assert res.dtype == sum_dtype
|
2865
|
+
|
2866
|
+
output = xp.empty_like(input)
|
2867
|
+
res = ndimage.vectorized_filter(input, xp.sum, output=output, **kwargs)
|
2868
|
+
xp_assert_close(res, xp.astype(xp.stack(ref), dtype))
|
2869
|
+
assert res.dtype == dtype
|
2870
|
+
|
2871
|
+
def test_mode_valid(self, xp):
|
2872
|
+
rng = np.random.default_rng(435982456983456987356)
|
2873
|
+
input = rng.random(size=(10, 11))
|
2874
|
+
input_xp = xp.asarray(input)
|
2875
|
+
input_xp_copy = xp_copy(input_xp) # check that it is not modified
|
2876
|
+
size = (3, 5)
|
2877
|
+
|
2878
|
+
res = ndimage.vectorized_filter(input_xp, xp.mean, size=size, mode='valid')
|
2879
|
+
|
2880
|
+
view = np.lib.stride_tricks.sliding_window_view(input, size)
|
2881
|
+
ref = np.mean(view, axis=(-2, -1))
|
2882
|
+
|
2883
|
+
xp_assert_close(res, xp.asarray(ref))
|
2884
|
+
assert res.shape == tuple(input.shape - np.asarray(size) + 1)
|
2885
|
+
xp_assert_equal(input_xp, input_xp_copy)
|
2886
|
+
|
2887
|
+
def test_input_validation(self, xp):
|
2888
|
+
input = xp.ones((10, 10))
|
2889
|
+
function = xp.mean
|
2890
|
+
size = 2
|
2891
|
+
footprint = xp.ones((2, 2))
|
2892
|
+
|
2893
|
+
message = "`function` must be a callable."
|
2894
|
+
with pytest.raises(ValueError, match=message):
|
2895
|
+
ndimage.vectorized_filter(input, "eggplant", size=size)
|
2896
|
+
|
2897
|
+
message = "Either `size` or `footprint` must be provided."
|
2898
|
+
with pytest.raises(ValueError, match=message):
|
2899
|
+
ndimage.vectorized_filter(input, function)
|
2900
|
+
|
2901
|
+
message = "Either `size` or `footprint` may be provided, not both."
|
2902
|
+
with pytest.raises(ValueError, match=message):
|
2903
|
+
ndimage.vectorized_filter(input, function, size=size, footprint=footprint)
|
2904
|
+
|
2905
|
+
message = "All elements of `size` must be positive integers."
|
2906
|
+
with pytest.raises(ValueError, match=message):
|
2907
|
+
ndimage.vectorized_filter(input, function, size=(1, -1))
|
2908
|
+
with pytest.raises(ValueError, match=message):
|
2909
|
+
ndimage.vectorized_filter(input, function, size=0)
|
2910
|
+
|
2911
|
+
message = "The dimensionality of the window"
|
2912
|
+
with pytest.raises(ValueError, match=message):
|
2913
|
+
ndimage.vectorized_filter(input, function, size=(1, 2, 3))
|
2914
|
+
with pytest.raises(ValueError, match=message):
|
2915
|
+
ndimage.vectorized_filter(input, function, footprint=xp.ones((2, 2, 2)))
|
2916
|
+
|
2917
|
+
message = "`axes` must be provided if the dimensionality..."
|
2918
|
+
with pytest.raises(ValueError, match=message):
|
2919
|
+
ndimage.vectorized_filter(input, function, size=(1,))
|
2920
|
+
|
2921
|
+
message = "All elements of `origin` must be integers"
|
2922
|
+
with pytest.raises(ValueError, match=message):
|
2923
|
+
ndimage.vectorized_filter(input, function, size=size, origin=(1, 1.5))
|
2924
|
+
|
2925
|
+
message = "`origin` must be an integer or tuple of integers with length..."
|
2926
|
+
with pytest.raises(ValueError, match=message):
|
2927
|
+
ndimage.vectorized_filter(input, function, size=size, origin=(1, 2, 3))
|
2928
|
+
|
2929
|
+
message = "`mode` must be one of..."
|
2930
|
+
with pytest.raises(ValueError, match=message):
|
2931
|
+
ndimage.vectorized_filter(input, function, size=size, mode='coconut')
|
2932
|
+
|
2933
|
+
message = "`mode='valid'` is incompatible with use of `origin`."
|
2934
|
+
with pytest.raises(ValueError, match=message):
|
2935
|
+
ndimage.vectorized_filter(input, function, size=size,
|
2936
|
+
mode='valid', origin=1)
|
2937
|
+
|
2938
|
+
message = "Use of `cval` is compatible only with `mode='constant'`."
|
2939
|
+
with pytest.raises(ValueError, match=message):
|
2940
|
+
ndimage.vectorized_filter(input, function, size=size, mode='valid', cval=1)
|
2941
|
+
|
2942
|
+
other_messages = "|Unsupported|The array_api_strict|new|Value 'a duck'"
|
2943
|
+
message = "`cval` must include only numbers." + other_messages
|
2944
|
+
with pytest.raises((ValueError, TypeError), match=message):
|
2945
|
+
ndimage.vectorized_filter(input, function, size=size,
|
2946
|
+
mode='constant', cval='a duck')
|
2947
|
+
|
2948
|
+
message = "`batch_memory` must be positive number." + other_messages
|
2949
|
+
with pytest.raises(ValueError, match=message):
|
2950
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory=0)
|
2951
|
+
with pytest.raises(ValueError, match=message):
|
2952
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory=(1, 2))
|
2953
|
+
with pytest.raises((ValueError, TypeError), match=message):
|
2954
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory="a duck")
|
2955
|
+
|
2956
|
+
@pytest.mark.parametrize('shape', [(0,), (1, 0), (0, 1, 0)])
|
2957
|
+
def test_zero_size(self, shape, xp):
|
2958
|
+
input = xp.empty(shape)
|
2959
|
+
res = ndimage.vectorized_filter(input, xp.mean, size=1)
|
2960
|
+
xp_assert_equal(res, input)
|
2961
|
+
|
2962
|
+
@pytest.mark.filterwarnings("ignore:Mean of empty slice.:RuntimeWarning")
|
2963
|
+
def test_edge_cases(self, xp):
|
2964
|
+
rng = np.random.default_rng(4835982345234982)
|
2965
|
+
function = xp.mean
|
2966
|
+
|
2967
|
+
# 0-D input
|
2968
|
+
input = xp.asarray(1.)
|
2969
|
+
res = ndimage.vectorized_filter(input, function, size=())
|
2970
|
+
xp_assert_equal(res, xp.asarray(function(input, axis=())))
|
2971
|
+
|
2972
|
+
if not (is_array_api_strict(xp) or is_dask(xp)):
|
2973
|
+
res = ndimage.vectorized_filter(input, function, footprint=True)
|
2974
|
+
xp_assert_equal(res, xp.asarray(function(input[True], axis=())))
|
2975
|
+
|
2976
|
+
res = ndimage.vectorized_filter(input, function, footprint=False)
|
2977
|
+
xp_assert_equal(res, xp.asarray(function(input[False], axis=())))
|
2978
|
+
|
2979
|
+
# 1x1 window
|
2980
|
+
input = xp.asarray(rng.random((5, 5)))
|
2981
|
+
res = ndimage.vectorized_filter(input, function, size=1)
|
2982
|
+
xp_assert_equal(res, input)
|
2983
|
+
|
2984
|
+
# window is bigger than input shouldn't be a problem
|
2985
|
+
res = ndimage.vectorized_filter(input, function, size=21)
|
2986
|
+
ref = ndimage.vectorized_filter(input, function, size=21)
|
2987
|
+
xp_assert_close(res, ref)
|
2988
|
+
|
2989
|
+
|
2990
|
+
@given(x=npst.arrays(dtype=np.float64,
|
2991
|
+
shape=st.integers(min_value=1, max_value=1000)),
|
2992
|
+
size=st.integers(min_value=1, max_value=50),
|
2993
|
+
mode=st.sampled_from(["constant", "mirror", "wrap", "reflect",
|
2994
|
+
"nearest"]),
|
2995
|
+
)
|
2996
|
+
def test_gh_22586_crash_property(x, size, mode):
|
2997
|
+
# property-based test for median_filter resilience to hard crashing
|
2998
|
+
ndimage.median_filter(x, size=size, mode=mode)
|