scipy 1.15.3__cp312-cp312-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp312-cp312-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scipy/__config__.py +10 -10
- scipy/__init__.py +3 -6
- scipy/_cyutility.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_array_api.py +486 -161
- scipy/_lib/_array_api_compat_vendor.py +9 -0
- scipy/_lib/_bunch.py +4 -0
- scipy/_lib/_ccallback_c.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_docscrape.py +1 -1
- scipy/_lib/_elementwise_iterative_method.py +15 -26
- scipy/_lib/_fpumode.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_ccallback.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_test_deprecation_call.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_test_deprecation_def.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_testutils.py +6 -2
- scipy/_lib/_uarray/_uarray.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/pyprima/__init__.py +212 -0
- scipy/_lib/pyprima/cobyla/__init__.py +0 -0
- scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
- scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
- scipy/_lib/pyprima/cobyla/geometry.py +226 -0
- scipy/_lib/pyprima/cobyla/initialize.py +215 -0
- scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
- scipy/_lib/pyprima/cobyla/update.py +289 -0
- scipy/_lib/pyprima/common/__init__.py +0 -0
- scipy/_lib/pyprima/common/_bounds.py +34 -0
- scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
- scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
- scipy/_lib/pyprima/common/_project.py +173 -0
- scipy/_lib/pyprima/common/checkbreak.py +93 -0
- scipy/_lib/pyprima/common/consts.py +47 -0
- scipy/_lib/pyprima/common/evaluate.py +99 -0
- scipy/_lib/pyprima/common/history.py +38 -0
- scipy/_lib/pyprima/common/infos.py +30 -0
- scipy/_lib/pyprima/common/linalg.py +435 -0
- scipy/_lib/pyprima/common/message.py +290 -0
- scipy/_lib/pyprima/common/powalg.py +131 -0
- scipy/_lib/pyprima/common/preproc.py +277 -0
- scipy/_lib/pyprima/common/present.py +5 -0
- scipy/_lib/pyprima/common/ratio.py +54 -0
- scipy/_lib/pyprima/common/redrho.py +47 -0
- scipy/_lib/pyprima/common/selectx.py +296 -0
- scipy/_lib/tests/test__util.py +105 -121
- scipy/_lib/tests/test_array_api.py +166 -35
- scipy/_lib/tests/test_bunch.py +7 -0
- scipy/_lib/tests/test_ccallback.py +2 -10
- scipy/_lib/tests/test_public_api.py +13 -0
- scipy/cluster/_hierarchy.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/cluster/_optimal_leaf_ordering.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/cluster/_vq.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/cluster/hierarchy.py +393 -223
- scipy/cluster/tests/test_hierarchy.py +273 -335
- scipy/cluster/tests/test_vq.py +45 -61
- scipy/cluster/vq.py +39 -35
- scipy/conftest.py +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/fftpack/tests/test_basic.py +2 -4
- scipy/fftpack/tests/test_real_transforms.py +8 -9
- scipy/integrate/_bvp.py +9 -3
- scipy/integrate/_cubature.py +3 -2
- scipy/integrate/_dop.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_lsoda.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_ode.py +9 -2
- scipy/integrate/_odepack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_quad_vec.py +21 -29
- scipy/integrate/_quadpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_quadpack_py.py +11 -7
- scipy/integrate/_quadrature.py +3 -3
- scipy/integrate/_rules/_base.py +2 -2
- scipy/integrate/_tanhsinh.py +48 -47
- scipy/integrate/_test_multivariate.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_test_odeint_banded.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_vode.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/tests/test__quad_vec.py +0 -6
- scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
- scipy/integrate/tests/test_cubature.py +21 -35
- scipy/integrate/tests/test_quadrature.py +6 -8
- scipy/integrate/tests/test_tanhsinh.py +56 -48
- scipy/interpolate/__init__.py +70 -58
- scipy/interpolate/_bary_rational.py +22 -22
- scipy/interpolate/_bsplines.py +119 -66
- scipy/interpolate/_cubic.py +65 -50
- scipy/interpolate/_dfitpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_dierckx.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_fitpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_fitpack2.py +9 -6
- scipy/interpolate/_fitpack_impl.py +32 -26
- scipy/interpolate/_fitpack_repro.py +23 -19
- scipy/interpolate/_interpnd.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_interpolate.py +30 -12
- scipy/interpolate/_ndbspline.py +13 -18
- scipy/interpolate/_ndgriddata.py +5 -8
- scipy/interpolate/_polyint.py +95 -31
- scipy/interpolate/_ppoly.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_rbf.py +2 -2
- scipy/interpolate/_rbfinterp.py +1 -1
- scipy/interpolate/_rbfinterp_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_rgi.py +31 -26
- scipy/interpolate/_rgi_cython.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/dfitpack.py +0 -20
- scipy/interpolate/interpnd.py +1 -2
- scipy/interpolate/tests/test_bary_rational.py +2 -2
- scipy/interpolate/tests/test_bsplines.py +97 -1
- scipy/interpolate/tests/test_fitpack2.py +39 -1
- scipy/interpolate/tests/test_interpnd.py +32 -20
- scipy/interpolate/tests/test_interpolate.py +48 -4
- scipy/interpolate/tests/test_rgi.py +2 -1
- scipy/io/_fast_matrix_market/__init__.py +2 -0
- scipy/io/_fast_matrix_market/_fmm_core.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/arff/tests/test_arffread.py +3 -3
- scipy/io/matlab/__init__.py +5 -3
- scipy/io/matlab/_mio.py +4 -1
- scipy/io/matlab/_mio5.py +19 -13
- scipy/io/matlab/_mio5_utils.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/matlab/_mio_utils.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/matlab/_miobase.py +4 -1
- scipy/io/matlab/_streams.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/matlab/tests/test_mio.py +46 -18
- scipy/io/matlab/tests/test_mio_funcs.py +1 -1
- scipy/io/tests/test_mmio.py +7 -1
- scipy/io/tests/test_wavfile.py +41 -0
- scipy/io/wavfile.py +57 -10
- scipy/linalg/_basic.py +113 -86
- scipy/linalg/_cythonized_array_utils.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_decomp.py +22 -9
- scipy/linalg/_decomp_cholesky.py +28 -13
- scipy/linalg/_decomp_cossin.py +45 -30
- scipy/linalg/_decomp_interpolative.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_decomp_ldl.py +4 -1
- scipy/linalg/_decomp_lu.py +18 -6
- scipy/linalg/_decomp_lu_cython.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_decomp_polar.py +2 -0
- scipy/linalg/_decomp_qr.py +6 -2
- scipy/linalg/_decomp_qz.py +3 -0
- scipy/linalg/_decomp_schur.py +3 -1
- scipy/linalg/_decomp_svd.py +13 -2
- scipy/linalg/_decomp_update.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_expm_frechet.py +4 -0
- scipy/linalg/_fblas.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_flapack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_linalg_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs.py +187 -4
- scipy/linalg/_matfuncs_expm.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +1 -99
- scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_procrustes.py +2 -0
- scipy/linalg/_sketches.py +17 -6
- scipy/linalg/_solve_toeplitz.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_solvers.py +7 -2
- scipy/linalg/_special_matrices.py +26 -36
- scipy/linalg/cython_blas.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/cython_lapack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/lapack.py +22 -2
- scipy/linalg/tests/_cython_examples/meson.build +7 -0
- scipy/linalg/tests/test_basic.py +31 -16
- scipy/linalg/tests/test_batch.py +588 -0
- scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
- scipy/linalg/tests/test_decomp.py +40 -3
- scipy/linalg/tests/test_decomp_cossin.py +14 -0
- scipy/linalg/tests/test_decomp_ldl.py +1 -1
- scipy/linalg/tests/test_lapack.py +115 -7
- scipy/linalg/tests/test_matfuncs.py +157 -102
- scipy/linalg/tests/test_procrustes.py +0 -7
- scipy/linalg/tests/test_solve_toeplitz.py +1 -1
- scipy/linalg/tests/test_special_matrices.py +1 -5
- scipy/ndimage/__init__.py +1 -0
- scipy/ndimage/_ctest.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_cytest.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_delegators.py +8 -2
- scipy/ndimage/_filters.py +453 -5
- scipy/ndimage/_interpolation.py +36 -6
- scipy/ndimage/_measurements.py +4 -2
- scipy/ndimage/_morphology.py +5 -0
- scipy/ndimage/_nd_image.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_ni_docstrings.py +5 -1
- scipy/ndimage/_ni_label.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_ni_support.py +1 -5
- scipy/ndimage/_rank_filter_1d.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_support_alternative_backends.py +18 -6
- scipy/ndimage/tests/test_filters.py +370 -259
- scipy/ndimage/tests/test_fourier.py +7 -9
- scipy/ndimage/tests/test_interpolation.py +68 -61
- scipy/ndimage/tests/test_measurements.py +18 -35
- scipy/ndimage/tests/test_morphology.py +143 -131
- scipy/ndimage/tests/test_splines.py +1 -3
- scipy/odr/__odrpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_basinhopping.py +13 -7
- scipy/optimize/_bglu_dense.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_bracket.py +17 -24
- scipy/optimize/_chandrupatla.py +9 -10
- scipy/optimize/_cobyla_py.py +104 -123
- scipy/optimize/_constraints.py +14 -10
- scipy/optimize/_differentiable_functions.py +371 -230
- scipy/optimize/_differentialevolution.py +4 -3
- scipy/optimize/_direct.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_dual_annealing.py +1 -1
- scipy/optimize/_elementwise.py +1 -4
- scipy/optimize/_group_columns.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_highspy/_core.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_highspy/_highs_options.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lbfgsb.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lbfgsb_py.py +57 -16
- scipy/optimize/_linprog_doc.py +2 -2
- scipy/optimize/_linprog_highs.py +2 -2
- scipy/optimize/_linprog_ip.py +25 -10
- scipy/optimize/_linprog_util.py +14 -16
- scipy/optimize/_lsap.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lsq/common.py +3 -3
- scipy/optimize/_lsq/dogbox.py +16 -2
- scipy/optimize/_lsq/givens_elimination.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lsq/least_squares.py +198 -126
- scipy/optimize/_lsq/lsq_linear.py +6 -6
- scipy/optimize/_lsq/trf.py +35 -8
- scipy/optimize/_milp.py +3 -1
- scipy/optimize/_minimize.py +105 -36
- scipy/optimize/_minpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_minpack_py.py +21 -14
- scipy/optimize/_moduleTNC.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_nnls.py +20 -21
- scipy/optimize/_nonlin.py +34 -3
- scipy/optimize/_numdiff.py +288 -110
- scipy/optimize/_optimize.py +86 -48
- scipy/optimize/_pava_pybind.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_remove_redundancy.py +5 -5
- scipy/optimize/_root_scalar.py +1 -1
- scipy/optimize/_shgo.py +6 -0
- scipy/optimize/_shgo_lib/_complex.py +1 -1
- scipy/optimize/_slsqp_py.py +216 -124
- scipy/optimize/_slsqplib.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_spectral.py +1 -1
- scipy/optimize/_tnc.py +8 -1
- scipy/optimize/_trlib/_trlib.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_trustregion.py +20 -6
- scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
- scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
- scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
- scipy/optimize/_trustregion_constr/projections.py +12 -8
- scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
- scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
- scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
- scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
- scipy/optimize/_trustregion_exact.py +0 -1
- scipy/optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_zeros_py.py +97 -17
- scipy/optimize/cython_optimize/_zeros.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/slsqp.py +0 -1
- scipy/optimize/tests/test__basinhopping.py +1 -1
- scipy/optimize/tests/test__differential_evolution.py +4 -4
- scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
- scipy/optimize/tests/test__numdiff.py +66 -22
- scipy/optimize/tests/test__remove_redundancy.py +2 -2
- scipy/optimize/tests/test__shgo.py +9 -1
- scipy/optimize/tests/test_bracket.py +36 -46
- scipy/optimize/tests/test_chandrupatla.py +133 -135
- scipy/optimize/tests/test_cobyla.py +74 -45
- scipy/optimize/tests/test_constraints.py +1 -1
- scipy/optimize/tests/test_differentiable_functions.py +226 -6
- scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
- scipy/optimize/tests/test_least_squares.py +125 -13
- scipy/optimize/tests/test_linear_assignment.py +3 -3
- scipy/optimize/tests/test_linprog.py +3 -3
- scipy/optimize/tests/test_lsq_linear.py +6 -6
- scipy/optimize/tests/test_minimize_constrained.py +2 -2
- scipy/optimize/tests/test_minpack.py +4 -4
- scipy/optimize/tests/test_nnls.py +43 -3
- scipy/optimize/tests/test_nonlin.py +36 -0
- scipy/optimize/tests/test_optimize.py +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_peak_finding_utils.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_polyutils.py +172 -0
- scipy/signal/_short_time_fft.py +519 -70
- scipy/signal/_signal_api.py +30 -0
- scipy/signal/_signaltools.py +719 -399
- scipy/signal/_sigtools.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_sosfilt.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_spectral_py.py +230 -50
- scipy/signal/_spline.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_spline_filters.py +108 -68
- scipy/signal/_support_alternative_backends.py +73 -0
- scipy/signal/_upfirdn.py +4 -1
- scipy/signal/_upfirdn_apply.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_waveforms.py +2 -11
- scipy/signal/_wavelets.py +1 -1
- scipy/signal/fir_filter_design.py +1 -0
- scipy/signal/spline.py +4 -11
- scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
- scipy/signal/tests/test_bsplines.py +114 -79
- scipy/signal/tests/test_cont2discrete.py +9 -2
- scipy/signal/tests/test_filter_design.py +721 -481
- scipy/signal/tests/test_fir_filter_design.py +332 -140
- scipy/signal/tests/test_savitzky_golay.py +4 -3
- scipy/signal/tests/test_short_time_fft.py +221 -3
- scipy/signal/tests/test_signaltools.py +2144 -1348
- scipy/signal/tests/test_spectral.py +50 -6
- scipy/signal/tests/test_splines.py +161 -96
- scipy/signal/tests/test_upfirdn.py +84 -50
- scipy/signal/tests/test_waveforms.py +20 -0
- scipy/signal/tests/test_windows.py +607 -466
- scipy/signal/windows/_windows.py +287 -148
- scipy/sparse/__init__.py +23 -4
- scipy/sparse/_base.py +270 -108
- scipy/sparse/_bsr.py +7 -4
- scipy/sparse/_compressed.py +59 -231
- scipy/sparse/_construct.py +90 -38
- scipy/sparse/_coo.py +115 -181
- scipy/sparse/_csc.py +4 -4
- scipy/sparse/_csparsetools.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/_csr.py +2 -2
- scipy/sparse/_data.py +48 -48
- scipy/sparse/_dia.py +105 -18
- scipy/sparse/_dok.py +0 -23
- scipy/sparse/_index.py +4 -4
- scipy/sparse/_matrix.py +23 -0
- scipy/sparse/_sparsetools.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/_sputils.py +37 -22
- scipy/sparse/base.py +0 -9
- scipy/sparse/bsr.py +0 -14
- scipy/sparse/compressed.py +0 -23
- scipy/sparse/construct.py +0 -6
- scipy/sparse/coo.py +0 -14
- scipy/sparse/csc.py +0 -3
- scipy/sparse/csgraph/_flow.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_matching.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_reordering.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_shortest_path.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_tools.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_traversal.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/tests/test_matching.py +14 -2
- scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
- scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
- scipy/sparse/csr.py +0 -5
- scipy/sparse/data.py +1 -6
- scipy/sparse/dia.py +0 -7
- scipy/sparse/dok.py +0 -10
- scipy/sparse/linalg/_dsolve/_superlu.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
- scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
- scipy/sparse/linalg/_eigen/arpack/_arpack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
- scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
- scipy/sparse/linalg/_interface.py +17 -18
- scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
- scipy/sparse/linalg/_isolve/iterative.py +51 -45
- scipy/sparse/linalg/_isolve/lgmres.py +6 -6
- scipy/sparse/linalg/_isolve/minres.py +5 -5
- scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
- scipy/sparse/linalg/_isolve/utils.py +2 -8
- scipy/sparse/linalg/_matfuncs.py +1 -1
- scipy/sparse/linalg/_norm.py +1 -1
- scipy/sparse/linalg/_propack/_cpropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_spropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
- scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
- scipy/sparse/tests/test_arithmetic1d.py +5 -2
- scipy/sparse/tests/test_base.py +214 -42
- scipy/sparse/tests/test_common1d.py +7 -7
- scipy/sparse/tests/test_construct.py +1 -1
- scipy/sparse/tests/test_coo.py +272 -4
- scipy/sparse/tests/test_sparsetools.py +5 -0
- scipy/sparse/tests/test_sputils.py +36 -7
- scipy/spatial/_ckdtree.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_distance_pybind.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_distance_wrap.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_hausdorff.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_qhull.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_voronoi.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/distance.py +49 -42
- scipy/spatial/tests/test_distance.py +15 -1
- scipy/spatial/tests/test_kdtree.py +1 -0
- scipy/spatial/tests/test_qhull.py +7 -2
- scipy/spatial/transform/__init__.py +5 -3
- scipy/spatial/transform/_rigid_transform.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/transform/_rotation.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
- scipy/spatial/transform/tests/test_rotation.py +1213 -832
- scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
- scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
- scipy/special/__init__.py +1 -47
- scipy/special/_add_newdocs.py +34 -772
- scipy/special/_basic.py +22 -25
- scipy/special/_comb.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_ellip_harm_2.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_gufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_logsumexp.py +67 -58
- scipy/special/_orthogonal.pyi +1 -1
- scipy/special/_specfun.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_special_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_spherical_bessel.py +4 -4
- scipy/special/_support_alternative_backends.py +212 -119
- scipy/special/_test_internal.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_testutils.py +4 -4
- scipy/special/_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_ufuncs.pyi +1 -0
- scipy/special/_ufuncs.pyx +215 -1400
- scipy/special/_ufuncs_cxx.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_ufuncs_cxx.pxd +2 -15
- scipy/special/_ufuncs_cxx.pyx +5 -44
- scipy/special/_ufuncs_cxx_defs.h +2 -16
- scipy/special/_ufuncs_defs.h +0 -8
- scipy/special/cython_special.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/cython_special.pxd +1 -1
- scipy/special/tests/_cython_examples/meson.build +10 -1
- scipy/special/tests/test_basic.py +153 -20
- scipy/special/tests/test_boost_ufuncs.py +3 -0
- scipy/special/tests/test_cdflib.py +35 -11
- scipy/special/tests/test_gammainc.py +16 -0
- scipy/special/tests/test_hyp2f1.py +2 -2
- scipy/special/tests/test_log1mexp.py +85 -0
- scipy/special/tests/test_logsumexp.py +206 -64
- scipy/special/tests/test_mpmath.py +1 -0
- scipy/special/tests/test_nan_inputs.py +1 -1
- scipy/special/tests/test_orthogonal.py +17 -18
- scipy/special/tests/test_sf_error.py +3 -2
- scipy/special/tests/test_sph_harm.py +6 -7
- scipy/special/tests/test_support_alternative_backends.py +211 -76
- scipy/stats/__init__.py +4 -1
- scipy/stats/_ansari_swilk_statistics.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_axis_nan_policy.py +5 -12
- scipy/stats/_biasedurn.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_continued_fraction.py +387 -0
- scipy/stats/_continuous_distns.py +277 -310
- scipy/stats/_correlation.py +1 -1
- scipy/stats/_covariance.py +6 -3
- scipy/stats/_discrete_distns.py +39 -32
- scipy/stats/_distn_infrastructure.py +39 -12
- scipy/stats/_distribution_infrastructure.py +900 -238
- scipy/stats/_entropy.py +9 -10
- scipy/{_lib → stats}/_finite_differences.py +1 -1
- scipy/stats/_hypotests.py +83 -50
- scipy/stats/_kde.py +53 -49
- scipy/stats/_ksstats.py +1 -1
- scipy/stats/_levy_stable/__init__.py +7 -15
- scipy/stats/_levy_stable/levyst.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_morestats.py +118 -73
- scipy/stats/_mstats_basic.py +13 -17
- scipy/stats/_mstats_extras.py +8 -8
- scipy/stats/_multivariate.py +89 -113
- scipy/stats/_new_distributions.py +97 -20
- scipy/stats/_page_trend_test.py +12 -5
- scipy/stats/_probability_distribution.py +265 -43
- scipy/stats/_qmc.py +14 -9
- scipy/stats/_qmc_cy.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_qmvnt.py +16 -95
- scipy/stats/_qmvnt_cy.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/rcont.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_resampling.py +4 -29
- scipy/stats/_sampling.py +1 -1
- scipy/stats/_sobol.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_stats.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_stats_mstats_common.py +21 -2
- scipy/stats/_stats_py.py +550 -476
- scipy/stats/_stats_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
- scipy/stats/_variation.py +6 -8
- scipy/stats/_wilcoxon.py +13 -7
- scipy/stats/tests/common_tests.py +6 -4
- scipy/stats/tests/test_axis_nan_policy.py +62 -24
- scipy/stats/tests/test_continued_fraction.py +173 -0
- scipy/stats/tests/test_continuous.py +379 -60
- scipy/stats/tests/test_continuous_basic.py +18 -12
- scipy/stats/tests/test_discrete_basic.py +14 -8
- scipy/stats/tests/test_discrete_distns.py +16 -16
- scipy/stats/tests/test_distributions.py +95 -75
- scipy/stats/tests/test_entropy.py +40 -48
- scipy/stats/tests/test_fit.py +4 -3
- scipy/stats/tests/test_hypotests.py +153 -24
- scipy/stats/tests/test_kdeoth.py +109 -41
- scipy/stats/tests/test_marray.py +289 -0
- scipy/stats/tests/test_morestats.py +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.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +1262 -1269
- scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
- scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
- scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
- scipy/_lib/array_api_extra/_funcs.py +0 -484
- scipy/_lib/array_api_extra/_typing.py +0 -8
- scipy/interpolate/_bspl.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_cobyla.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_cython_nnls.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_slsqp.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/qhull_src/COPYING.txt +0 -38
- scipy/special/libsf_error_state.so +0 -0
- scipy/special/tests/test_log_softmax.py +0 -109
- scipy/special/tests/test_xsf_cuda.py +0 -114
- scipy/special/xsf/binom.h +0 -89
- scipy/special/xsf/cdflib.h +0 -100
- scipy/special/xsf/cephes/airy.h +0 -307
- scipy/special/xsf/cephes/besselpoly.h +0 -51
- scipy/special/xsf/cephes/beta.h +0 -257
- scipy/special/xsf/cephes/cbrt.h +0 -131
- scipy/special/xsf/cephes/chbevl.h +0 -85
- scipy/special/xsf/cephes/chdtr.h +0 -193
- scipy/special/xsf/cephes/const.h +0 -87
- scipy/special/xsf/cephes/ellie.h +0 -293
- scipy/special/xsf/cephes/ellik.h +0 -251
- scipy/special/xsf/cephes/ellpe.h +0 -107
- scipy/special/xsf/cephes/ellpk.h +0 -117
- scipy/special/xsf/cephes/expn.h +0 -260
- scipy/special/xsf/cephes/gamma.h +0 -398
- scipy/special/xsf/cephes/hyp2f1.h +0 -596
- scipy/special/xsf/cephes/hyperg.h +0 -361
- scipy/special/xsf/cephes/i0.h +0 -149
- scipy/special/xsf/cephes/i1.h +0 -158
- scipy/special/xsf/cephes/igam.h +0 -421
- scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
- scipy/special/xsf/cephes/igami.h +0 -313
- scipy/special/xsf/cephes/j0.h +0 -225
- scipy/special/xsf/cephes/j1.h +0 -198
- scipy/special/xsf/cephes/jv.h +0 -715
- scipy/special/xsf/cephes/k0.h +0 -164
- scipy/special/xsf/cephes/k1.h +0 -163
- scipy/special/xsf/cephes/kn.h +0 -243
- scipy/special/xsf/cephes/lanczos.h +0 -112
- scipy/special/xsf/cephes/ndtr.h +0 -275
- scipy/special/xsf/cephes/poch.h +0 -85
- scipy/special/xsf/cephes/polevl.h +0 -167
- scipy/special/xsf/cephes/psi.h +0 -194
- scipy/special/xsf/cephes/rgamma.h +0 -111
- scipy/special/xsf/cephes/scipy_iv.h +0 -811
- scipy/special/xsf/cephes/shichi.h +0 -248
- scipy/special/xsf/cephes/sici.h +0 -224
- scipy/special/xsf/cephes/sindg.h +0 -221
- scipy/special/xsf/cephes/tandg.h +0 -139
- scipy/special/xsf/cephes/trig.h +0 -58
- scipy/special/xsf/cephes/unity.h +0 -186
- scipy/special/xsf/cephes/zeta.h +0 -172
- scipy/special/xsf/config.h +0 -304
- scipy/special/xsf/digamma.h +0 -205
- scipy/special/xsf/error.h +0 -57
- scipy/special/xsf/evalpoly.h +0 -47
- scipy/special/xsf/expint.h +0 -266
- scipy/special/xsf/hyp2f1.h +0 -694
- scipy/special/xsf/iv_ratio.h +0 -173
- scipy/special/xsf/lambertw.h +0 -150
- scipy/special/xsf/loggamma.h +0 -163
- scipy/special/xsf/sici.h +0 -200
- scipy/special/xsf/tools.h +0 -427
- scipy/special/xsf/trig.h +0 -164
- scipy/special/xsf/wright_bessel.h +0 -843
- scipy/special/xsf/zlog1.h +0 -35
- scipy/stats/_mvn.cpython-312-aarch64-linux-musl.so +0 -0
- scipy.libs/libgcc_s-7393e603.so.1 +0 -0
- scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
@@ -2,6 +2,7 @@
|
|
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
|
@@ -17,8 +18,8 @@ from scipy._lib._array_api import (
|
|
17
18
|
xp_assert_close,
|
18
19
|
xp_assert_equal,
|
19
20
|
)
|
20
|
-
from scipy._lib._array_api import is_cupy,
|
21
|
-
|
21
|
+
from scipy._lib._array_api import (is_cupy, is_torch, is_dask, is_jax, array_namespace,
|
22
|
+
is_array_api_strict, xp_copy)
|
22
23
|
from scipy.ndimage._filters import _gaussian_kernel1d
|
23
24
|
|
24
25
|
from . import types, float_types, complex_types
|
@@ -26,9 +27,18 @@ from . import types, float_types, complex_types
|
|
26
27
|
|
27
28
|
skip_xp_backends = pytest.mark.skip_xp_backends
|
28
29
|
xfail_xp_backends = pytest.mark.xfail_xp_backends
|
29
|
-
pytestmark = [
|
30
|
-
|
31
|
-
|
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
|
+
|
32
42
|
|
33
43
|
|
34
44
|
def sumsq(a, b, xp=None):
|
@@ -44,9 +54,8 @@ def _complex_correlate(xp, array, kernel, real_dtype, convolve=False,
|
|
44
54
|
"""
|
45
55
|
array = xp.asarray(array)
|
46
56
|
kernel = xp.asarray(kernel)
|
47
|
-
|
48
|
-
|
49
|
-
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')
|
50
59
|
if array.ndim == 1:
|
51
60
|
func = ndimage.convolve1d if convolve else ndimage.correlate1d
|
52
61
|
else:
|
@@ -197,7 +206,7 @@ class TestNdimageFilters:
|
|
197
206
|
assert_array_almost_equal(output, expected)
|
198
207
|
|
199
208
|
@xfail_xp_backends('cupy', reason="Differs by a factor of two?")
|
200
|
-
@
|
209
|
+
@uses_output_array
|
201
210
|
def test_correlate01_overlap(self, xp):
|
202
211
|
array = xp.reshape(xp.arange(256), (16, 16))
|
203
212
|
weights = xp.asarray([2])
|
@@ -348,9 +357,7 @@ class TestNdimageFilters:
|
|
348
357
|
output = ndimage.convolve(array, kernel)
|
349
358
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
350
359
|
|
351
|
-
@
|
352
|
-
reason="output=dtype is numpy-specific",
|
353
|
-
exceptions=['cupy'],)
|
360
|
+
@uses_output_dtype
|
354
361
|
@pytest.mark.parametrize('dtype_array', types)
|
355
362
|
@pytest.mark.parametrize('dtype_kernel', types)
|
356
363
|
def test_correlate13(self, dtype_array, dtype_kernel, xp):
|
@@ -370,9 +377,7 @@ class TestNdimageFilters:
|
|
370
377
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
371
378
|
assert output.dtype.type == dtype_kernel
|
372
379
|
|
373
|
-
@
|
374
|
-
reason="output=dtype is numpy-specific",
|
375
|
-
exceptions=['cupy'],)
|
380
|
+
@uses_output_array
|
376
381
|
@pytest.mark.parametrize('dtype_array', types)
|
377
382
|
@pytest.mark.parametrize('dtype_output', types)
|
378
383
|
def test_correlate14(self, dtype_array, dtype_output, xp):
|
@@ -386,15 +391,13 @@ class TestNdimageFilters:
|
|
386
391
|
output = xp.zeros(array.shape, dtype=dtype_output)
|
387
392
|
ndimage.correlate(array, kernel, output=output)
|
388
393
|
assert_array_almost_equal(xp.asarray([[2, 3, 5], [5, 6, 8]]), output)
|
389
|
-
assert output.dtype
|
394
|
+
assert output.dtype == dtype_output
|
390
395
|
|
391
396
|
ndimage.convolve(array, kernel, output=output)
|
392
397
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
393
|
-
assert output.dtype
|
398
|
+
assert output.dtype == dtype_output
|
394
399
|
|
395
|
-
@
|
396
|
-
reason="output=dtype is numpy-specific",
|
397
|
-
exceptions=['cupy'],)
|
400
|
+
@uses_output_dtype
|
398
401
|
@pytest.mark.parametrize('dtype_array', types)
|
399
402
|
def test_correlate15(self, dtype_array, xp):
|
400
403
|
dtype_array = getattr(xp, dtype_array)
|
@@ -411,9 +414,7 @@ class TestNdimageFilters:
|
|
411
414
|
assert_array_almost_equal(xp.asarray([[6, 8, 9], [9, 11, 12]]), output)
|
412
415
|
assert output.dtype.type == xp.float32
|
413
416
|
|
414
|
-
@
|
415
|
-
reason="output=dtype is numpy-specific",
|
416
|
-
exceptions=['cupy'],)
|
417
|
+
@uses_output_dtype
|
417
418
|
@pytest.mark.parametrize('dtype_array', types)
|
418
419
|
def test_correlate16(self, dtype_array, xp):
|
419
420
|
dtype_array = getattr(xp, dtype_array)
|
@@ -443,9 +444,7 @@ class TestNdimageFilters:
|
|
443
444
|
output = ndimage.convolve1d(array, kernel, origin=-1)
|
444
445
|
assert_array_almost_equal(tcov, output)
|
445
446
|
|
446
|
-
@
|
447
|
-
reason="output=dtype is numpy-specific",
|
448
|
-
exceptions=['cupy'],)
|
447
|
+
@uses_output_dtype
|
449
448
|
@pytest.mark.parametrize('dtype_array', types)
|
450
449
|
def test_correlate18(self, dtype_array, xp):
|
451
450
|
dtype_array = getattr(xp, dtype_array)
|
@@ -474,9 +473,7 @@ class TestNdimageFilters:
|
|
474
473
|
with assert_raises(RuntimeError):
|
475
474
|
ndimage.convolve(array, kernel, mode=['nearest', 'reflect'])
|
476
475
|
|
477
|
-
@
|
478
|
-
reason="output=dtype is numpy-specific",
|
479
|
-
exceptions=['cupy'],)
|
476
|
+
@uses_output_dtype
|
480
477
|
@pytest.mark.parametrize('dtype_array', types)
|
481
478
|
def test_correlate19(self, dtype_array, xp):
|
482
479
|
dtype_array = getattr(xp, dtype_array)
|
@@ -497,9 +494,7 @@ class TestNdimageFilters:
|
|
497
494
|
assert_array_almost_equal(xp.asarray([[3, 5, 6], [6, 8, 9]]), output)
|
498
495
|
assert output.dtype.type == xp.float32
|
499
496
|
|
500
|
-
@
|
501
|
-
reason="output=dtype is numpy-specific",
|
502
|
-
exceptions=['cupy'],)
|
497
|
+
@uses_output_array
|
503
498
|
@pytest.mark.parametrize('dtype_array', types)
|
504
499
|
@pytest.mark.parametrize('dtype_output', types)
|
505
500
|
def test_correlate20(self, dtype_array, dtype_output, xp):
|
@@ -526,9 +521,7 @@ class TestNdimageFilters:
|
|
526
521
|
output = ndimage.convolve1d(array, weights, axis=0)
|
527
522
|
assert_array_almost_equal(output, expected)
|
528
523
|
|
529
|
-
@
|
530
|
-
reason="output=dtype is numpy-specific",
|
531
|
-
exceptions=['cupy'],)
|
524
|
+
@uses_output_array
|
532
525
|
@pytest.mark.parametrize('dtype_array', types)
|
533
526
|
@pytest.mark.parametrize('dtype_output', types)
|
534
527
|
def test_correlate22(self, dtype_array, dtype_output, xp):
|
@@ -547,7 +540,7 @@ class TestNdimageFilters:
|
|
547
540
|
mode='wrap', output=output)
|
548
541
|
assert_array_almost_equal(output, expected)
|
549
542
|
|
550
|
-
@
|
543
|
+
@uses_output_array
|
551
544
|
@pytest.mark.parametrize('dtype_array', types)
|
552
545
|
@pytest.mark.parametrize('dtype_output', types)
|
553
546
|
def test_correlate23(self, dtype_array, dtype_output, xp):
|
@@ -566,7 +559,7 @@ class TestNdimageFilters:
|
|
566
559
|
mode='nearest', output=output)
|
567
560
|
assert_array_almost_equal(output, expected)
|
568
561
|
|
569
|
-
@
|
562
|
+
@uses_output_array
|
570
563
|
@pytest.mark.parametrize('dtype_array', types)
|
571
564
|
@pytest.mark.parametrize('dtype_output', types)
|
572
565
|
def test_correlate24(self, dtype_array, dtype_output, xp):
|
@@ -586,7 +579,7 @@ class TestNdimageFilters:
|
|
586
579
|
mode='nearest', output=output, origin=-1)
|
587
580
|
assert_array_almost_equal(output, tcov)
|
588
581
|
|
589
|
-
@
|
582
|
+
@uses_output_array
|
590
583
|
@pytest.mark.parametrize('dtype_array', types)
|
591
584
|
@pytest.mark.parametrize('dtype_output', types)
|
592
585
|
def test_correlate25(self, dtype_array, dtype_output, xp):
|
@@ -614,9 +607,7 @@ class TestNdimageFilters:
|
|
614
607
|
y = ndimage.correlate1d(xp.ones(1), xp.ones(5), mode='mirror')
|
615
608
|
xp_assert_equal(y, xp.asarray([5.]))
|
616
609
|
|
617
|
-
@
|
618
|
-
reason="output=dtype is numpy-specific",
|
619
|
-
exceptions=['cupy'],)
|
610
|
+
@uses_output_dtype
|
620
611
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
621
612
|
@pytest.mark.parametrize('dtype_input', types)
|
622
613
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -633,9 +624,7 @@ class TestNdimageFilters:
|
|
633
624
|
self._validate_complex(xp, array, kernel, dtype_output,
|
634
625
|
check_warnings=num_parallel_threads == 1)
|
635
626
|
|
636
|
-
@
|
637
|
-
reason="output=dtype is numpy-specific",
|
638
|
-
exceptions=['cupy'],)
|
627
|
+
@uses_output_dtype
|
639
628
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
640
629
|
@pytest.mark.parametrize('dtype_input', types)
|
641
630
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -648,7 +637,7 @@ class TestNdimageFilters:
|
|
648
637
|
dtype_output = getattr(xp, dtype_output)
|
649
638
|
|
650
639
|
if is_cupy(xp) and mode == 'grid-constant':
|
651
|
-
pytest.xfail('
|
640
|
+
pytest.xfail('cupy/cupy#8404')
|
652
641
|
|
653
642
|
# test use of non-zero cval with complex inputs
|
654
643
|
# also verifies that mode 'grid-constant' does not segfault
|
@@ -680,7 +669,7 @@ class TestNdimageFilters:
|
|
680
669
|
func(array, kernel, mode='constant', cval=5.0 + 1.0j,
|
681
670
|
output=xp.complex64)
|
682
671
|
|
683
|
-
@
|
672
|
+
@uses_output_dtype
|
684
673
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
685
674
|
@pytest.mark.parametrize('dtype_input', types)
|
686
675
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -695,7 +684,7 @@ class TestNdimageFilters:
|
|
695
684
|
self._validate_complex(xp, array, kernel, dtype_output,
|
696
685
|
check_warnings=num_parallel_threads == 1)
|
697
686
|
|
698
|
-
@
|
687
|
+
@uses_output_dtype
|
699
688
|
@pytest.mark.parametrize('dtype_kernel', complex_types)
|
700
689
|
@pytest.mark.parametrize('dtype_input', types)
|
701
690
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -712,7 +701,7 @@ class TestNdimageFilters:
|
|
712
701
|
cval=5.0,
|
713
702
|
check_warnings=num_parallel_threads == 1)
|
714
703
|
|
715
|
-
@
|
704
|
+
@uses_output_dtype
|
716
705
|
@pytest.mark.parametrize('dtype_kernel', types)
|
717
706
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
718
707
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -729,7 +718,7 @@ class TestNdimageFilters:
|
|
729
718
|
self._validate_complex(xp, array, kernel, dtype_output,
|
730
719
|
check_warnings=num_parallel_threads == 1)
|
731
720
|
|
732
|
-
@
|
721
|
+
@uses_output_dtype
|
733
722
|
@pytest.mark.parametrize('dtype_kernel', types)
|
734
723
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
735
724
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -744,10 +733,8 @@ class TestNdimageFilters:
|
|
744
733
|
self._validate_complex(xp, array, kernel, dtype_output,
|
745
734
|
check_warnings=num_parallel_threads == 1)
|
746
735
|
|
747
|
-
@
|
748
|
-
@
|
749
|
-
reason='output=dtype is numpy-specific',
|
750
|
-
exceptions=['cupy'])
|
736
|
+
@uses_output_dtype
|
737
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
751
738
|
@pytest.mark.parametrize('dtype_kernel', types)
|
752
739
|
@pytest.mark.parametrize('dtype_input', complex_types)
|
753
740
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
@@ -764,7 +751,8 @@ class TestNdimageFilters:
|
|
764
751
|
cval=5 - 3j,
|
765
752
|
check_warnings=num_parallel_threads == 1)
|
766
753
|
|
767
|
-
@
|
754
|
+
@uses_output_dtype
|
755
|
+
@xfail_xp_backends("cupy", reason="unhashable type: 'ndarray'")
|
768
756
|
@pytest.mark.parametrize('dtype', complex_types)
|
769
757
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
770
758
|
def test_correlate_complex_input_and_kernel(self, dtype, dtype_output, xp,
|
@@ -779,10 +767,8 @@ class TestNdimageFilters:
|
|
779
767
|
self._validate_complex(xp, array, kernel, dtype_output,
|
780
768
|
check_warnings=num_parallel_threads == 1)
|
781
769
|
|
782
|
-
@
|
783
|
-
@
|
784
|
-
reason="output=dtype is numpy-specific",
|
785
|
-
exceptions=['cupy'],)
|
770
|
+
@uses_output_dtype
|
771
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
786
772
|
@pytest.mark.parametrize('dtype', complex_types)
|
787
773
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
788
774
|
def test_correlate_complex_input_and_kernel_cval(self, dtype,
|
@@ -799,7 +785,8 @@ class TestNdimageFilters:
|
|
799
785
|
cval=5.0 + 2.0j,
|
800
786
|
check_warnings=num_parallel_threads == 1)
|
801
787
|
|
802
|
-
@
|
788
|
+
@uses_output_dtype
|
789
|
+
@xfail_xp_backends("cupy", reason="unhashable type: 'ndarray'")
|
803
790
|
@pytest.mark.parametrize('dtype', complex_types)
|
804
791
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
805
792
|
@pytest.mark.thread_unsafe
|
@@ -813,20 +800,17 @@ class TestNdimageFilters:
|
|
813
800
|
self._validate_complex(xp, array, kernel, dtype_output,
|
814
801
|
check_warnings=num_parallel_threads == 1)
|
815
802
|
|
803
|
+
@uses_output_dtype
|
804
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8405")
|
816
805
|
@pytest.mark.parametrize('dtype', complex_types)
|
817
806
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
818
807
|
def test_correlate1d_complex_input_and_kernel_cval(self, dtype,
|
819
808
|
dtype_output, xp,
|
820
809
|
num_parallel_threads):
|
821
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
822
|
-
pytest.xfail("output=dtype is numpy-specific")
|
823
810
|
|
824
811
|
dtype = getattr(xp, dtype)
|
825
812
|
dtype_output = getattr(xp, dtype_output)
|
826
813
|
|
827
|
-
if is_cupy(xp):
|
828
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8405")
|
829
|
-
|
830
814
|
kernel = xp.asarray([1, 1 + 1j], dtype=dtype)
|
831
815
|
array = xp.asarray([1, 2j, 3, 1 + 4j, 5, 6j], dtype=dtype)
|
832
816
|
self._validate_complex(xp, array, kernel, dtype_output, mode='constant',
|
@@ -846,10 +830,8 @@ class TestNdimageFilters:
|
|
846
830
|
assert input.dtype == output.dtype
|
847
831
|
assert input.shape == output.shape
|
848
832
|
|
833
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8403")
|
849
834
|
def test_gauss03(self, xp):
|
850
|
-
if is_cupy(xp):
|
851
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8403")
|
852
|
-
|
853
835
|
# single precision data
|
854
836
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
855
837
|
input = xp.reshape(input, (100, 100))
|
@@ -865,10 +847,8 @@ class TestNdimageFilters:
|
|
865
847
|
assert_almost_equal(o_sum, i_sum, decimal=0)
|
866
848
|
assert sumsq(input, output) > 1.0
|
867
849
|
|
850
|
+
@uses_output_dtype
|
868
851
|
def test_gauss04(self, xp):
|
869
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
870
|
-
pytest.xfail("output=dtype is numpy-specific")
|
871
|
-
|
872
852
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
873
853
|
input = xp.reshape(input, (100, 100))
|
874
854
|
otype = xp.float64
|
@@ -877,10 +857,8 @@ class TestNdimageFilters:
|
|
877
857
|
assert input.shape == output.shape
|
878
858
|
assert sumsq(input, output) > 1.0
|
879
859
|
|
860
|
+
@uses_output_dtype
|
880
861
|
def test_gauss05(self, xp):
|
881
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
882
|
-
pytest.xfail("output=dtype is numpy-specific")
|
883
|
-
|
884
862
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
885
863
|
input = xp.reshape(input, (100, 100))
|
886
864
|
otype = xp.float64
|
@@ -890,10 +868,8 @@ class TestNdimageFilters:
|
|
890
868
|
assert input.shape == output.shape
|
891
869
|
assert sumsq(input, output) > 1.0
|
892
870
|
|
871
|
+
@uses_output_dtype
|
893
872
|
def test_gauss06(self, xp):
|
894
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
895
|
-
pytest.xfail("output=dtype is numpy-specific")
|
896
|
-
|
897
873
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
898
874
|
input = xp.reshape(input, (100, 100))
|
899
875
|
otype = xp.float64
|
@@ -901,7 +877,7 @@ class TestNdimageFilters:
|
|
901
877
|
output2 = ndimage.gaussian_filter(input, 1.0, output=otype)
|
902
878
|
assert_array_almost_equal(output1, output2)
|
903
879
|
|
904
|
-
@
|
880
|
+
@uses_output_array
|
905
881
|
def test_gauss_memory_overlap(self, xp):
|
906
882
|
input = xp.arange(100 * 100, dtype=xp.float32)
|
907
883
|
input = xp.reshape(input, (100, 100))
|
@@ -909,6 +885,7 @@ class TestNdimageFilters:
|
|
909
885
|
ndimage.gaussian_filter(input, 1.0, output=input)
|
910
886
|
assert_array_almost_equal(output1, input)
|
911
887
|
|
888
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
912
889
|
@pytest.mark.parametrize(('filter_func', 'extra_args', 'size0', 'size'),
|
913
890
|
[(ndimage.gaussian_filter, (), 0, 1.0),
|
914
891
|
(ndimage.uniform_filter, (), 1, 3),
|
@@ -923,9 +900,6 @@ class TestNdimageFilters:
|
|
923
900
|
+ tuple(itertools.combinations(range(-3, 3), 2))
|
924
901
|
+ ((0, 1, 2),))
|
925
902
|
def test_filter_axes(self, filter_func, extra_args, size0, size, axes, xp):
|
926
|
-
if is_cupy(xp):
|
927
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
928
|
-
|
929
903
|
# Note: `size` is called `sigma` in `gaussian_filter`
|
930
904
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
931
905
|
array = xp.reshape(array, (6, 8, 12))
|
@@ -945,8 +919,7 @@ class TestNdimageFilters:
|
|
945
919
|
xp_assert_close(output, expected)
|
946
920
|
|
947
921
|
@skip_xp_backends("cupy",
|
948
|
-
reason="these filters do not yet have axes support"
|
949
|
-
)
|
922
|
+
reason="these filters do not yet have axes support")
|
950
923
|
@pytest.mark.parametrize(('filter_func', 'kwargs'),
|
951
924
|
[(ndimage.laplace, {}),
|
952
925
|
(ndimage.gaussian_gradient_magnitude,
|
@@ -987,8 +960,7 @@ class TestNdimageFilters:
|
|
987
960
|
xp_assert_close(output, expected)
|
988
961
|
|
989
962
|
@skip_xp_backends("cupy",
|
990
|
-
reason="generic_filter does not yet have axes support"
|
991
|
-
)
|
963
|
+
reason="generic_filter does not yet have axes support")
|
992
964
|
@pytest.mark.parametrize(
|
993
965
|
'axes',
|
994
966
|
tuple(itertools.combinations(range(-3, 3), 1))
|
@@ -1010,8 +982,7 @@ class TestNdimageFilters:
|
|
1010
982
|
xp_assert_close(output, expected)
|
1011
983
|
|
1012
984
|
@skip_xp_backends("cupy",
|
1013
|
-
reason="https://github.com/cupy/cupy/pull/8339"
|
1014
|
-
)
|
985
|
+
reason="https://github.com/cupy/cupy/pull/8339")
|
1015
986
|
@pytest.mark.parametrize('func', [ndimage.correlate, ndimage.convolve])
|
1016
987
|
@pytest.mark.parametrize(
|
1017
988
|
'dtype', [np.float32, np.float64, np.complex64, np.complex128]
|
@@ -1051,9 +1022,7 @@ class TestNdimageFilters:
|
|
1051
1022
|
mode=['reflect', 'nearest', 'constant'])
|
1052
1023
|
kwargs_rank = dict(origin=(-1, 0, 1))
|
1053
1024
|
|
1054
|
-
@
|
1055
|
-
reason="fancy indexing is only available in 2024 version",
|
1056
|
-
)
|
1025
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1057
1026
|
@pytest.mark.parametrize("filter_func, size0, size, kwargs",
|
1058
1027
|
[(ndimage.gaussian_filter, 0, 1.0, kwargs_gauss),
|
1059
1028
|
(ndimage.uniform_filter, 1, 3, kwargs_other),
|
@@ -1064,10 +1033,6 @@ class TestNdimageFilters:
|
|
1064
1033
|
(ndimage.percentile_filter, 1, 3, kwargs_rank)])
|
1065
1034
|
@pytest.mark.parametrize('axes', itertools.combinations(range(-3, 3), 2))
|
1066
1035
|
def test_filter_axes_kwargs(self, filter_func, size0, size, kwargs, axes, xp):
|
1067
|
-
|
1068
|
-
if is_cupy(xp):
|
1069
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1070
|
-
|
1071
1036
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1072
1037
|
array = xp.reshape(array, (6, 8, 12))
|
1073
1038
|
|
@@ -1108,6 +1073,7 @@ class TestNdimageFilters:
|
|
1108
1073
|
xp_assert_close(output, expected)
|
1109
1074
|
|
1110
1075
|
|
1076
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1111
1077
|
@pytest.mark.parametrize("filter_func, kwargs",
|
1112
1078
|
[(ndimage.convolve, {}),
|
1113
1079
|
(ndimage.correlate, {}),
|
@@ -1117,9 +1083,6 @@ class TestNdimageFilters:
|
|
1117
1083
|
(ndimage.rank_filter, {"rank": 1}),
|
1118
1084
|
(ndimage.percentile_filter, {"percentile": 30})])
|
1119
1085
|
def test_filter_weights_subset_axes_origins(self, filter_func, kwargs, xp):
|
1120
|
-
if is_cupy(xp):
|
1121
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1122
|
-
|
1123
1086
|
axes = (-2, -1)
|
1124
1087
|
origins = (0, 1)
|
1125
1088
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
@@ -1152,6 +1115,7 @@ class TestNdimageFilters:
|
|
1152
1115
|
output[:, :, origins[1]:], output0[:, :, :-origins[1]])
|
1153
1116
|
|
1154
1117
|
|
1118
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1155
1119
|
@pytest.mark.parametrize(
|
1156
1120
|
'filter_func, args',
|
1157
1121
|
[(ndimage.convolve, (np.ones((3, 3, 3)),)), # args = (weights,)
|
@@ -1167,9 +1131,6 @@ class TestNdimageFilters:
|
|
1167
1131
|
'axes', [(1.5,), (0, 1, 2, 3), (3,), (-4,)]
|
1168
1132
|
)
|
1169
1133
|
def test_filter_invalid_axes(self, filter_func, args, axes, xp):
|
1170
|
-
if is_cupy(xp):
|
1171
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1172
|
-
|
1173
1134
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1174
1135
|
array = xp.reshape(array, (6, 8, 12))
|
1175
1136
|
args = [
|
@@ -1185,6 +1146,7 @@ class TestNdimageFilters:
|
|
1185
1146
|
with pytest.raises(error_class, match=match):
|
1186
1147
|
filter_func(array, *args, axes=axes)
|
1187
1148
|
|
1149
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1188
1150
|
@pytest.mark.parametrize(
|
1189
1151
|
'filter_func, kwargs',
|
1190
1152
|
[(ndimage.convolve, {}),
|
@@ -1200,9 +1162,6 @@ class TestNdimageFilters:
|
|
1200
1162
|
@pytest.mark.parametrize('separable_footprint', [False, True])
|
1201
1163
|
def test_filter_invalid_footprint_ndim(self, filter_func, kwargs, axes,
|
1202
1164
|
separable_footprint, xp):
|
1203
|
-
if is_cupy(xp):
|
1204
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1205
|
-
|
1206
1165
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1207
1166
|
array = xp.reshape(array, (6, 8, 12))
|
1208
1167
|
# create a footprint with one too many dimensions
|
@@ -1226,14 +1185,12 @@ class TestNdimageFilters:
|
|
1226
1185
|
with pytest.raises(RuntimeError, match=match):
|
1227
1186
|
filter_func(array, axes=axes, **kwargs)
|
1228
1187
|
|
1188
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1229
1189
|
@pytest.mark.parametrize('n_mismatch', [1, 3])
|
1230
1190
|
@pytest.mark.parametrize('filter_func, kwargs, key, val',
|
1231
1191
|
_cases_axes_tuple_length_mismatch())
|
1232
1192
|
def test_filter_tuple_length_mismatch(self, n_mismatch, filter_func,
|
1233
1193
|
kwargs, key, val, xp):
|
1234
|
-
if is_cupy(xp):
|
1235
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1236
|
-
|
1237
1194
|
# Test for the intended RuntimeError when a kwargs has an invalid size
|
1238
1195
|
array = xp.arange(6 * 8 * 12, dtype=xp.float64)
|
1239
1196
|
array = xp.reshape(array, (6, 8, 12))
|
@@ -1248,9 +1205,6 @@ class TestNdimageFilters:
|
|
1248
1205
|
|
1249
1206
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1250
1207
|
def test_prewitt01(self, dtype, xp):
|
1251
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1252
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1253
|
-
|
1254
1208
|
dtype = getattr(xp, dtype)
|
1255
1209
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1256
1210
|
[5, 8, 3, 7, 1],
|
@@ -1260,12 +1214,9 @@ class TestNdimageFilters:
|
|
1260
1214
|
output = ndimage.prewitt(array, 0)
|
1261
1215
|
assert_array_almost_equal(t, output)
|
1262
1216
|
|
1263
|
-
@
|
1217
|
+
@uses_output_array
|
1264
1218
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1265
1219
|
def test_prewitt02(self, dtype, xp):
|
1266
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1267
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1268
|
-
|
1269
1220
|
dtype = getattr(xp, dtype)
|
1270
1221
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1271
1222
|
[5, 8, 3, 7, 1],
|
@@ -1278,14 +1229,9 @@ class TestNdimageFilters:
|
|
1278
1229
|
|
1279
1230
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1280
1231
|
def test_prewitt03(self, dtype, xp):
|
1281
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1282
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1283
|
-
|
1284
1232
|
dtype = getattr(xp, dtype)
|
1285
1233
|
if is_cupy(xp) and dtype in [xp.uint32, xp.uint64]:
|
1286
1234
|
pytest.xfail("uint UB? XXX")
|
1287
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1288
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1289
1235
|
|
1290
1236
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1291
1237
|
[5, 8, 3, 7, 1],
|
@@ -1297,9 +1243,6 @@ class TestNdimageFilters:
|
|
1297
1243
|
|
1298
1244
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1299
1245
|
def test_prewitt04(self, dtype, xp):
|
1300
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1301
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1302
|
-
|
1303
1246
|
dtype = getattr(xp, dtype)
|
1304
1247
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1305
1248
|
[5, 8, 3, 7, 1],
|
@@ -1310,9 +1253,6 @@ class TestNdimageFilters:
|
|
1310
1253
|
|
1311
1254
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1312
1255
|
def test_sobel01(self, dtype, xp):
|
1313
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1314
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1315
|
-
|
1316
1256
|
dtype = getattr(xp, dtype)
|
1317
1257
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1318
1258
|
[5, 8, 3, 7, 1],
|
@@ -1322,12 +1262,9 @@ class TestNdimageFilters:
|
|
1322
1262
|
output = ndimage.sobel(array, 0)
|
1323
1263
|
assert_array_almost_equal(t, output)
|
1324
1264
|
|
1325
|
-
@
|
1265
|
+
@uses_output_array
|
1326
1266
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1327
1267
|
def test_sobel02(self, dtype, xp):
|
1328
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1329
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1330
|
-
|
1331
1268
|
dtype = getattr(xp, dtype)
|
1332
1269
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1333
1270
|
[5, 8, 3, 7, 1],
|
@@ -1342,8 +1279,6 @@ class TestNdimageFilters:
|
|
1342
1279
|
def test_sobel03(self, dtype, xp):
|
1343
1280
|
if is_cupy(xp) and dtype in ["uint32", "uint64"]:
|
1344
1281
|
pytest.xfail("uint UB? XXX")
|
1345
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1346
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1347
1282
|
|
1348
1283
|
dtype = getattr(xp, dtype)
|
1349
1284
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
@@ -1357,9 +1292,6 @@ class TestNdimageFilters:
|
|
1357
1292
|
|
1358
1293
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1359
1294
|
def test_sobel04(self, dtype, xp):
|
1360
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1361
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1362
|
-
|
1363
1295
|
dtype = getattr(xp, dtype)
|
1364
1296
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1365
1297
|
[5, 8, 3, 7, 1],
|
@@ -1382,7 +1314,7 @@ class TestNdimageFilters:
|
|
1382
1314
|
output = ndimage.laplace(array)
|
1383
1315
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1384
1316
|
|
1385
|
-
@
|
1317
|
+
@uses_output_array
|
1386
1318
|
@pytest.mark.parametrize('dtype',
|
1387
1319
|
["int32", "float32", "float64",
|
1388
1320
|
"complex64", "complex128"])
|
@@ -1412,7 +1344,7 @@ class TestNdimageFilters:
|
|
1412
1344
|
output = ndimage.gaussian_laplace(array, 1.0)
|
1413
1345
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1414
1346
|
|
1415
|
-
@
|
1347
|
+
@uses_output_array
|
1416
1348
|
@pytest.mark.parametrize('dtype',
|
1417
1349
|
["int32", "float32", "float64",
|
1418
1350
|
"complex64", "complex128"])
|
@@ -1428,12 +1360,9 @@ class TestNdimageFilters:
|
|
1428
1360
|
ndimage.gaussian_laplace(array, 1.0, output)
|
1429
1361
|
assert_array_almost_equal(tmp1 + tmp2, output)
|
1430
1362
|
|
1431
|
-
@
|
1363
|
+
@uses_output_array
|
1432
1364
|
@pytest.mark.parametrize('dtype', types + complex_types)
|
1433
1365
|
def test_generic_laplace01(self, dtype, xp):
|
1434
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1435
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1436
|
-
|
1437
1366
|
def derivative2(input, axis, output, mode, cval, a, b):
|
1438
1367
|
sigma = np.asarray([a, b / 2.0])
|
1439
1368
|
order = [0] * input.ndim
|
@@ -1453,7 +1382,6 @@ class TestNdimageFilters:
|
|
1453
1382
|
ndimage.gaussian_laplace(array, 1.0, output)
|
1454
1383
|
assert_array_almost_equal(tmp, output)
|
1455
1384
|
|
1456
|
-
@skip_xp_backends("jax.numpy", reason="output array is read-only")
|
1457
1385
|
@pytest.mark.parametrize('dtype',
|
1458
1386
|
["int32", "float32", "float64",
|
1459
1387
|
"complex64", "complex128"])
|
@@ -1469,12 +1397,11 @@ class TestNdimageFilters:
|
|
1469
1397
|
output = ndimage.gaussian_gradient_magnitude(array, 1.0)
|
1470
1398
|
expected = tmp1 * tmp1 + tmp2 * tmp2
|
1471
1399
|
|
1472
|
-
|
1473
|
-
|
1474
|
-
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)
|
1475
1402
|
xp_assert_close(output, expected, rtol=1e-6, atol=1e-6)
|
1476
1403
|
|
1477
|
-
@
|
1404
|
+
@uses_output_array
|
1478
1405
|
@pytest.mark.parametrize('dtype',
|
1479
1406
|
["int32", "float32", "float64",
|
1480
1407
|
"complex64", "complex128"])
|
@@ -1491,10 +1418,9 @@ class TestNdimageFilters:
|
|
1491
1418
|
ndimage.gaussian_gradient_magnitude(array, 1.0, output)
|
1492
1419
|
expected = tmp1 * tmp1 + tmp2 * tmp2
|
1493
1420
|
|
1494
|
-
|
1495
|
-
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
|
1496
1422
|
|
1497
|
-
expected = astype(xp.sqrt(fl_expected), dtype)
|
1423
|
+
expected = xp.astype(xp.sqrt(fl_expected), dtype)
|
1498
1424
|
xp_assert_close(output, expected, rtol=1e-6, atol=1e-6)
|
1499
1425
|
|
1500
1426
|
def test_generic_gradient_magnitude01(self, xp):
|
@@ -1514,18 +1440,12 @@ class TestNdimageFilters:
|
|
1514
1440
|
extra_keywords={'b': 2.0})
|
1515
1441
|
assert_array_almost_equal(tmp1, tmp2)
|
1516
1442
|
|
1517
|
-
@skip_xp_backends("cupy",
|
1518
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1519
|
-
)
|
1520
1443
|
def test_uniform01(self, xp):
|
1521
1444
|
array = xp.asarray([2, 4, 6])
|
1522
1445
|
size = 2
|
1523
1446
|
output = ndimage.uniform_filter1d(array, size, origin=-1)
|
1524
1447
|
assert_array_almost_equal(xp.asarray([3, 5, 6]), output)
|
1525
1448
|
|
1526
|
-
@skip_xp_backends("cupy",
|
1527
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1528
|
-
)
|
1529
1449
|
def test_uniform01_complex(self, xp):
|
1530
1450
|
array = xp.asarray([2 + 1j, 4 + 2j, 6 + 3j], dtype=xp.complex128)
|
1531
1451
|
size = 2
|
@@ -1545,9 +1465,6 @@ class TestNdimageFilters:
|
|
1545
1465
|
output = ndimage.uniform_filter(array, filter_shape)
|
1546
1466
|
assert_array_almost_equal(array, output)
|
1547
1467
|
|
1548
|
-
@skip_xp_backends("cupy",
|
1549
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1550
|
-
)
|
1551
1468
|
def test_uniform04(self, xp):
|
1552
1469
|
array = xp.asarray([2, 4, 6])
|
1553
1470
|
filter_shape = [2]
|
@@ -1560,15 +1477,10 @@ class TestNdimageFilters:
|
|
1560
1477
|
output = ndimage.uniform_filter(array, filter_shape)
|
1561
1478
|
assert_array_almost_equal(xp.asarray([]), output)
|
1562
1479
|
|
1563
|
-
@
|
1564
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1565
|
-
)
|
1480
|
+
@uses_output_dtype
|
1566
1481
|
@pytest.mark.parametrize('dtype_array', types)
|
1567
1482
|
@pytest.mark.parametrize('dtype_output', types)
|
1568
1483
|
def test_uniform06(self, dtype_array, dtype_output, xp):
|
1569
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
1570
|
-
pytest.xfail("output=dtype is numpy-specific")
|
1571
|
-
|
1572
1484
|
dtype_array = getattr(xp, dtype_array)
|
1573
1485
|
dtype_output = getattr(xp, dtype_output)
|
1574
1486
|
|
@@ -1580,15 +1492,10 @@ class TestNdimageFilters:
|
|
1580
1492
|
assert_array_almost_equal(xp.asarray([[4, 6, 10], [10, 12, 16]]), output)
|
1581
1493
|
assert output.dtype.type == dtype_output
|
1582
1494
|
|
1583
|
-
@
|
1584
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
1585
|
-
)
|
1495
|
+
@uses_output_dtype
|
1586
1496
|
@pytest.mark.parametrize('dtype_array', complex_types)
|
1587
1497
|
@pytest.mark.parametrize('dtype_output', complex_types)
|
1588
1498
|
def test_uniform06_complex(self, dtype_array, dtype_output, xp):
|
1589
|
-
if not (is_numpy(xp) or is_cupy(xp)):
|
1590
|
-
pytest.xfail("output=dtype is numpy-specific")
|
1591
|
-
|
1592
1499
|
dtype_array = getattr(xp, dtype_array)
|
1593
1500
|
dtype_output = getattr(xp, dtype_output)
|
1594
1501
|
|
@@ -1634,7 +1541,7 @@ class TestNdimageFilters:
|
|
1634
1541
|
[2, 2, 1, 1, 1],
|
1635
1542
|
[5, 3, 3, 1, 1]]), output)
|
1636
1543
|
|
1637
|
-
@
|
1544
|
+
@uses_output_array
|
1638
1545
|
def test_minimum_filter05_overlap(self, xp):
|
1639
1546
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1640
1547
|
[7, 6, 9, 3, 5],
|
@@ -1776,6 +1683,7 @@ class TestNdimageFilters:
|
|
1776
1683
|
[7, 9, 8, 9, 7],
|
1777
1684
|
[8, 8, 8, 7, 7]]), output)
|
1778
1685
|
|
1686
|
+
@xfail_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8339")
|
1779
1687
|
@pytest.mark.parametrize(
|
1780
1688
|
'axes', tuple(itertools.combinations(range(-3, 3), 2))
|
1781
1689
|
)
|
@@ -1788,9 +1696,6 @@ class TestNdimageFilters:
|
|
1788
1696
|
(ndimage.percentile_filter, dict(percentile=60))]
|
1789
1697
|
)
|
1790
1698
|
def test_minmax_nonseparable_axes(self, filter_func, axes, kwargs, xp):
|
1791
|
-
if is_cupy(xp):
|
1792
|
-
pytest.xfail("https://github.com/cupy/cupy/pull/8339")
|
1793
|
-
|
1794
1699
|
array = xp.arange(6 * 8 * 12, dtype=xp.float32)
|
1795
1700
|
array = xp.reshape(array, (6, 8, 12))
|
1796
1701
|
# use 2D triangular footprint because it is non-separable
|
@@ -1806,8 +1711,7 @@ class TestNdimageFilters:
|
|
1806
1711
|
|
1807
1712
|
missing_axis = tuple(set(range(3)) - set(axes % array.ndim))[0]
|
1808
1713
|
|
1809
|
-
|
1810
|
-
footprint_3d = expand_dims(footprint, axis=missing_axis)
|
1714
|
+
footprint_3d = xp.expand_dims(footprint, axis=missing_axis)
|
1811
1715
|
expected = filter_func(array, footprint=footprint_3d, **kwargs)
|
1812
1716
|
xp_assert_close(output, expected)
|
1813
1717
|
|
@@ -1865,18 +1769,14 @@ class TestNdimageFilters:
|
|
1865
1769
|
output = ndimage.percentile_filter(array, 17, size=(2, 3))
|
1866
1770
|
xp_assert_equal(expected, output)
|
1867
1771
|
|
1868
|
-
@
|
1869
|
-
|
1870
|
-
)
|
1772
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8406")
|
1773
|
+
@uses_output_array
|
1871
1774
|
def test_rank06_overlap(self, xp):
|
1872
|
-
if is_cupy(xp):
|
1873
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8406")
|
1874
1775
|
array = xp.asarray([[3, 2, 5, 1, 4],
|
1875
1776
|
[5, 8, 3, 7, 1],
|
1876
1777
|
[5, 6, 9, 3, 5]])
|
1877
1778
|
|
1878
|
-
|
1879
|
-
array_copy = asarray(array, copy=True)
|
1779
|
+
array_copy = xp.asarray(array, copy=True)
|
1880
1780
|
expected = [[2, 2, 1, 1, 1],
|
1881
1781
|
[3, 3, 2, 1, 1],
|
1882
1782
|
[5, 5, 3, 3, 1]]
|
@@ -1969,9 +1869,6 @@ class TestNdimageFilters:
|
|
1969
1869
|
|
1970
1870
|
@pytest.mark.parametrize('dtype', types)
|
1971
1871
|
def test_rank12(self, dtype, xp):
|
1972
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1973
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1974
|
-
|
1975
1872
|
dtype = getattr(xp, dtype)
|
1976
1873
|
expected = [[3, 3, 2, 4, 4],
|
1977
1874
|
[3, 5, 2, 5, 1],
|
@@ -1991,9 +1888,6 @@ class TestNdimageFilters:
|
|
1991
1888
|
|
1992
1889
|
@pytest.mark.parametrize('dtype', types)
|
1993
1890
|
def test_rank13(self, dtype, xp):
|
1994
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
1995
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
1996
|
-
|
1997
1891
|
dtype = getattr(xp, dtype)
|
1998
1892
|
expected = [[5, 2, 5, 1, 1],
|
1999
1893
|
[5, 8, 3, 5, 5],
|
@@ -2009,9 +1903,6 @@ class TestNdimageFilters:
|
|
2009
1903
|
|
2010
1904
|
@pytest.mark.parametrize('dtype', types)
|
2011
1905
|
def test_rank14(self, dtype, xp):
|
2012
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2013
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2014
|
-
|
2015
1906
|
dtype = getattr(xp, dtype)
|
2016
1907
|
expected = [[3, 5, 2, 5, 1],
|
2017
1908
|
[5, 5, 8, 3, 5],
|
@@ -2027,9 +1918,6 @@ class TestNdimageFilters:
|
|
2027
1918
|
|
2028
1919
|
@pytest.mark.parametrize('dtype', types)
|
2029
1920
|
def test_rank15(self, dtype, xp):
|
2030
|
-
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2031
|
-
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2032
|
-
|
2033
1921
|
dtype = getattr(xp, dtype)
|
2034
1922
|
expected = [[2, 3, 1, 4, 1],
|
2035
1923
|
[5, 3, 7, 1, 1],
|
@@ -2043,7 +1931,8 @@ class TestNdimageFilters:
|
|
2043
1931
|
origin=[-1, 0])
|
2044
1932
|
xp_assert_equal(expected, output)
|
2045
1933
|
|
2046
|
-
|
1934
|
+
# NumPy-only because test is for list input
|
1935
|
+
def test_rank16(self):
|
2047
1936
|
# test that lists are accepted and interpreted as numpy arrays
|
2048
1937
|
array = [3, 2, 5, 1, 4]
|
2049
1938
|
# expected values are: median(3, 2, 5) = 3, median(2, 5, 1) = 2, etc
|
@@ -2080,20 +1969,20 @@ class TestNdimageFilters:
|
|
2080
1969
|
y = ndimage.rank_filter(x, -2, size=3)
|
2081
1970
|
assert y.dtype == x.dtype
|
2082
1971
|
|
2083
|
-
@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")
|
2084
1975
|
@pytest.mark.parametrize('dtype', types)
|
2085
1976
|
def test_generic_filter1d01(self, dtype, xp):
|
2086
1977
|
weights = xp.asarray([1.1, 2.2, 3.3])
|
2087
1978
|
|
2088
|
-
if is_cupy(xp):
|
2089
|
-
pytest.xfail("CuPy does not support extra_arguments")
|
2090
|
-
|
2091
1979
|
def _filter_func(input, output, fltr, total):
|
2092
1980
|
fltr = fltr / total
|
2093
1981
|
for ii in range(input.shape[0] - 2):
|
2094
1982
|
output[ii] = input[ii] * fltr[0]
|
2095
1983
|
output[ii] += input[ii + 1] * fltr[1]
|
2096
1984
|
output[ii] += input[ii + 2] * fltr[2]
|
1985
|
+
|
2097
1986
|
a = np.arange(12, dtype=dtype).reshape(3, 4)
|
2098
1987
|
a = xp.asarray(a)
|
2099
1988
|
dtype = getattr(xp, dtype)
|
@@ -2105,10 +1994,9 @@ class TestNdimageFilters:
|
|
2105
1994
|
extra_keywords={'total': xp.sum(weights)})
|
2106
1995
|
assert_array_almost_equal(r1, r2)
|
2107
1996
|
|
1997
|
+
@xfail_xp_backends("cupy", reason="does not support extra_arguments")
|
2108
1998
|
@pytest.mark.parametrize('dtype', types)
|
2109
1999
|
def test_generic_filter01(self, dtype, xp):
|
2110
|
-
if is_cupy(xp):
|
2111
|
-
pytest.xfail("CuPy does not support extra_arguments")
|
2112
2000
|
if is_torch(xp) and dtype in ("uint16", "uint32", "uint64"):
|
2113
2001
|
pytest.xfail("https://github.com/pytorch/pytorch/issues/58734")
|
2114
2002
|
|
@@ -2297,10 +2185,8 @@ class TestNdimageFilters:
|
|
2297
2185
|
xp_assert_equal(output, expected_value)
|
2298
2186
|
|
2299
2187
|
|
2188
|
+
@xfail_xp_backends("cupy", reason="TypeError")
|
2300
2189
|
def test_ticket_701(xp):
|
2301
|
-
if is_cupy(xp):
|
2302
|
-
pytest.xfail("CuPy raises a TypeError.")
|
2303
|
-
|
2304
2190
|
# Test generic filter sizes
|
2305
2191
|
arr = xp.asarray(np.arange(4).reshape(2, 2))
|
2306
2192
|
def func(x):
|
@@ -2340,9 +2226,8 @@ def test_gh_5430():
|
|
2340
2226
|
ndimage._ni_support._normalize_sequence(x, 0)
|
2341
2227
|
|
2342
2228
|
|
2229
|
+
@skip_xp_backends("cupy", reason="tests a private scipy utility")
|
2343
2230
|
def test_gaussian_kernel1d(xp):
|
2344
|
-
if is_cupy(xp):
|
2345
|
-
pytest.skip("This test tests a private scipy utility.")
|
2346
2231
|
radius = 10
|
2347
2232
|
sigma = 2
|
2348
2233
|
sigma2 = sigma * sigma
|
@@ -2373,13 +2258,12 @@ def test_orders_gauss(xp):
|
|
2373
2258
|
assert_raises(ValueError, ndimage.gaussian_filter1d, arr, 1, -1, -1)
|
2374
2259
|
|
2375
2260
|
|
2261
|
+
@xfail_xp_backends("cupy", reason="TypeError")
|
2376
2262
|
def test_valid_origins(xp):
|
2377
2263
|
"""Regression test for #1311."""
|
2378
|
-
if is_cupy(xp):
|
2379
|
-
pytest.xfail("CuPy raises a TypeError.")
|
2380
|
-
|
2381
2264
|
def func(x):
|
2382
2265
|
return xp.mean(x)
|
2266
|
+
|
2383
2267
|
data = xp.asarray([1, 2, 3, 4, 5], dtype=xp.float64)
|
2384
2268
|
assert_raises(ValueError, ndimage.generic_filter, data, func, size=3,
|
2385
2269
|
origin=2)
|
@@ -2418,9 +2302,7 @@ def test_bad_convolve_and_correlate_origins(xp):
|
|
2418
2302
|
assert_raises(ValueError, ndimage.convolve,
|
2419
2303
|
xp.ones((3, 5)), xp.ones((2, 2)), origin=[0, -2])
|
2420
2304
|
|
2421
|
-
@skip_xp_backends("cupy",
|
2422
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
2423
|
-
)
|
2305
|
+
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2424
2306
|
def test_multiple_modes(xp):
|
2425
2307
|
# Test that the filters with multiple mode capabilities for different
|
2426
2308
|
# dimensions give the same result as applying a single mode.
|
@@ -2452,14 +2334,13 @@ def test_multiple_modes(xp):
|
|
2452
2334
|
|
2453
2335
|
|
2454
2336
|
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2455
|
-
@skip_xp_backends("jax.numpy", reason="output array is read-only.")
|
2456
2337
|
def test_multiple_modes_sequentially(xp):
|
2457
2338
|
# Test that the filters with multiple mode capabilities for different
|
2458
2339
|
# dimensions give the same result as applying the filters with
|
2459
2340
|
# different modes sequentially
|
2460
2341
|
arr = xp.asarray([[1., 0., 0.],
|
2461
|
-
|
2462
|
-
|
2342
|
+
[1., 1., 0.],
|
2343
|
+
[0., 0., 0.]])
|
2463
2344
|
|
2464
2345
|
modes = ['reflect', 'wrap']
|
2465
2346
|
|
@@ -2567,9 +2448,7 @@ def test_multiple_modes_gaussian_gradient_magnitude(xp):
|
|
2567
2448
|
|
2568
2449
|
assert_almost_equal(expected, calculated)
|
2569
2450
|
|
2570
|
-
@skip_xp_backends("cupy",
|
2571
|
-
reason="https://github.com/cupy/cupy/pull/8430",
|
2572
|
-
)
|
2451
|
+
@skip_xp_backends("cupy", reason="https://github.com/cupy/cupy/pull/8430")
|
2573
2452
|
def test_multiple_modes_uniform(xp):
|
2574
2453
|
# Test uniform filter for multiple extrapolation modes
|
2575
2454
|
arr = xp.asarray([[1., 0., 0.],
|
@@ -2610,8 +2489,6 @@ def test_gaussian_truncate(xp):
|
|
2610
2489
|
)
|
2611
2490
|
assert num_nonzeros_5 == 51**2
|
2612
2491
|
|
2613
|
-
nnz_kw = {'as_tuple': True} if is_torch(xp) else {}
|
2614
|
-
|
2615
2492
|
# Test truncate when sigma is a sequence.
|
2616
2493
|
f = ndimage.gaussian_filter(arr, [0.5, 2.5], truncate=3.5)
|
2617
2494
|
fpos = f > 0
|
@@ -2630,22 +2507,20 @@ def test_gaussian_truncate(xp):
|
|
2630
2507
|
|
2631
2508
|
# Test gaussian_laplace
|
2632
2509
|
y = ndimage.gaussian_laplace(x, sigma=2, truncate=3.5)
|
2633
|
-
nonzero_indices = xp.nonzero(y != 0
|
2510
|
+
nonzero_indices = xp.nonzero(y != 0)[0]
|
2634
2511
|
|
2635
2512
|
n = xp.max(nonzero_indices) - xp.min(nonzero_indices) + 1
|
2636
2513
|
assert n == 15
|
2637
2514
|
|
2638
2515
|
# Test gaussian_gradient_magnitude
|
2639
2516
|
y = ndimage.gaussian_gradient_magnitude(x, sigma=2, truncate=3.5)
|
2640
|
-
nonzero_indices = xp.nonzero(y != 0
|
2517
|
+
nonzero_indices = xp.nonzero(y != 0)[0]
|
2641
2518
|
n = xp.max(nonzero_indices) - xp.min(nonzero_indices) + 1
|
2642
2519
|
assert n == 15
|
2643
2520
|
|
2644
2521
|
|
2522
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8402")
|
2645
2523
|
def test_gaussian_radius(xp):
|
2646
|
-
if is_cupy(xp):
|
2647
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8402")
|
2648
|
-
|
2649
2524
|
# Test that Gaussian filters with radius argument produce the same
|
2650
2525
|
# results as the filters with corresponding truncate argument.
|
2651
2526
|
# radius = int(truncate * sigma + 0.5)
|
@@ -2674,10 +2549,8 @@ def test_gaussian_radius(xp):
|
|
2674
2549
|
xp_assert_equal(f1, f2)
|
2675
2550
|
|
2676
2551
|
|
2552
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8402")
|
2677
2553
|
def test_gaussian_radius_invalid(xp):
|
2678
|
-
if is_cupy(xp):
|
2679
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8402")
|
2680
|
-
|
2681
2554
|
# radius must be a nonnegative integer
|
2682
2555
|
with assert_raises(ValueError):
|
2683
2556
|
ndimage.gaussian_filter1d(xp.zeros(8), sigma=1, radius=-1)
|
@@ -2685,7 +2558,7 @@ def test_gaussian_radius_invalid(xp):
|
|
2685
2558
|
ndimage.gaussian_filter1d(xp.zeros(8), sigma=1, radius=1.1)
|
2686
2559
|
|
2687
2560
|
|
2688
|
-
@
|
2561
|
+
@uses_output_array
|
2689
2562
|
class TestThreading:
|
2690
2563
|
def check_func_thread(self, n, fun, args, out):
|
2691
2564
|
from threading import Thread
|
@@ -2698,10 +2571,9 @@ class TestThreading:
|
|
2698
2571
|
for i in range(n):
|
2699
2572
|
fun(*args, output=out[i, ...])
|
2700
2573
|
|
2574
|
+
@xfail_xp_backends("cupy",
|
2575
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2701
2576
|
def test_correlate1d(self, xp):
|
2702
|
-
if is_cupy(xp):
|
2703
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2704
|
-
|
2705
2577
|
d = np.random.randn(5000)
|
2706
2578
|
os = np.empty((4, d.size))
|
2707
2579
|
ot = np.empty_like(os)
|
@@ -2713,10 +2585,9 @@ class TestThreading:
|
|
2713
2585
|
self.check_func_thread(4, ndimage.correlate1d, (d, k), ot)
|
2714
2586
|
xp_assert_equal(os, ot)
|
2715
2587
|
|
2588
|
+
@xfail_xp_backends("cupy",
|
2589
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2716
2590
|
def test_correlate(self, xp):
|
2717
|
-
if is_cupy(xp):
|
2718
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2719
|
-
|
2720
2591
|
d = xp.asarray(np.random.randn(500, 500))
|
2721
2592
|
k = xp.asarray(np.random.randn(10, 10))
|
2722
2593
|
os = xp.empty([4] + list(d.shape))
|
@@ -2725,10 +2596,9 @@ class TestThreading:
|
|
2725
2596
|
self.check_func_thread(4, ndimage.correlate, (d, k), ot)
|
2726
2597
|
xp_assert_equal(os, ot)
|
2727
2598
|
|
2599
|
+
@xfail_xp_backends("cupy",
|
2600
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2728
2601
|
def test_median_filter(self, xp):
|
2729
|
-
if is_cupy(xp):
|
2730
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2731
|
-
|
2732
2602
|
d = xp.asarray(np.random.randn(500, 500))
|
2733
2603
|
os = xp.empty([4] + list(d.shape))
|
2734
2604
|
ot = xp.empty_like(os)
|
@@ -2736,10 +2606,9 @@ class TestThreading:
|
|
2736
2606
|
self.check_func_thread(4, ndimage.median_filter, (d, 3), ot)
|
2737
2607
|
xp_assert_equal(os, ot)
|
2738
2608
|
|
2609
|
+
@xfail_xp_backends("cupy",
|
2610
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2739
2611
|
def test_uniform_filter1d(self, xp):
|
2740
|
-
if is_cupy(xp):
|
2741
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2742
|
-
|
2743
2612
|
d = np.random.randn(5000)
|
2744
2613
|
os = np.empty((4, d.size))
|
2745
2614
|
ot = np.empty_like(os)
|
@@ -2750,10 +2619,9 @@ class TestThreading:
|
|
2750
2619
|
self.check_func_thread(4, ndimage.uniform_filter1d, (d, 5), ot)
|
2751
2620
|
xp_assert_equal(os, ot)
|
2752
2621
|
|
2622
|
+
@xfail_xp_backends("cupy",
|
2623
|
+
reason="XXX thread exception; cannot repro outside of pytest")
|
2753
2624
|
def test_minmax_filter(self, xp):
|
2754
|
-
if is_cupy(xp):
|
2755
|
-
pytest.xfail("XXX thread exception; cannot repro outside of pytest")
|
2756
|
-
|
2757
2625
|
d = xp.asarray(np.random.randn(500, 500))
|
2758
2626
|
os = xp.empty([4] + list(d.shape))
|
2759
2627
|
ot = xp.empty_like(os)
|
@@ -2794,9 +2662,8 @@ def test_minmaximum_filter1d(xp):
|
|
2794
2662
|
xp_assert_equal(xp.asarray([9, 9, 4, 5, 6, 7, 8, 9, 9, 9]), out)
|
2795
2663
|
|
2796
2664
|
|
2665
|
+
@xfail_xp_backends("cupy", reason="cupy/cupy#8401")
|
2797
2666
|
def test_uniform_filter1d_roundoff_errors(xp):
|
2798
|
-
if is_cupy(xp):
|
2799
|
-
pytest.xfail("https://github.com/cupy/cupy/issues/8401")
|
2800
2667
|
# gh-6930
|
2801
2668
|
in_ = np.repeat([0, 1, 0], [9, 9, 9])
|
2802
2669
|
in_ = xp.asarray(in_)
|
@@ -2814,14 +2681,10 @@ def test_footprint_all_zeros(xp):
|
|
2814
2681
|
ndimage.maximum_filter(arr, footprint=kernel)
|
2815
2682
|
|
2816
2683
|
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
|
2821
|
-
if not hasattr(xp, "float16"):
|
2822
|
-
pytest.xfail(f"{xp} does not have float16")
|
2823
|
-
|
2824
|
-
# 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):
|
2825
2688
|
# gh-8207
|
2826
2689
|
data = xp.asarray([1], dtype=xp.float16)
|
2827
2690
|
sigma = 1.0
|
@@ -2829,10 +2692,8 @@ def test_gaussian_filter(xp):
|
|
2829
2692
|
ndimage.gaussian_filter(data, sigma)
|
2830
2693
|
|
2831
2694
|
|
2695
|
+
@xfail_xp_backends("cupy", reason="does not raise")
|
2832
2696
|
def test_rank_filter_noninteger_rank(xp):
|
2833
|
-
if is_cupy(xp):
|
2834
|
-
pytest.xfail("CuPy does not raise")
|
2835
|
-
|
2836
2697
|
# regression test for issue 9388: ValueError for
|
2837
2698
|
# non integer rank when performing rank_filter
|
2838
2699
|
arr = xp.asarray(np.random.random((10, 20, 30)))
|
@@ -2854,12 +2715,12 @@ def test_size_footprint_both_set(xp):
|
|
2854
2715
|
)
|
2855
2716
|
|
2856
2717
|
|
2857
|
-
|
2858
|
-
def test_byte_order_median(
|
2718
|
+
# NumPy-only because 'byteorder is numpy-specific'
|
2719
|
+
def test_byte_order_median():
|
2859
2720
|
"""Regression test for #413: median_filter does not handle bytes orders."""
|
2860
|
-
a =
|
2721
|
+
a = np.arange(9, dtype='<f4').reshape(3, 3)
|
2861
2722
|
ref = ndimage.median_filter(a, (3, 3))
|
2862
|
-
b =
|
2723
|
+
b = np.arange(9, dtype='>f4').reshape(3, 3)
|
2863
2724
|
t = ndimage.median_filter(b, (3, 3))
|
2864
2725
|
assert_array_almost_equal(ref, t)
|
2865
2726
|
|
@@ -2909,6 +2770,256 @@ def test_gh_22333():
|
|
2909
2770
|
assert_array_equal(actual, expected)
|
2910
2771
|
|
2911
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 length of `axes` may not exceed "
|
2912
|
+
axes = (0, 1, 2)
|
2913
|
+
with pytest.raises(ValueError, match=message):
|
2914
|
+
ndimage.vectorized_filter(input, function, size=(1, 2), axes=axes)
|
2915
|
+
with pytest.raises(ValueError, match=message):
|
2916
|
+
ndimage.vectorized_filter(input, function, footprint=xp.ones((2, 2)),
|
2917
|
+
axes=axes)
|
2918
|
+
|
2919
|
+
message = "`axes` must be compatible with the dimensionality..."
|
2920
|
+
with pytest.raises(ValueError, match=message):
|
2921
|
+
ndimage.vectorized_filter(input, function, size=(1,))
|
2922
|
+
with pytest.raises(ValueError, match=message):
|
2923
|
+
ndimage.vectorized_filter(input, function, size=(2,), axes=(0,1))
|
2924
|
+
|
2925
|
+
message = "All elements of `origin` must be integers"
|
2926
|
+
with pytest.raises(ValueError, match=message):
|
2927
|
+
ndimage.vectorized_filter(input, function, size=size, origin=(1, 1.5))
|
2928
|
+
|
2929
|
+
message = "`origin` must be an integer or tuple of integers with length..."
|
2930
|
+
with pytest.raises(ValueError, match=message):
|
2931
|
+
ndimage.vectorized_filter(input, function, size=size, origin=(1, 2, 3))
|
2932
|
+
|
2933
|
+
message = "`mode` must be one of..."
|
2934
|
+
with pytest.raises(ValueError, match=message):
|
2935
|
+
ndimage.vectorized_filter(input, function, size=size, mode='coconut')
|
2936
|
+
|
2937
|
+
message = "`mode='valid'` is incompatible with use of `origin`."
|
2938
|
+
with pytest.raises(ValueError, match=message):
|
2939
|
+
ndimage.vectorized_filter(input, function, size=size,
|
2940
|
+
mode='valid', origin=1)
|
2941
|
+
|
2942
|
+
message = "Use of `cval` is compatible only with `mode='constant'`."
|
2943
|
+
with pytest.raises(ValueError, match=message):
|
2944
|
+
ndimage.vectorized_filter(input, function, size=size, mode='valid', cval=1)
|
2945
|
+
|
2946
|
+
other_messages = "|Unsupported|The array_api_strict|new|Value 'a duck'"
|
2947
|
+
message = "`cval` must include only numbers." + other_messages
|
2948
|
+
with pytest.raises((ValueError, TypeError), match=message):
|
2949
|
+
ndimage.vectorized_filter(input, function, size=size,
|
2950
|
+
mode='constant', cval='a duck')
|
2951
|
+
|
2952
|
+
message = "`batch_memory` must be positive number." + other_messages
|
2953
|
+
with pytest.raises(ValueError, match=message):
|
2954
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory=0)
|
2955
|
+
with pytest.raises(ValueError, match=message):
|
2956
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory=(1, 2))
|
2957
|
+
with pytest.raises((ValueError, TypeError), match=message):
|
2958
|
+
ndimage.vectorized_filter(input, function, size=size, batch_memory="a duck")
|
2959
|
+
|
2960
|
+
@pytest.mark.parametrize('shape', [(0,), (1, 0), (0, 1, 0)])
|
2961
|
+
def test_zero_size(self, shape, xp):
|
2962
|
+
input = xp.empty(shape)
|
2963
|
+
res = ndimage.vectorized_filter(input, xp.mean, size=1)
|
2964
|
+
xp_assert_equal(res, input)
|
2965
|
+
|
2966
|
+
@pytest.mark.filterwarnings("ignore:Mean of empty slice.:RuntimeWarning")
|
2967
|
+
def test_edge_cases(self, xp):
|
2968
|
+
rng = np.random.default_rng(4835982345234982)
|
2969
|
+
function = xp.mean
|
2970
|
+
|
2971
|
+
# 0-D input
|
2972
|
+
input = xp.asarray(1.)
|
2973
|
+
res = ndimage.vectorized_filter(input, function, size=())
|
2974
|
+
xp_assert_equal(res, xp.asarray(function(input, axis=())))
|
2975
|
+
|
2976
|
+
if not (is_array_api_strict(xp) or is_dask(xp)):
|
2977
|
+
res = ndimage.vectorized_filter(input, function, footprint=True)
|
2978
|
+
xp_assert_equal(res, xp.asarray(function(input[True], axis=())))
|
2979
|
+
|
2980
|
+
res = ndimage.vectorized_filter(input, function, footprint=False)
|
2981
|
+
xp_assert_equal(res, xp.asarray(function(input[False], axis=())))
|
2982
|
+
|
2983
|
+
# 1x1 window
|
2984
|
+
input = xp.asarray(rng.random((5, 5)))
|
2985
|
+
res = ndimage.vectorized_filter(input, function, size=1)
|
2986
|
+
xp_assert_equal(res, input)
|
2987
|
+
|
2988
|
+
# window is bigger than input shouldn't be a problem
|
2989
|
+
res = ndimage.vectorized_filter(input, function, size=21)
|
2990
|
+
ref = ndimage.vectorized_filter(input, function, size=21)
|
2991
|
+
xp_assert_close(res, ref)
|
2992
|
+
|
2993
|
+
def test_gh23046_feature(self, xp):
|
2994
|
+
# The intent of gh-23046 was to always allow `size` to be a scalar.
|
2995
|
+
rng = np.random.default_rng(45982734597824)
|
2996
|
+
img = xp.asarray(rng.random((5, 5)))
|
2997
|
+
|
2998
|
+
ref = ndimage.vectorized_filter(img, xp.mean, size=2)
|
2999
|
+
res = ndimage.vectorized_filter(img, xp.mean, size=2, axes=(0, 1))
|
3000
|
+
xp_assert_close(res, ref)
|
3001
|
+
|
3002
|
+
ref = ndimage.vectorized_filter(img, xp.mean, size=(2,), axes=(0,))
|
3003
|
+
res = ndimage.vectorized_filter(img, xp.mean, size=2, axes=0)
|
3004
|
+
xp_assert_close(res, ref)
|
3005
|
+
|
3006
|
+
def test_gh23046_fix(self, xp):
|
3007
|
+
# While investigating the feasibility of gh-23046, I noticed a bug when the
|
3008
|
+
# length of an `axes` tuple equals the dimensionality of the image.
|
3009
|
+
rng = np.random.default_rng(45982734597824)
|
3010
|
+
img = xp.asarray(rng.random((5, 5)))
|
3011
|
+
size = (2, 3)
|
3012
|
+
ref = ndimage.vectorized_filter(img.T, xp.mean, size=size).T
|
3013
|
+
res = ndimage.vectorized_filter(img, xp.mean, size=size, axes=(1, 0))
|
3014
|
+
xp_assert_close(res, ref)
|
3015
|
+
|
3016
|
+
ref = ndimage.vectorized_filter(img, xp.mean, size=size, mode='constant')
|
3017
|
+
res = ndimage.vectorized_filter(img, xp.mean, size=size[::-1], axes=(1, 0),
|
3018
|
+
mode='constant')
|
3019
|
+
xp_assert_close(res, ref)
|
3020
|
+
|
3021
|
+
|
3022
|
+
|
2912
3023
|
@given(x=npst.arrays(dtype=np.float64,
|
2913
3024
|
shape=st.integers(min_value=1, max_value=1000)),
|
2914
3025
|
size=st.integers(min_value=1, max_value=50),
|