scipy 1.16.2__cp312-cp312-win_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scipy/__config__.py +161 -0
- scipy/__init__.py +150 -0
- scipy/_cyutility.cp312-win_arm64.lib +0 -0
- scipy/_cyutility.cp312-win_arm64.pyd +0 -0
- scipy/_distributor_init.py +18 -0
- scipy/_lib/__init__.py +14 -0
- scipy/_lib/_array_api.py +931 -0
- scipy/_lib/_array_api_compat_vendor.py +9 -0
- scipy/_lib/_array_api_no_0d.py +103 -0
- scipy/_lib/_bunch.py +229 -0
- scipy/_lib/_ccallback.py +251 -0
- scipy/_lib/_ccallback_c.cp312-win_arm64.lib +0 -0
- scipy/_lib/_ccallback_c.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_disjoint_set.py +254 -0
- scipy/_lib/_docscrape.py +761 -0
- scipy/_lib/_elementwise_iterative_method.py +346 -0
- scipy/_lib/_fpumode.cp312-win_arm64.lib +0 -0
- scipy/_lib/_fpumode.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_gcutils.py +105 -0
- scipy/_lib/_pep440.py +487 -0
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_ccallback.cp312-win_arm64.lib +0 -0
- scipy/_lib/_test_ccallback.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp312-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_call.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp312-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_def.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_testutils.py +373 -0
- scipy/_lib/_threadsafety.py +58 -0
- scipy/_lib/_tmpdirs.py +86 -0
- scipy/_lib/_uarray/LICENSE +29 -0
- scipy/_lib/_uarray/__init__.py +116 -0
- scipy/_lib/_uarray/_backend.py +707 -0
- scipy/_lib/_uarray/_uarray.cp312-win_arm64.lib +0 -0
- scipy/_lib/_uarray/_uarray.cp312-win_arm64.pyd +0 -0
- scipy/_lib/_util.py +1283 -0
- scipy/_lib/array_api_compat/__init__.py +22 -0
- scipy/_lib/array_api_compat/_internal.py +59 -0
- scipy/_lib/array_api_compat/common/__init__.py +1 -0
- scipy/_lib/array_api_compat/common/_aliases.py +727 -0
- scipy/_lib/array_api_compat/common/_fft.py +213 -0
- scipy/_lib/array_api_compat/common/_helpers.py +1058 -0
- scipy/_lib/array_api_compat/common/_linalg.py +232 -0
- scipy/_lib/array_api_compat/common/_typing.py +192 -0
- scipy/_lib/array_api_compat/cupy/__init__.py +13 -0
- scipy/_lib/array_api_compat/cupy/_aliases.py +156 -0
- scipy/_lib/array_api_compat/cupy/_info.py +336 -0
- scipy/_lib/array_api_compat/cupy/_typing.py +31 -0
- scipy/_lib/array_api_compat/cupy/fft.py +36 -0
- scipy/_lib/array_api_compat/cupy/linalg.py +49 -0
- scipy/_lib/array_api_compat/dask/__init__.py +0 -0
- scipy/_lib/array_api_compat/dask/array/__init__.py +12 -0
- scipy/_lib/array_api_compat/dask/array/_aliases.py +376 -0
- scipy/_lib/array_api_compat/dask/array/_info.py +416 -0
- scipy/_lib/array_api_compat/dask/array/fft.py +21 -0
- scipy/_lib/array_api_compat/dask/array/linalg.py +72 -0
- scipy/_lib/array_api_compat/numpy/__init__.py +28 -0
- scipy/_lib/array_api_compat/numpy/_aliases.py +190 -0
- scipy/_lib/array_api_compat/numpy/_info.py +366 -0
- scipy/_lib/array_api_compat/numpy/_typing.py +30 -0
- scipy/_lib/array_api_compat/numpy/fft.py +35 -0
- scipy/_lib/array_api_compat/numpy/linalg.py +143 -0
- scipy/_lib/array_api_compat/torch/__init__.py +22 -0
- scipy/_lib/array_api_compat/torch/_aliases.py +855 -0
- scipy/_lib/array_api_compat/torch/_info.py +369 -0
- scipy/_lib/array_api_compat/torch/_typing.py +3 -0
- scipy/_lib/array_api_compat/torch/fft.py +85 -0
- scipy/_lib/array_api_compat/torch/linalg.py +121 -0
- scipy/_lib/array_api_extra/__init__.py +38 -0
- 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/cobyqa/__init__.py +20 -0
- scipy/_lib/cobyqa/framework.py +1240 -0
- scipy/_lib/cobyqa/main.py +1506 -0
- scipy/_lib/cobyqa/models.py +1529 -0
- scipy/_lib/cobyqa/problem.py +1296 -0
- scipy/_lib/cobyqa/settings.py +132 -0
- scipy/_lib/cobyqa/subsolvers/__init__.py +14 -0
- scipy/_lib/cobyqa/subsolvers/geometry.py +387 -0
- scipy/_lib/cobyqa/subsolvers/optim.py +1203 -0
- scipy/_lib/cobyqa/utils/__init__.py +18 -0
- scipy/_lib/cobyqa/utils/exceptions.py +22 -0
- scipy/_lib/cobyqa/utils/math.py +77 -0
- scipy/_lib/cobyqa/utils/versions.py +67 -0
- scipy/_lib/decorator.py +399 -0
- scipy/_lib/deprecation.py +274 -0
- scipy/_lib/doccer.py +366 -0
- scipy/_lib/messagestream.cp312-win_arm64.lib +0 -0
- scipy/_lib/messagestream.cp312-win_arm64.pyd +0 -0
- scipy/_lib/pyprima/__init__.py +212 -0
- scipy/_lib/pyprima/cobyla/__init__.py +0 -0
- scipy/_lib/pyprima/cobyla/cobyla.py +559 -0
- scipy/_lib/pyprima/cobyla/cobylb.py +714 -0
- scipy/_lib/pyprima/cobyla/geometry.py +226 -0
- scipy/_lib/pyprima/cobyla/initialize.py +215 -0
- scipy/_lib/pyprima/cobyla/trustregion.py +492 -0
- scipy/_lib/pyprima/cobyla/update.py +289 -0
- scipy/_lib/pyprima/common/__init__.py +0 -0
- scipy/_lib/pyprima/common/_bounds.py +34 -0
- scipy/_lib/pyprima/common/_linear_constraints.py +46 -0
- scipy/_lib/pyprima/common/_nonlinear_constraints.py +54 -0
- scipy/_lib/pyprima/common/_project.py +173 -0
- scipy/_lib/pyprima/common/checkbreak.py +93 -0
- scipy/_lib/pyprima/common/consts.py +47 -0
- scipy/_lib/pyprima/common/evaluate.py +99 -0
- scipy/_lib/pyprima/common/history.py +38 -0
- scipy/_lib/pyprima/common/infos.py +30 -0
- scipy/_lib/pyprima/common/linalg.py +435 -0
- scipy/_lib/pyprima/common/message.py +290 -0
- scipy/_lib/pyprima/common/powalg.py +131 -0
- scipy/_lib/pyprima/common/preproc.py +277 -0
- scipy/_lib/pyprima/common/present.py +5 -0
- scipy/_lib/pyprima/common/ratio.py +54 -0
- scipy/_lib/pyprima/common/redrho.py +47 -0
- scipy/_lib/pyprima/common/selectx.py +296 -0
- scipy/_lib/tests/__init__.py +0 -0
- scipy/_lib/tests/test__gcutils.py +110 -0
- scipy/_lib/tests/test__pep440.py +67 -0
- scipy/_lib/tests/test__testutils.py +32 -0
- scipy/_lib/tests/test__threadsafety.py +51 -0
- scipy/_lib/tests/test__util.py +641 -0
- scipy/_lib/tests/test_array_api.py +322 -0
- scipy/_lib/tests/test_bunch.py +169 -0
- scipy/_lib/tests/test_ccallback.py +196 -0
- scipy/_lib/tests/test_config.py +45 -0
- scipy/_lib/tests/test_deprecation.py +10 -0
- scipy/_lib/tests/test_doccer.py +143 -0
- scipy/_lib/tests/test_import_cycles.py +18 -0
- scipy/_lib/tests/test_public_api.py +482 -0
- scipy/_lib/tests/test_scipy_version.py +28 -0
- scipy/_lib/tests/test_tmpdirs.py +48 -0
- scipy/_lib/tests/test_warnings.py +137 -0
- scipy/_lib/uarray.py +31 -0
- scipy/cluster/__init__.py +31 -0
- scipy/cluster/_hierarchy.cp312-win_arm64.lib +0 -0
- scipy/cluster/_hierarchy.cp312-win_arm64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp312-win_arm64.lib +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp312-win_arm64.pyd +0 -0
- scipy/cluster/_vq.cp312-win_arm64.lib +0 -0
- scipy/cluster/_vq.cp312-win_arm64.pyd +0 -0
- scipy/cluster/hierarchy.py +4348 -0
- scipy/cluster/tests/__init__.py +0 -0
- scipy/cluster/tests/hierarchy_test_data.py +145 -0
- scipy/cluster/tests/test_disjoint_set.py +202 -0
- scipy/cluster/tests/test_hierarchy.py +1238 -0
- scipy/cluster/tests/test_vq.py +434 -0
- scipy/cluster/vq.py +832 -0
- scipy/conftest.py +683 -0
- scipy/constants/__init__.py +358 -0
- scipy/constants/_codata.py +2266 -0
- scipy/constants/_constants.py +369 -0
- scipy/constants/codata.py +21 -0
- scipy/constants/constants.py +53 -0
- scipy/constants/tests/__init__.py +0 -0
- scipy/constants/tests/test_codata.py +78 -0
- scipy/constants/tests/test_constants.py +83 -0
- scipy/datasets/__init__.py +90 -0
- scipy/datasets/_download_all.py +71 -0
- scipy/datasets/_fetchers.py +225 -0
- scipy/datasets/_registry.py +26 -0
- scipy/datasets/_utils.py +81 -0
- scipy/datasets/tests/__init__.py +0 -0
- scipy/datasets/tests/test_data.py +128 -0
- scipy/differentiate/__init__.py +27 -0
- scipy/differentiate/_differentiate.py +1129 -0
- scipy/differentiate/tests/__init__.py +0 -0
- scipy/differentiate/tests/test_differentiate.py +694 -0
- scipy/fft/__init__.py +114 -0
- scipy/fft/_backend.py +196 -0
- scipy/fft/_basic.py +1650 -0
- scipy/fft/_basic_backend.py +197 -0
- scipy/fft/_debug_backends.py +22 -0
- scipy/fft/_fftlog.py +223 -0
- scipy/fft/_fftlog_backend.py +200 -0
- scipy/fft/_helper.py +348 -0
- scipy/fft/_pocketfft/LICENSE.md +25 -0
- scipy/fft/_pocketfft/__init__.py +9 -0
- scipy/fft/_pocketfft/basic.py +251 -0
- scipy/fft/_pocketfft/helper.py +249 -0
- scipy/fft/_pocketfft/pypocketfft.cp312-win_arm64.lib +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp312-win_arm64.pyd +0 -0
- scipy/fft/_pocketfft/realtransforms.py +109 -0
- scipy/fft/_pocketfft/tests/__init__.py +0 -0
- scipy/fft/_pocketfft/tests/test_basic.py +1011 -0
- scipy/fft/_pocketfft/tests/test_real_transforms.py +505 -0
- scipy/fft/_realtransforms.py +706 -0
- scipy/fft/_realtransforms_backend.py +63 -0
- scipy/fft/tests/__init__.py +0 -0
- scipy/fft/tests/mock_backend.py +96 -0
- scipy/fft/tests/test_backend.py +98 -0
- scipy/fft/tests/test_basic.py +504 -0
- scipy/fft/tests/test_fftlog.py +215 -0
- scipy/fft/tests/test_helper.py +558 -0
- scipy/fft/tests/test_multithreading.py +84 -0
- scipy/fft/tests/test_real_transforms.py +247 -0
- scipy/fftpack/__init__.py +103 -0
- scipy/fftpack/_basic.py +428 -0
- scipy/fftpack/_helper.py +115 -0
- scipy/fftpack/_pseudo_diffs.py +554 -0
- scipy/fftpack/_realtransforms.py +598 -0
- scipy/fftpack/basic.py +20 -0
- scipy/fftpack/convolve.cp312-win_arm64.lib +0 -0
- scipy/fftpack/convolve.cp312-win_arm64.pyd +0 -0
- scipy/fftpack/helper.py +19 -0
- scipy/fftpack/pseudo_diffs.py +22 -0
- scipy/fftpack/realtransforms.py +19 -0
- scipy/fftpack/tests/__init__.py +0 -0
- scipy/fftpack/tests/fftw_double_ref.npz +0 -0
- scipy/fftpack/tests/fftw_longdouble_ref.npz +0 -0
- scipy/fftpack/tests/fftw_single_ref.npz +0 -0
- scipy/fftpack/tests/test.npz +0 -0
- scipy/fftpack/tests/test_basic.py +877 -0
- scipy/fftpack/tests/test_helper.py +54 -0
- scipy/fftpack/tests/test_import.py +33 -0
- scipy/fftpack/tests/test_pseudo_diffs.py +388 -0
- scipy/fftpack/tests/test_real_transforms.py +836 -0
- scipy/integrate/__init__.py +122 -0
- scipy/integrate/_bvp.py +1160 -0
- scipy/integrate/_cubature.py +729 -0
- scipy/integrate/_dop.cp312-win_arm64.lib +0 -0
- scipy/integrate/_dop.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_ivp/__init__.py +8 -0
- scipy/integrate/_ivp/base.py +290 -0
- scipy/integrate/_ivp/bdf.py +478 -0
- scipy/integrate/_ivp/common.py +451 -0
- scipy/integrate/_ivp/dop853_coefficients.py +193 -0
- scipy/integrate/_ivp/ivp.py +755 -0
- scipy/integrate/_ivp/lsoda.py +224 -0
- scipy/integrate/_ivp/radau.py +572 -0
- scipy/integrate/_ivp/rk.py +601 -0
- scipy/integrate/_ivp/tests/__init__.py +0 -0
- scipy/integrate/_ivp/tests/test_ivp.py +1287 -0
- scipy/integrate/_ivp/tests/test_rk.py +37 -0
- scipy/integrate/_lebedev.py +5450 -0
- scipy/integrate/_lsoda.cp312-win_arm64.lib +0 -0
- scipy/integrate/_lsoda.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_ode.py +1395 -0
- scipy/integrate/_odepack.cp312-win_arm64.lib +0 -0
- scipy/integrate/_odepack.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_odepack_py.py +273 -0
- scipy/integrate/_quad_vec.py +674 -0
- scipy/integrate/_quadpack.cp312-win_arm64.lib +0 -0
- scipy/integrate/_quadpack.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_quadpack_py.py +1283 -0
- scipy/integrate/_quadrature.py +1336 -0
- scipy/integrate/_rules/__init__.py +12 -0
- scipy/integrate/_rules/_base.py +518 -0
- scipy/integrate/_rules/_gauss_kronrod.py +202 -0
- scipy/integrate/_rules/_gauss_legendre.py +62 -0
- scipy/integrate/_rules/_genz_malik.py +210 -0
- scipy/integrate/_tanhsinh.py +1385 -0
- scipy/integrate/_test_multivariate.cp312-win_arm64.lib +0 -0
- scipy/integrate/_test_multivariate.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp312-win_arm64.lib +0 -0
- scipy/integrate/_test_odeint_banded.cp312-win_arm64.pyd +0 -0
- scipy/integrate/_vode.cp312-win_arm64.lib +0 -0
- scipy/integrate/_vode.cp312-win_arm64.pyd +0 -0
- scipy/integrate/dop.py +15 -0
- scipy/integrate/lsoda.py +15 -0
- scipy/integrate/odepack.py +17 -0
- scipy/integrate/quadpack.py +23 -0
- scipy/integrate/tests/__init__.py +0 -0
- scipy/integrate/tests/test__quad_vec.py +211 -0
- scipy/integrate/tests/test_banded_ode_solvers.py +305 -0
- scipy/integrate/tests/test_bvp.py +714 -0
- scipy/integrate/tests/test_cubature.py +1375 -0
- scipy/integrate/tests/test_integrate.py +840 -0
- scipy/integrate/tests/test_odeint_jac.py +74 -0
- scipy/integrate/tests/test_quadpack.py +680 -0
- scipy/integrate/tests/test_quadrature.py +730 -0
- scipy/integrate/tests/test_tanhsinh.py +1171 -0
- scipy/integrate/vode.py +15 -0
- scipy/interpolate/__init__.py +228 -0
- scipy/interpolate/_bary_rational.py +715 -0
- scipy/interpolate/_bsplines.py +2469 -0
- scipy/interpolate/_cubic.py +973 -0
- scipy/interpolate/_dfitpack.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_dfitpack.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_dierckx.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_dierckx.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_fitpack.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_fitpack.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_fitpack2.py +2397 -0
- scipy/interpolate/_fitpack_impl.py +811 -0
- scipy/interpolate/_fitpack_py.py +898 -0
- scipy/interpolate/_fitpack_repro.py +996 -0
- scipy/interpolate/_interpnd.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_interpnd.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_interpolate.py +2266 -0
- scipy/interpolate/_ndbspline.py +415 -0
- scipy/interpolate/_ndgriddata.py +329 -0
- scipy/interpolate/_pade.py +67 -0
- scipy/interpolate/_polyint.py +1025 -0
- scipy/interpolate/_ppoly.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_ppoly.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_rbf.py +290 -0
- scipy/interpolate/_rbfinterp.py +550 -0
- scipy/interpolate/_rbfinterp_pythran.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/_rgi.py +764 -0
- scipy/interpolate/_rgi_cython.cp312-win_arm64.lib +0 -0
- scipy/interpolate/_rgi_cython.cp312-win_arm64.pyd +0 -0
- scipy/interpolate/dfitpack.py +24 -0
- scipy/interpolate/fitpack.py +31 -0
- scipy/interpolate/fitpack2.py +29 -0
- scipy/interpolate/interpnd.py +24 -0
- scipy/interpolate/interpolate.py +30 -0
- scipy/interpolate/ndgriddata.py +23 -0
- scipy/interpolate/polyint.py +24 -0
- scipy/interpolate/rbf.py +18 -0
- scipy/interpolate/tests/__init__.py +0 -0
- scipy/interpolate/tests/data/bug-1310.npz +0 -0
- scipy/interpolate/tests/data/estimate_gradients_hang.npy +0 -0
- scipy/interpolate/tests/data/gcvspl.npz +0 -0
- scipy/interpolate/tests/test_bary_rational.py +368 -0
- scipy/interpolate/tests/test_bsplines.py +3754 -0
- scipy/interpolate/tests/test_fitpack.py +519 -0
- scipy/interpolate/tests/test_fitpack2.py +1431 -0
- scipy/interpolate/tests/test_gil.py +64 -0
- scipy/interpolate/tests/test_interpnd.py +452 -0
- scipy/interpolate/tests/test_interpolate.py +2630 -0
- scipy/interpolate/tests/test_ndgriddata.py +308 -0
- scipy/interpolate/tests/test_pade.py +107 -0
- scipy/interpolate/tests/test_polyint.py +972 -0
- scipy/interpolate/tests/test_rbf.py +246 -0
- scipy/interpolate/tests/test_rbfinterp.py +534 -0
- scipy/interpolate/tests/test_rgi.py +1151 -0
- scipy/io/__init__.py +116 -0
- scipy/io/_fast_matrix_market/__init__.py +600 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp312-win_arm64.lib +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp312-win_arm64.pyd +0 -0
- scipy/io/_fortran.py +354 -0
- scipy/io/_harwell_boeing/__init__.py +7 -0
- scipy/io/_harwell_boeing/_fortran_format_parser.py +316 -0
- scipy/io/_harwell_boeing/hb.py +571 -0
- scipy/io/_harwell_boeing/tests/__init__.py +0 -0
- scipy/io/_harwell_boeing/tests/test_fortran_format.py +74 -0
- scipy/io/_harwell_boeing/tests/test_hb.py +70 -0
- scipy/io/_idl.py +917 -0
- scipy/io/_mmio.py +968 -0
- scipy/io/_netcdf.py +1104 -0
- scipy/io/_test_fortran.cp312-win_arm64.lib +0 -0
- scipy/io/_test_fortran.cp312-win_arm64.pyd +0 -0
- scipy/io/arff/__init__.py +28 -0
- scipy/io/arff/_arffread.py +873 -0
- scipy/io/arff/arffread.py +19 -0
- scipy/io/arff/tests/__init__.py +0 -0
- scipy/io/arff/tests/data/iris.arff +225 -0
- scipy/io/arff/tests/data/missing.arff +8 -0
- scipy/io/arff/tests/data/nodata.arff +11 -0
- scipy/io/arff/tests/data/quoted_nominal.arff +13 -0
- scipy/io/arff/tests/data/quoted_nominal_spaces.arff +13 -0
- scipy/io/arff/tests/data/test1.arff +10 -0
- scipy/io/arff/tests/data/test10.arff +8 -0
- scipy/io/arff/tests/data/test11.arff +11 -0
- scipy/io/arff/tests/data/test2.arff +15 -0
- scipy/io/arff/tests/data/test3.arff +6 -0
- scipy/io/arff/tests/data/test4.arff +11 -0
- scipy/io/arff/tests/data/test5.arff +26 -0
- scipy/io/arff/tests/data/test6.arff +12 -0
- scipy/io/arff/tests/data/test7.arff +15 -0
- scipy/io/arff/tests/data/test8.arff +12 -0
- scipy/io/arff/tests/data/test9.arff +14 -0
- scipy/io/arff/tests/test_arffread.py +421 -0
- scipy/io/harwell_boeing.py +17 -0
- scipy/io/idl.py +17 -0
- scipy/io/matlab/__init__.py +66 -0
- scipy/io/matlab/_byteordercodes.py +75 -0
- scipy/io/matlab/_mio.py +375 -0
- scipy/io/matlab/_mio4.py +632 -0
- scipy/io/matlab/_mio5.py +901 -0
- scipy/io/matlab/_mio5_params.py +281 -0
- scipy/io/matlab/_mio5_utils.cp312-win_arm64.lib +0 -0
- scipy/io/matlab/_mio5_utils.cp312-win_arm64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp312-win_arm64.lib +0 -0
- scipy/io/matlab/_mio_utils.cp312-win_arm64.pyd +0 -0
- scipy/io/matlab/_miobase.py +435 -0
- scipy/io/matlab/_streams.cp312-win_arm64.lib +0 -0
- scipy/io/matlab/_streams.cp312-win_arm64.pyd +0 -0
- scipy/io/matlab/byteordercodes.py +17 -0
- scipy/io/matlab/mio.py +16 -0
- scipy/io/matlab/mio4.py +17 -0
- scipy/io/matlab/mio5.py +19 -0
- scipy/io/matlab/mio5_params.py +18 -0
- scipy/io/matlab/mio5_utils.py +17 -0
- scipy/io/matlab/mio_utils.py +17 -0
- scipy/io/matlab/miobase.py +16 -0
- scipy/io/matlab/streams.py +16 -0
- scipy/io/matlab/tests/__init__.py +0 -0
- scipy/io/matlab/tests/data/bad_miuint32.mat +0 -0
- scipy/io/matlab/tests/data/bad_miutf8_array_name.mat +0 -0
- scipy/io/matlab/tests/data/big_endian.mat +0 -0
- scipy/io/matlab/tests/data/broken_utf8.mat +0 -0
- scipy/io/matlab/tests/data/corrupted_zlib_checksum.mat +0 -0
- scipy/io/matlab/tests/data/corrupted_zlib_data.mat +0 -0
- scipy/io/matlab/tests/data/debigged_m4.mat +0 -0
- scipy/io/matlab/tests/data/japanese_utf8.txt +5 -0
- scipy/io/matlab/tests/data/little_endian.mat +0 -0
- scipy/io/matlab/tests/data/logical_sparse.mat +0 -0
- scipy/io/matlab/tests/data/malformed1.mat +0 -0
- scipy/io/matlab/tests/data/miuint32_for_miint32.mat +0 -0
- scipy/io/matlab/tests/data/miutf8_array_name.mat +0 -0
- scipy/io/matlab/tests/data/nasty_duplicate_fieldnames.mat +0 -0
- scipy/io/matlab/tests/data/one_by_zero_char.mat +0 -0
- scipy/io/matlab/tests/data/parabola.mat +0 -0
- scipy/io/matlab/tests/data/single_empty_string.mat +0 -0
- scipy/io/matlab/tests/data/some_functions.mat +0 -0
- scipy/io/matlab/tests/data/sqr.mat +0 -0
- scipy/io/matlab/tests/data/test3dmatrix_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/test3dmatrix_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/test3dmatrix_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/test3dmatrix_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/test_empty_struct.mat +0 -0
- scipy/io/matlab/tests/data/test_mat4_le_floats.mat +0 -0
- scipy/io/matlab/tests/data/test_skip_variable.mat +0 -0
- scipy/io/matlab/tests/data/testbool_8_WIN64.mat +0 -0
- scipy/io/matlab/tests/data/testcell_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testcell_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcell_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcell_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcellnest_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testcellnest_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcellnest_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcellnest_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcomplex_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testcomplex_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testcomplex_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcomplex_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testcomplex_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testdouble_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testdouble_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testdouble_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testdouble_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testdouble_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testemptycell_5.3_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testemptycell_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testemptycell_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testemptycell_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testfunc_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testhdf5_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testmatrix_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testmatrix_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testmatrix_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testmatrix_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testmatrix_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testminus_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testminus_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testminus_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testminus_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testminus_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testmulti_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testmulti_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testmulti_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testobject_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testobject_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testobject_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testobject_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testonechar_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testonechar_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testonechar_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testonechar_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testonechar_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testscalarcell_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsimplecell.mat +0 -0
- scipy/io/matlab/tests/data/testsparse_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testsparse_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testsparse_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparse_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparse_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparsecomplex_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testsparsecomplex_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/testsparsecomplex_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparsecomplex_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparsecomplex_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testsparsefloat_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststring_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststring_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststring_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststring_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststring_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststringarray_4.2c_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststringarray_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststringarray_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststringarray_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststringarray_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststruct_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststruct_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststruct_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststruct_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructarr_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststructarr_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructarr_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructarr_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructnest_6.1_SOL2.mat +0 -0
- scipy/io/matlab/tests/data/teststructnest_6.5.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructnest_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/teststructnest_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testunicode_7.1_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testunicode_7.4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/data/testvec_4_GLNX86.mat +0 -0
- scipy/io/matlab/tests/test_byteordercodes.py +29 -0
- scipy/io/matlab/tests/test_mio.py +1399 -0
- scipy/io/matlab/tests/test_mio5_utils.py +179 -0
- scipy/io/matlab/tests/test_mio_funcs.py +51 -0
- scipy/io/matlab/tests/test_mio_utils.py +45 -0
- scipy/io/matlab/tests/test_miobase.py +32 -0
- scipy/io/matlab/tests/test_pathological.py +33 -0
- scipy/io/matlab/tests/test_streams.py +241 -0
- scipy/io/mmio.py +17 -0
- scipy/io/netcdf.py +17 -0
- scipy/io/tests/__init__.py +0 -0
- scipy/io/tests/data/Transparent Busy.ani +0 -0
- scipy/io/tests/data/array_float32_1d.sav +0 -0
- scipy/io/tests/data/array_float32_2d.sav +0 -0
- scipy/io/tests/data/array_float32_3d.sav +0 -0
- scipy/io/tests/data/array_float32_4d.sav +0 -0
- scipy/io/tests/data/array_float32_5d.sav +0 -0
- scipy/io/tests/data/array_float32_6d.sav +0 -0
- scipy/io/tests/data/array_float32_7d.sav +0 -0
- scipy/io/tests/data/array_float32_8d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_1d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_2d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_3d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_4d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_5d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_6d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_7d.sav +0 -0
- scipy/io/tests/data/array_float32_pointer_8d.sav +0 -0
- scipy/io/tests/data/example_1.nc +0 -0
- scipy/io/tests/data/example_2.nc +0 -0
- scipy/io/tests/data/example_3_maskedvals.nc +0 -0
- scipy/io/tests/data/fortran-3x3d-2i.dat +0 -0
- scipy/io/tests/data/fortran-mixed.dat +0 -0
- scipy/io/tests/data/fortran-sf8-11x1x10.dat +0 -0
- scipy/io/tests/data/fortran-sf8-15x10x22.dat +0 -0
- scipy/io/tests/data/fortran-sf8-1x1x1.dat +0 -0
- scipy/io/tests/data/fortran-sf8-1x1x5.dat +0 -0
- scipy/io/tests/data/fortran-sf8-1x1x7.dat +0 -0
- scipy/io/tests/data/fortran-sf8-1x3x5.dat +0 -0
- scipy/io/tests/data/fortran-si4-11x1x10.dat +0 -0
- scipy/io/tests/data/fortran-si4-15x10x22.dat +0 -0
- scipy/io/tests/data/fortran-si4-1x1x1.dat +0 -0
- scipy/io/tests/data/fortran-si4-1x1x5.dat +0 -0
- scipy/io/tests/data/fortran-si4-1x1x7.dat +0 -0
- scipy/io/tests/data/fortran-si4-1x3x5.dat +0 -0
- scipy/io/tests/data/invalid_pointer.sav +0 -0
- scipy/io/tests/data/null_pointer.sav +0 -0
- scipy/io/tests/data/scalar_byte.sav +0 -0
- scipy/io/tests/data/scalar_byte_descr.sav +0 -0
- scipy/io/tests/data/scalar_complex32.sav +0 -0
- scipy/io/tests/data/scalar_complex64.sav +0 -0
- scipy/io/tests/data/scalar_float32.sav +0 -0
- scipy/io/tests/data/scalar_float64.sav +0 -0
- scipy/io/tests/data/scalar_heap_pointer.sav +0 -0
- scipy/io/tests/data/scalar_int16.sav +0 -0
- scipy/io/tests/data/scalar_int32.sav +0 -0
- scipy/io/tests/data/scalar_int64.sav +0 -0
- scipy/io/tests/data/scalar_string.sav +0 -0
- scipy/io/tests/data/scalar_uint16.sav +0 -0
- scipy/io/tests/data/scalar_uint32.sav +0 -0
- scipy/io/tests/data/scalar_uint64.sav +0 -0
- scipy/io/tests/data/struct_arrays.sav +0 -0
- scipy/io/tests/data/struct_arrays_byte_idl80.sav +0 -0
- scipy/io/tests/data/struct_arrays_replicated.sav +0 -0
- scipy/io/tests/data/struct_arrays_replicated_3d.sav +0 -0
- scipy/io/tests/data/struct_inherit.sav +0 -0
- scipy/io/tests/data/struct_pointer_arrays.sav +0 -0
- scipy/io/tests/data/struct_pointer_arrays_replicated.sav +0 -0
- scipy/io/tests/data/struct_pointer_arrays_replicated_3d.sav +0 -0
- scipy/io/tests/data/struct_pointers.sav +0 -0
- scipy/io/tests/data/struct_pointers_replicated.sav +0 -0
- scipy/io/tests/data/struct_pointers_replicated_3d.sav +0 -0
- scipy/io/tests/data/struct_scalars.sav +0 -0
- scipy/io/tests/data/struct_scalars_replicated.sav +0 -0
- scipy/io/tests/data/struct_scalars_replicated_3d.sav +0 -0
- scipy/io/tests/data/test-1234Hz-le-1ch-10S-20bit-extra.wav +0 -0
- scipy/io/tests/data/test-44100Hz-2ch-32bit-float-be.wav +0 -0
- scipy/io/tests/data/test-44100Hz-2ch-32bit-float-le.wav +0 -0
- scipy/io/tests/data/test-44100Hz-be-1ch-4bytes.wav +0 -0
- scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof-no-data.wav +0 -0
- scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-early-eof.wav +0 -0
- scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-incomplete-chunk.wav +0 -0
- scipy/io/tests/data/test-44100Hz-le-1ch-4bytes-rf64.wav +0 -0
- scipy/io/tests/data/test-44100Hz-le-1ch-4bytes.wav +0 -0
- scipy/io/tests/data/test-48000Hz-2ch-64bit-float-le-wavex.wav +0 -0
- scipy/io/tests/data/test-8000Hz-be-3ch-5S-24bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-1ch-1byte-ulaw.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-2ch-1byteu.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-inconsistent.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit-rf64.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-24bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-36bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-45bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-53bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-3ch-5S-64bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-4ch-9S-12bit.wav +0 -0
- scipy/io/tests/data/test-8000Hz-le-5ch-9S-5bit.wav +0 -0
- scipy/io/tests/data/various_compressed.sav +0 -0
- scipy/io/tests/test_fortran.py +264 -0
- scipy/io/tests/test_idl.py +483 -0
- scipy/io/tests/test_mmio.py +831 -0
- scipy/io/tests/test_netcdf.py +550 -0
- scipy/io/tests/test_paths.py +93 -0
- scipy/io/tests/test_wavfile.py +501 -0
- scipy/io/wavfile.py +938 -0
- scipy/linalg/__init__.pxd +1 -0
- scipy/linalg/__init__.py +236 -0
- scipy/linalg/_basic.py +2146 -0
- scipy/linalg/_blas_subroutines.h +164 -0
- scipy/linalg/_cythonized_array_utils.cp312-win_arm64.lib +0 -0
- scipy/linalg/_cythonized_array_utils.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_cythonized_array_utils.pxd +40 -0
- scipy/linalg/_cythonized_array_utils.pyi +16 -0
- scipy/linalg/_decomp.py +1645 -0
- scipy/linalg/_decomp_cholesky.py +413 -0
- scipy/linalg/_decomp_cossin.py +236 -0
- scipy/linalg/_decomp_interpolative.cp312-win_arm64.lib +0 -0
- scipy/linalg/_decomp_interpolative.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +356 -0
- scipy/linalg/_decomp_lu.py +401 -0
- scipy/linalg/_decomp_lu_cython.cp312-win_arm64.lib +0 -0
- scipy/linalg/_decomp_lu_cython.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_decomp_lu_cython.pyi +6 -0
- scipy/linalg/_decomp_polar.py +113 -0
- scipy/linalg/_decomp_qr.py +494 -0
- scipy/linalg/_decomp_qz.py +452 -0
- scipy/linalg/_decomp_schur.py +336 -0
- scipy/linalg/_decomp_svd.py +545 -0
- scipy/linalg/_decomp_update.cp312-win_arm64.lib +0 -0
- scipy/linalg/_decomp_update.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +417 -0
- scipy/linalg/_fblas.cp312-win_arm64.lib +0 -0
- scipy/linalg/_fblas.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_flapack.cp312-win_arm64.lib +0 -0
- scipy/linalg/_flapack.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_lapack_subroutines.h +1521 -0
- scipy/linalg/_linalg_pythran.cp312-win_arm64.lib +0 -0
- scipy/linalg/_linalg_pythran.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs.py +1050 -0
- scipy/linalg/_matfuncs_expm.cp312-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_expm.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs_expm.pyi +6 -0
- scipy/linalg/_matfuncs_inv_ssq.py +886 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp312-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +107 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp312-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_misc.py +191 -0
- scipy/linalg/_procrustes.py +113 -0
- scipy/linalg/_sketches.py +189 -0
- scipy/linalg/_solve_toeplitz.cp312-win_arm64.lib +0 -0
- scipy/linalg/_solve_toeplitz.cp312-win_arm64.pyd +0 -0
- scipy/linalg/_solvers.py +862 -0
- scipy/linalg/_special_matrices.py +1322 -0
- scipy/linalg/_testutils.py +65 -0
- scipy/linalg/basic.py +23 -0
- scipy/linalg/blas.py +495 -0
- scipy/linalg/cython_blas.cp312-win_arm64.lib +0 -0
- scipy/linalg/cython_blas.cp312-win_arm64.pyd +0 -0
- scipy/linalg/cython_blas.pxd +169 -0
- scipy/linalg/cython_blas.pyx +1432 -0
- scipy/linalg/cython_lapack.cp312-win_arm64.lib +0 -0
- scipy/linalg/cython_lapack.cp312-win_arm64.pyd +0 -0
- scipy/linalg/cython_lapack.pxd +1528 -0
- scipy/linalg/cython_lapack.pyx +12045 -0
- scipy/linalg/decomp.py +23 -0
- scipy/linalg/decomp_cholesky.py +21 -0
- scipy/linalg/decomp_lu.py +21 -0
- scipy/linalg/decomp_qr.py +20 -0
- scipy/linalg/decomp_schur.py +21 -0
- scipy/linalg/decomp_svd.py +21 -0
- scipy/linalg/interpolative.py +989 -0
- scipy/linalg/lapack.py +1081 -0
- scipy/linalg/matfuncs.py +23 -0
- scipy/linalg/misc.py +21 -0
- scipy/linalg/special_matrices.py +22 -0
- scipy/linalg/tests/__init__.py +0 -0
- scipy/linalg/tests/_cython_examples/extending.pyx +23 -0
- scipy/linalg/tests/_cython_examples/meson.build +34 -0
- scipy/linalg/tests/data/carex_15_data.npz +0 -0
- scipy/linalg/tests/data/carex_18_data.npz +0 -0
- scipy/linalg/tests/data/carex_19_data.npz +0 -0
- scipy/linalg/tests/data/carex_20_data.npz +0 -0
- scipy/linalg/tests/data/carex_6_data.npz +0 -0
- scipy/linalg/tests/data/gendare_20170120_data.npz +0 -0
- scipy/linalg/tests/test_basic.py +2074 -0
- scipy/linalg/tests/test_batch.py +588 -0
- scipy/linalg/tests/test_blas.py +1127 -0
- scipy/linalg/tests/test_cython_blas.py +118 -0
- scipy/linalg/tests/test_cython_lapack.py +22 -0
- scipy/linalg/tests/test_cythonized_array_utils.py +130 -0
- scipy/linalg/tests/test_decomp.py +3189 -0
- scipy/linalg/tests/test_decomp_cholesky.py +268 -0
- scipy/linalg/tests/test_decomp_cossin.py +314 -0
- scipy/linalg/tests/test_decomp_ldl.py +137 -0
- scipy/linalg/tests/test_decomp_lu.py +308 -0
- scipy/linalg/tests/test_decomp_polar.py +110 -0
- scipy/linalg/tests/test_decomp_update.py +1701 -0
- scipy/linalg/tests/test_extending.py +46 -0
- scipy/linalg/tests/test_fblas.py +607 -0
- scipy/linalg/tests/test_interpolative.py +232 -0
- scipy/linalg/tests/test_lapack.py +3620 -0
- scipy/linalg/tests/test_matfuncs.py +1125 -0
- scipy/linalg/tests/test_matmul_toeplitz.py +136 -0
- scipy/linalg/tests/test_procrustes.py +214 -0
- scipy/linalg/tests/test_sketches.py +118 -0
- scipy/linalg/tests/test_solve_toeplitz.py +150 -0
- scipy/linalg/tests/test_solvers.py +844 -0
- scipy/linalg/tests/test_special_matrices.py +636 -0
- scipy/misc/__init__.py +6 -0
- scipy/misc/common.py +6 -0
- scipy/misc/doccer.py +6 -0
- scipy/ndimage/__init__.py +174 -0
- scipy/ndimage/_ctest.cp312-win_arm64.lib +0 -0
- scipy/ndimage/_ctest.cp312-win_arm64.pyd +0 -0
- scipy/ndimage/_cytest.cp312-win_arm64.lib +0 -0
- scipy/ndimage/_cytest.cp312-win_arm64.pyd +0 -0
- scipy/ndimage/_delegators.py +303 -0
- scipy/ndimage/_filters.py +2422 -0
- scipy/ndimage/_fourier.py +306 -0
- scipy/ndimage/_interpolation.py +1033 -0
- scipy/ndimage/_measurements.py +1689 -0
- scipy/ndimage/_morphology.py +2634 -0
- scipy/ndimage/_nd_image.cp312-win_arm64.lib +0 -0
- scipy/ndimage/_nd_image.cp312-win_arm64.pyd +0 -0
- scipy/ndimage/_ndimage_api.py +16 -0
- scipy/ndimage/_ni_docstrings.py +214 -0
- scipy/ndimage/_ni_label.cp312-win_arm64.lib +0 -0
- scipy/ndimage/_ni_label.cp312-win_arm64.pyd +0 -0
- scipy/ndimage/_ni_support.py +139 -0
- scipy/ndimage/_rank_filter_1d.cp312-win_arm64.lib +0 -0
- scipy/ndimage/_rank_filter_1d.cp312-win_arm64.pyd +0 -0
- scipy/ndimage/_support_alternative_backends.py +84 -0
- scipy/ndimage/filters.py +27 -0
- scipy/ndimage/fourier.py +21 -0
- scipy/ndimage/interpolation.py +22 -0
- scipy/ndimage/measurements.py +24 -0
- scipy/ndimage/morphology.py +27 -0
- scipy/ndimage/tests/__init__.py +12 -0
- scipy/ndimage/tests/data/label_inputs.txt +21 -0
- scipy/ndimage/tests/data/label_results.txt +294 -0
- scipy/ndimage/tests/data/label_strels.txt +42 -0
- scipy/ndimage/tests/dots.png +0 -0
- scipy/ndimage/tests/test_c_api.py +102 -0
- scipy/ndimage/tests/test_datatypes.py +67 -0
- scipy/ndimage/tests/test_filters.py +3083 -0
- scipy/ndimage/tests/test_fourier.py +187 -0
- scipy/ndimage/tests/test_interpolation.py +1491 -0
- scipy/ndimage/tests/test_measurements.py +1592 -0
- scipy/ndimage/tests/test_morphology.py +2950 -0
- scipy/ndimage/tests/test_ni_support.py +78 -0
- scipy/ndimage/tests/test_splines.py +70 -0
- scipy/odr/__init__.py +131 -0
- scipy/odr/__odrpack.cp312-win_arm64.lib +0 -0
- scipy/odr/__odrpack.cp312-win_arm64.pyd +0 -0
- scipy/odr/_add_newdocs.py +34 -0
- scipy/odr/_models.py +315 -0
- scipy/odr/_odrpack.py +1154 -0
- scipy/odr/models.py +20 -0
- scipy/odr/odrpack.py +21 -0
- scipy/odr/tests/__init__.py +0 -0
- scipy/odr/tests/test_odr.py +607 -0
- scipy/optimize/__init__.pxd +1 -0
- scipy/optimize/__init__.py +460 -0
- scipy/optimize/_basinhopping.py +741 -0
- scipy/optimize/_bglu_dense.cp312-win_arm64.lib +0 -0
- scipy/optimize/_bglu_dense.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_bracket.py +706 -0
- scipy/optimize/_chandrupatla.py +551 -0
- scipy/optimize/_cobyla_py.py +297 -0
- scipy/optimize/_cobyqa_py.py +72 -0
- scipy/optimize/_constraints.py +598 -0
- scipy/optimize/_dcsrch.py +728 -0
- scipy/optimize/_differentiable_functions.py +835 -0
- scipy/optimize/_differentialevolution.py +1970 -0
- scipy/optimize/_direct.cp312-win_arm64.lib +0 -0
- scipy/optimize/_direct.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_direct_py.py +280 -0
- scipy/optimize/_dual_annealing.py +732 -0
- scipy/optimize/_elementwise.py +798 -0
- scipy/optimize/_group_columns.cp312-win_arm64.lib +0 -0
- scipy/optimize/_group_columns.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_hessian_update_strategy.py +479 -0
- scipy/optimize/_highspy/__init__.py +0 -0
- scipy/optimize/_highspy/_core.cp312-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_core.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp312-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_highs_options.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_wrapper.py +338 -0
- scipy/optimize/_isotonic.py +157 -0
- scipy/optimize/_lbfgsb.cp312-win_arm64.lib +0 -0
- scipy/optimize/_lbfgsb.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_lbfgsb_py.py +634 -0
- scipy/optimize/_linesearch.py +896 -0
- scipy/optimize/_linprog.py +733 -0
- scipy/optimize/_linprog_doc.py +1434 -0
- scipy/optimize/_linprog_highs.py +422 -0
- scipy/optimize/_linprog_ip.py +1141 -0
- scipy/optimize/_linprog_rs.py +572 -0
- scipy/optimize/_linprog_simplex.py +663 -0
- scipy/optimize/_linprog_util.py +1521 -0
- scipy/optimize/_lsap.cp312-win_arm64.lib +0 -0
- scipy/optimize/_lsap.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_lsq/__init__.py +5 -0
- scipy/optimize/_lsq/bvls.py +183 -0
- scipy/optimize/_lsq/common.py +731 -0
- scipy/optimize/_lsq/dogbox.py +345 -0
- scipy/optimize/_lsq/givens_elimination.cp312-win_arm64.lib +0 -0
- scipy/optimize/_lsq/givens_elimination.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_lsq/least_squares.py +1044 -0
- scipy/optimize/_lsq/lsq_linear.py +361 -0
- scipy/optimize/_lsq/trf.py +587 -0
- scipy/optimize/_lsq/trf_linear.py +249 -0
- scipy/optimize/_milp.py +394 -0
- scipy/optimize/_minimize.py +1199 -0
- scipy/optimize/_minpack.cp312-win_arm64.lib +0 -0
- scipy/optimize/_minpack.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_minpack_py.py +1178 -0
- scipy/optimize/_moduleTNC.cp312-win_arm64.lib +0 -0
- scipy/optimize/_moduleTNC.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_nnls.py +96 -0
- scipy/optimize/_nonlin.py +1634 -0
- scipy/optimize/_numdiff.py +963 -0
- scipy/optimize/_optimize.py +4169 -0
- scipy/optimize/_pava_pybind.cp312-win_arm64.lib +0 -0
- scipy/optimize/_pava_pybind.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_qap.py +760 -0
- scipy/optimize/_remove_redundancy.py +522 -0
- scipy/optimize/_root.py +732 -0
- scipy/optimize/_root_scalar.py +538 -0
- scipy/optimize/_shgo.py +1606 -0
- scipy/optimize/_shgo_lib/__init__.py +0 -0
- scipy/optimize/_shgo_lib/_complex.py +1225 -0
- scipy/optimize/_shgo_lib/_vertex.py +460 -0
- scipy/optimize/_slsqp_py.py +603 -0
- scipy/optimize/_slsqplib.cp312-win_arm64.lib +0 -0
- scipy/optimize/_slsqplib.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_spectral.py +260 -0
- scipy/optimize/_tnc.py +438 -0
- scipy/optimize/_trlib/__init__.py +12 -0
- scipy/optimize/_trlib/_trlib.cp312-win_arm64.lib +0 -0
- scipy/optimize/_trlib/_trlib.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_trustregion.py +318 -0
- scipy/optimize/_trustregion_constr/__init__.py +6 -0
- scipy/optimize/_trustregion_constr/canonical_constraint.py +390 -0
- scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +231 -0
- scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +584 -0
- scipy/optimize/_trustregion_constr/projections.py +411 -0
- scipy/optimize/_trustregion_constr/qp_subproblem.py +637 -0
- scipy/optimize/_trustregion_constr/report.py +49 -0
- scipy/optimize/_trustregion_constr/tests/__init__.py +0 -0
- scipy/optimize/_trustregion_constr/tests/test_canonical_constraint.py +296 -0
- scipy/optimize/_trustregion_constr/tests/test_nested_minimize.py +39 -0
- scipy/optimize/_trustregion_constr/tests/test_projections.py +214 -0
- scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +645 -0
- scipy/optimize/_trustregion_constr/tests/test_report.py +34 -0
- scipy/optimize/_trustregion_constr/tr_interior_point.py +361 -0
- scipy/optimize/_trustregion_dogleg.py +122 -0
- scipy/optimize/_trustregion_exact.py +437 -0
- scipy/optimize/_trustregion_krylov.py +65 -0
- scipy/optimize/_trustregion_ncg.py +126 -0
- scipy/optimize/_tstutils.py +972 -0
- scipy/optimize/_zeros.cp312-win_arm64.lib +0 -0
- scipy/optimize/_zeros.cp312-win_arm64.pyd +0 -0
- scipy/optimize/_zeros_py.py +1475 -0
- scipy/optimize/cobyla.py +19 -0
- scipy/optimize/cython_optimize/__init__.py +133 -0
- scipy/optimize/cython_optimize/_zeros.cp312-win_arm64.lib +0 -0
- scipy/optimize/cython_optimize/_zeros.cp312-win_arm64.pyd +0 -0
- scipy/optimize/cython_optimize/_zeros.pxd +33 -0
- scipy/optimize/cython_optimize/c_zeros.pxd +26 -0
- scipy/optimize/cython_optimize.pxd +11 -0
- scipy/optimize/elementwise.py +38 -0
- scipy/optimize/lbfgsb.py +23 -0
- scipy/optimize/linesearch.py +18 -0
- scipy/optimize/minpack.py +27 -0
- scipy/optimize/minpack2.py +17 -0
- scipy/optimize/moduleTNC.py +19 -0
- scipy/optimize/nonlin.py +29 -0
- scipy/optimize/optimize.py +40 -0
- scipy/optimize/slsqp.py +22 -0
- scipy/optimize/tests/__init__.py +0 -0
- scipy/optimize/tests/_cython_examples/extending.pyx +43 -0
- scipy/optimize/tests/_cython_examples/meson.build +32 -0
- scipy/optimize/tests/test__basinhopping.py +535 -0
- scipy/optimize/tests/test__differential_evolution.py +1703 -0
- scipy/optimize/tests/test__dual_annealing.py +416 -0
- scipy/optimize/tests/test__linprog_clean_inputs.py +312 -0
- scipy/optimize/tests/test__numdiff.py +885 -0
- scipy/optimize/tests/test__remove_redundancy.py +228 -0
- scipy/optimize/tests/test__root.py +124 -0
- scipy/optimize/tests/test__shgo.py +1164 -0
- scipy/optimize/tests/test__spectral.py +226 -0
- scipy/optimize/tests/test_bracket.py +896 -0
- scipy/optimize/tests/test_chandrupatla.py +982 -0
- scipy/optimize/tests/test_cobyla.py +195 -0
- scipy/optimize/tests/test_cobyqa.py +252 -0
- scipy/optimize/tests/test_constraint_conversion.py +286 -0
- scipy/optimize/tests/test_constraints.py +255 -0
- scipy/optimize/tests/test_cython_optimize.py +92 -0
- scipy/optimize/tests/test_differentiable_functions.py +1025 -0
- scipy/optimize/tests/test_direct.py +321 -0
- scipy/optimize/tests/test_extending.py +28 -0
- scipy/optimize/tests/test_hessian_update_strategy.py +300 -0
- scipy/optimize/tests/test_isotonic_regression.py +167 -0
- scipy/optimize/tests/test_lbfgsb_hessinv.py +65 -0
- scipy/optimize/tests/test_lbfgsb_setulb.py +122 -0
- scipy/optimize/tests/test_least_squares.py +986 -0
- scipy/optimize/tests/test_linear_assignment.py +116 -0
- scipy/optimize/tests/test_linesearch.py +328 -0
- scipy/optimize/tests/test_linprog.py +2577 -0
- scipy/optimize/tests/test_lsq_common.py +297 -0
- scipy/optimize/tests/test_lsq_linear.py +287 -0
- scipy/optimize/tests/test_milp.py +459 -0
- scipy/optimize/tests/test_minimize_constrained.py +845 -0
- scipy/optimize/tests/test_minpack.py +1194 -0
- scipy/optimize/tests/test_nnls.py +469 -0
- scipy/optimize/tests/test_nonlin.py +572 -0
- scipy/optimize/tests/test_optimize.py +3344 -0
- scipy/optimize/tests/test_quadratic_assignment.py +455 -0
- scipy/optimize/tests/test_regression.py +40 -0
- scipy/optimize/tests/test_slsqp.py +645 -0
- scipy/optimize/tests/test_tnc.py +345 -0
- scipy/optimize/tests/test_trustregion.py +110 -0
- scipy/optimize/tests/test_trustregion_exact.py +351 -0
- scipy/optimize/tests/test_trustregion_krylov.py +170 -0
- scipy/optimize/tests/test_zeros.py +998 -0
- scipy/optimize/tnc.py +22 -0
- scipy/optimize/zeros.py +26 -0
- scipy/signal/__init__.py +316 -0
- scipy/signal/_arraytools.py +264 -0
- scipy/signal/_czt.py +575 -0
- scipy/signal/_delegators.py +568 -0
- scipy/signal/_filter_design.py +5893 -0
- scipy/signal/_fir_filter_design.py +1458 -0
- scipy/signal/_lti_conversion.py +534 -0
- scipy/signal/_ltisys.py +3546 -0
- scipy/signal/_max_len_seq.py +139 -0
- scipy/signal/_max_len_seq_inner.cp312-win_arm64.lib +0 -0
- scipy/signal/_max_len_seq_inner.cp312-win_arm64.pyd +0 -0
- scipy/signal/_peak_finding.py +1310 -0
- scipy/signal/_peak_finding_utils.cp312-win_arm64.lib +0 -0
- scipy/signal/_peak_finding_utils.cp312-win_arm64.pyd +0 -0
- scipy/signal/_polyutils.py +172 -0
- scipy/signal/_savitzky_golay.py +357 -0
- scipy/signal/_short_time_fft.py +2228 -0
- scipy/signal/_signal_api.py +30 -0
- scipy/signal/_signaltools.py +5309 -0
- scipy/signal/_sigtools.cp312-win_arm64.lib +0 -0
- scipy/signal/_sigtools.cp312-win_arm64.pyd +0 -0
- scipy/signal/_sosfilt.cp312-win_arm64.lib +0 -0
- scipy/signal/_sosfilt.cp312-win_arm64.pyd +0 -0
- scipy/signal/_spectral_py.py +2471 -0
- scipy/signal/_spline.cp312-win_arm64.lib +0 -0
- scipy/signal/_spline.cp312-win_arm64.pyd +0 -0
- scipy/signal/_spline.pyi +34 -0
- scipy/signal/_spline_filters.py +848 -0
- scipy/signal/_support_alternative_backends.py +73 -0
- scipy/signal/_upfirdn.py +219 -0
- scipy/signal/_upfirdn_apply.cp312-win_arm64.lib +0 -0
- scipy/signal/_upfirdn_apply.cp312-win_arm64.pyd +0 -0
- scipy/signal/_waveforms.py +687 -0
- scipy/signal/_wavelets.py +29 -0
- scipy/signal/bsplines.py +21 -0
- scipy/signal/filter_design.py +28 -0
- scipy/signal/fir_filter_design.py +21 -0
- scipy/signal/lti_conversion.py +20 -0
- scipy/signal/ltisys.py +25 -0
- scipy/signal/signaltools.py +27 -0
- scipy/signal/spectral.py +21 -0
- scipy/signal/spline.py +18 -0
- scipy/signal/tests/__init__.py +0 -0
- scipy/signal/tests/_scipy_spectral_test_shim.py +311 -0
- scipy/signal/tests/mpsig.py +122 -0
- scipy/signal/tests/test_array_tools.py +111 -0
- scipy/signal/tests/test_bsplines.py +365 -0
- scipy/signal/tests/test_cont2discrete.py +424 -0
- scipy/signal/tests/test_czt.py +221 -0
- scipy/signal/tests/test_dltisys.py +599 -0
- scipy/signal/tests/test_filter_design.py +4744 -0
- scipy/signal/tests/test_fir_filter_design.py +851 -0
- scipy/signal/tests/test_ltisys.py +1225 -0
- scipy/signal/tests/test_max_len_seq.py +71 -0
- scipy/signal/tests/test_peak_finding.py +915 -0
- scipy/signal/tests/test_result_type.py +51 -0
- scipy/signal/tests/test_savitzky_golay.py +363 -0
- scipy/signal/tests/test_short_time_fft.py +1107 -0
- scipy/signal/tests/test_signaltools.py +4735 -0
- scipy/signal/tests/test_spectral.py +2141 -0
- scipy/signal/tests/test_splines.py +427 -0
- scipy/signal/tests/test_upfirdn.py +322 -0
- scipy/signal/tests/test_waveforms.py +400 -0
- scipy/signal/tests/test_wavelets.py +59 -0
- scipy/signal/tests/test_windows.py +987 -0
- scipy/signal/waveforms.py +20 -0
- scipy/signal/wavelets.py +17 -0
- scipy/signal/windows/__init__.py +52 -0
- scipy/signal/windows/_windows.py +2513 -0
- scipy/signal/windows/windows.py +23 -0
- scipy/sparse/__init__.py +350 -0
- scipy/sparse/_base.py +1613 -0
- scipy/sparse/_bsr.py +880 -0
- scipy/sparse/_compressed.py +1328 -0
- scipy/sparse/_construct.py +1454 -0
- scipy/sparse/_coo.py +1581 -0
- scipy/sparse/_csc.py +367 -0
- scipy/sparse/_csparsetools.cp312-win_arm64.lib +0 -0
- scipy/sparse/_csparsetools.cp312-win_arm64.pyd +0 -0
- scipy/sparse/_csr.py +558 -0
- scipy/sparse/_data.py +569 -0
- scipy/sparse/_dia.py +677 -0
- scipy/sparse/_dok.py +669 -0
- scipy/sparse/_extract.py +178 -0
- scipy/sparse/_index.py +444 -0
- scipy/sparse/_lil.py +632 -0
- scipy/sparse/_matrix.py +169 -0
- scipy/sparse/_matrix_io.py +167 -0
- scipy/sparse/_sparsetools.cp312-win_arm64.lib +0 -0
- scipy/sparse/_sparsetools.cp312-win_arm64.pyd +0 -0
- scipy/sparse/_spfuncs.py +76 -0
- scipy/sparse/_sputils.py +632 -0
- scipy/sparse/base.py +24 -0
- scipy/sparse/bsr.py +22 -0
- scipy/sparse/compressed.py +20 -0
- scipy/sparse/construct.py +38 -0
- scipy/sparse/coo.py +23 -0
- scipy/sparse/csc.py +22 -0
- scipy/sparse/csgraph/__init__.py +210 -0
- scipy/sparse/csgraph/_flow.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_flow.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_laplacian.py +563 -0
- scipy/sparse/csgraph/_matching.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_matching.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_reordering.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_shortest_path.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_tools.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp312-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_traversal.cp312-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_validation.py +66 -0
- scipy/sparse/csgraph/tests/__init__.py +0 -0
- scipy/sparse/csgraph/tests/test_connected_components.py +119 -0
- scipy/sparse/csgraph/tests/test_conversions.py +61 -0
- scipy/sparse/csgraph/tests/test_flow.py +209 -0
- scipy/sparse/csgraph/tests/test_graph_laplacian.py +368 -0
- scipy/sparse/csgraph/tests/test_matching.py +307 -0
- scipy/sparse/csgraph/tests/test_pydata_sparse.py +197 -0
- scipy/sparse/csgraph/tests/test_reordering.py +70 -0
- scipy/sparse/csgraph/tests/test_shortest_path.py +540 -0
- scipy/sparse/csgraph/tests/test_spanning_tree.py +66 -0
- scipy/sparse/csgraph/tests/test_traversal.py +148 -0
- scipy/sparse/csr.py +22 -0
- scipy/sparse/data.py +18 -0
- scipy/sparse/dia.py +22 -0
- scipy/sparse/dok.py +22 -0
- scipy/sparse/extract.py +23 -0
- scipy/sparse/lil.py +22 -0
- scipy/sparse/linalg/__init__.py +148 -0
- scipy/sparse/linalg/_dsolve/__init__.py +71 -0
- scipy/sparse/linalg/_dsolve/_add_newdocs.py +147 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_dsolve/linsolve.py +882 -0
- scipy/sparse/linalg/_dsolve/tests/__init__.py +0 -0
- scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +928 -0
- scipy/sparse/linalg/_eigen/__init__.py +22 -0
- scipy/sparse/linalg/_eigen/_svds.py +540 -0
- scipy/sparse/linalg/_eigen/_svds_doc.py +382 -0
- scipy/sparse/linalg/_eigen/arpack/COPYING +45 -0
- scipy/sparse/linalg/_eigen/arpack/__init__.py +20 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_eigen/arpack/arpack.py +1706 -0
- scipy/sparse/linalg/_eigen/arpack/tests/__init__.py +0 -0
- scipy/sparse/linalg/_eigen/arpack/tests/test_arpack.py +717 -0
- scipy/sparse/linalg/_eigen/lobpcg/__init__.py +16 -0
- scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +1110 -0
- scipy/sparse/linalg/_eigen/lobpcg/tests/__init__.py +0 -0
- scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py +725 -0
- scipy/sparse/linalg/_eigen/tests/__init__.py +0 -0
- scipy/sparse/linalg/_eigen/tests/test_svds.py +886 -0
- scipy/sparse/linalg/_expm_multiply.py +816 -0
- scipy/sparse/linalg/_interface.py +920 -0
- scipy/sparse/linalg/_isolve/__init__.py +20 -0
- scipy/sparse/linalg/_isolve/_gcrotmk.py +503 -0
- scipy/sparse/linalg/_isolve/iterative.py +1051 -0
- scipy/sparse/linalg/_isolve/lgmres.py +230 -0
- scipy/sparse/linalg/_isolve/lsmr.py +486 -0
- scipy/sparse/linalg/_isolve/lsqr.py +589 -0
- scipy/sparse/linalg/_isolve/minres.py +372 -0
- scipy/sparse/linalg/_isolve/tests/__init__.py +0 -0
- scipy/sparse/linalg/_isolve/tests/test_gcrotmk.py +183 -0
- scipy/sparse/linalg/_isolve/tests/test_iterative.py +809 -0
- scipy/sparse/linalg/_isolve/tests/test_lgmres.py +225 -0
- scipy/sparse/linalg/_isolve/tests/test_lsmr.py +185 -0
- scipy/sparse/linalg/_isolve/tests/test_lsqr.py +120 -0
- scipy/sparse/linalg/_isolve/tests/test_minres.py +97 -0
- scipy/sparse/linalg/_isolve/tests/test_utils.py +9 -0
- scipy/sparse/linalg/_isolve/tfqmr.py +179 -0
- scipy/sparse/linalg/_isolve/utils.py +121 -0
- scipy/sparse/linalg/_matfuncs.py +940 -0
- scipy/sparse/linalg/_norm.py +195 -0
- scipy/sparse/linalg/_onenormest.py +467 -0
- scipy/sparse/linalg/_propack/_cpropack.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp312-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp312-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_special_sparse_arrays.py +949 -0
- scipy/sparse/linalg/_svdp.py +309 -0
- scipy/sparse/linalg/dsolve.py +22 -0
- scipy/sparse/linalg/eigen.py +21 -0
- scipy/sparse/linalg/interface.py +20 -0
- scipy/sparse/linalg/isolve.py +22 -0
- scipy/sparse/linalg/matfuncs.py +18 -0
- scipy/sparse/linalg/tests/__init__.py +0 -0
- scipy/sparse/linalg/tests/propack_test_data.npz +0 -0
- scipy/sparse/linalg/tests/test_expm_multiply.py +367 -0
- scipy/sparse/linalg/tests/test_interface.py +561 -0
- scipy/sparse/linalg/tests/test_matfuncs.py +592 -0
- scipy/sparse/linalg/tests/test_norm.py +154 -0
- scipy/sparse/linalg/tests/test_onenormest.py +252 -0
- scipy/sparse/linalg/tests/test_propack.py +165 -0
- scipy/sparse/linalg/tests/test_pydata_sparse.py +272 -0
- scipy/sparse/linalg/tests/test_special_sparse_arrays.py +337 -0
- scipy/sparse/sparsetools.py +17 -0
- scipy/sparse/spfuncs.py +17 -0
- scipy/sparse/sputils.py +17 -0
- scipy/sparse/tests/__init__.py +0 -0
- scipy/sparse/tests/data/csc_py2.npz +0 -0
- scipy/sparse/tests/data/csc_py3.npz +0 -0
- scipy/sparse/tests/test_arithmetic1d.py +341 -0
- scipy/sparse/tests/test_array_api.py +561 -0
- scipy/sparse/tests/test_base.py +5870 -0
- scipy/sparse/tests/test_common1d.py +447 -0
- scipy/sparse/tests/test_construct.py +872 -0
- scipy/sparse/tests/test_coo.py +1119 -0
- scipy/sparse/tests/test_csc.py +98 -0
- scipy/sparse/tests/test_csr.py +214 -0
- scipy/sparse/tests/test_dok.py +209 -0
- scipy/sparse/tests/test_extract.py +51 -0
- scipy/sparse/tests/test_indexing1d.py +603 -0
- scipy/sparse/tests/test_matrix_io.py +109 -0
- scipy/sparse/tests/test_minmax1d.py +128 -0
- scipy/sparse/tests/test_sparsetools.py +344 -0
- scipy/sparse/tests/test_spfuncs.py +97 -0
- scipy/sparse/tests/test_sputils.py +424 -0
- scipy/spatial/__init__.py +129 -0
- scipy/spatial/_ckdtree.cp312-win_arm64.lib +0 -0
- scipy/spatial/_ckdtree.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp312-win_arm64.lib +0 -0
- scipy/spatial/_distance_pybind.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp312-win_arm64.lib +0 -0
- scipy/spatial/_distance_wrap.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_geometric_slerp.py +238 -0
- scipy/spatial/_hausdorff.cp312-win_arm64.lib +0 -0
- scipy/spatial/_hausdorff.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_kdtree.py +920 -0
- scipy/spatial/_plotutils.py +274 -0
- scipy/spatial/_procrustes.py +132 -0
- scipy/spatial/_qhull.cp312-win_arm64.lib +0 -0
- scipy/spatial/_qhull.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_qhull.pyi +213 -0
- scipy/spatial/_spherical_voronoi.py +341 -0
- scipy/spatial/_voronoi.cp312-win_arm64.lib +0 -0
- scipy/spatial/_voronoi.cp312-win_arm64.pyd +0 -0
- scipy/spatial/_voronoi.pyi +4 -0
- scipy/spatial/ckdtree.py +18 -0
- scipy/spatial/distance.py +3147 -0
- scipy/spatial/distance.pyi +210 -0
- scipy/spatial/kdtree.py +25 -0
- scipy/spatial/qhull.py +25 -0
- scipy/spatial/qhull_src/COPYING_QHULL.txt +39 -0
- scipy/spatial/tests/__init__.py +0 -0
- scipy/spatial/tests/data/cdist-X1.txt +10 -0
- scipy/spatial/tests/data/cdist-X2.txt +20 -0
- scipy/spatial/tests/data/degenerate_pointset.npz +0 -0
- scipy/spatial/tests/data/iris.txt +150 -0
- scipy/spatial/tests/data/pdist-boolean-inp.txt +20 -0
- scipy/spatial/tests/data/pdist-chebyshev-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-chebyshev-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-cityblock-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-cityblock-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-correlation-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-correlation-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-cosine-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-cosine-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-double-inp.txt +20 -0
- scipy/spatial/tests/data/pdist-euclidean-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-euclidean-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-hamming-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-jaccard-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-jensenshannon-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-jensenshannon-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-minkowski-3.2-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-minkowski-3.2-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-minkowski-5.8-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-seuclidean-ml-iris.txt +1 -0
- scipy/spatial/tests/data/pdist-seuclidean-ml.txt +1 -0
- scipy/spatial/tests/data/pdist-spearman-ml.txt +1 -0
- scipy/spatial/tests/data/random-bool-data.txt +100 -0
- scipy/spatial/tests/data/random-double-data.txt +100 -0
- scipy/spatial/tests/data/random-int-data.txt +100 -0
- scipy/spatial/tests/data/random-uint-data.txt +100 -0
- scipy/spatial/tests/data/selfdual-4d-polytope.txt +27 -0
- scipy/spatial/tests/test__plotutils.py +91 -0
- scipy/spatial/tests/test__procrustes.py +116 -0
- scipy/spatial/tests/test_distance.py +2389 -0
- scipy/spatial/tests/test_hausdorff.py +199 -0
- scipy/spatial/tests/test_kdtree.py +1536 -0
- scipy/spatial/tests/test_qhull.py +1313 -0
- scipy/spatial/tests/test_slerp.py +417 -0
- scipy/spatial/tests/test_spherical_voronoi.py +358 -0
- scipy/spatial/transform/__init__.py +31 -0
- scipy/spatial/transform/_rigid_transform.cp312-win_arm64.lib +0 -0
- scipy/spatial/transform/_rigid_transform.cp312-win_arm64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp312-win_arm64.lib +0 -0
- scipy/spatial/transform/_rotation.cp312-win_arm64.pyd +0 -0
- scipy/spatial/transform/_rotation_groups.py +140 -0
- scipy/spatial/transform/_rotation_spline.py +460 -0
- scipy/spatial/transform/rotation.py +21 -0
- scipy/spatial/transform/tests/__init__.py +0 -0
- scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
- scipy/spatial/transform/tests/test_rotation.py +2569 -0
- scipy/spatial/transform/tests/test_rotation_groups.py +169 -0
- scipy/spatial/transform/tests/test_rotation_spline.py +183 -0
- scipy/special/__init__.pxd +1 -0
- scipy/special/__init__.py +841 -0
- scipy/special/_add_newdocs.py +9961 -0
- scipy/special/_basic.py +3576 -0
- scipy/special/_comb.cp312-win_arm64.lib +0 -0
- scipy/special/_comb.cp312-win_arm64.pyd +0 -0
- scipy/special/_ellip_harm.py +214 -0
- scipy/special/_ellip_harm_2.cp312-win_arm64.lib +0 -0
- scipy/special/_ellip_harm_2.cp312-win_arm64.pyd +0 -0
- scipy/special/_gufuncs.cp312-win_arm64.lib +0 -0
- scipy/special/_gufuncs.cp312-win_arm64.pyd +0 -0
- scipy/special/_input_validation.py +17 -0
- scipy/special/_lambertw.py +149 -0
- scipy/special/_logsumexp.py +426 -0
- scipy/special/_mptestutils.py +453 -0
- scipy/special/_multiufuncs.py +610 -0
- scipy/special/_orthogonal.py +2592 -0
- scipy/special/_orthogonal.pyi +330 -0
- scipy/special/_precompute/__init__.py +0 -0
- scipy/special/_precompute/cosine_cdf.py +17 -0
- scipy/special/_precompute/expn_asy.py +54 -0
- scipy/special/_precompute/gammainc_asy.py +116 -0
- scipy/special/_precompute/gammainc_data.py +124 -0
- scipy/special/_precompute/hyp2f1_data.py +484 -0
- scipy/special/_precompute/lambertw.py +68 -0
- scipy/special/_precompute/loggamma.py +43 -0
- scipy/special/_precompute/struve_convergence.py +131 -0
- scipy/special/_precompute/utils.py +38 -0
- scipy/special/_precompute/wright_bessel.py +342 -0
- scipy/special/_precompute/wright_bessel_data.py +152 -0
- scipy/special/_precompute/wrightomega.py +41 -0
- scipy/special/_precompute/zetac.py +27 -0
- scipy/special/_sf_error.py +15 -0
- scipy/special/_specfun.cp312-win_arm64.lib +0 -0
- scipy/special/_specfun.cp312-win_arm64.pyd +0 -0
- scipy/special/_special_ufuncs.cp312-win_arm64.lib +0 -0
- scipy/special/_special_ufuncs.cp312-win_arm64.pyd +0 -0
- scipy/special/_spfun_stats.py +106 -0
- scipy/special/_spherical_bessel.py +397 -0
- scipy/special/_support_alternative_backends.py +295 -0
- scipy/special/_test_internal.cp312-win_arm64.lib +0 -0
- scipy/special/_test_internal.cp312-win_arm64.pyd +0 -0
- scipy/special/_test_internal.pyi +9 -0
- scipy/special/_testutils.py +321 -0
- scipy/special/_ufuncs.cp312-win_arm64.lib +0 -0
- scipy/special/_ufuncs.cp312-win_arm64.pyd +0 -0
- scipy/special/_ufuncs.pyi +522 -0
- scipy/special/_ufuncs.pyx +13173 -0
- scipy/special/_ufuncs_cxx.cp312-win_arm64.lib +0 -0
- scipy/special/_ufuncs_cxx.cp312-win_arm64.pyd +0 -0
- scipy/special/_ufuncs_cxx.pxd +142 -0
- scipy/special/_ufuncs_cxx.pyx +427 -0
- scipy/special/_ufuncs_cxx_defs.h +147 -0
- scipy/special/_ufuncs_defs.h +57 -0
- scipy/special/add_newdocs.py +15 -0
- scipy/special/basic.py +87 -0
- scipy/special/cython_special.cp312-win_arm64.lib +0 -0
- scipy/special/cython_special.cp312-win_arm64.pyd +0 -0
- scipy/special/cython_special.pxd +259 -0
- scipy/special/cython_special.pyi +3 -0
- scipy/special/orthogonal.py +45 -0
- scipy/special/sf_error.py +20 -0
- scipy/special/specfun.py +24 -0
- scipy/special/spfun_stats.py +17 -0
- scipy/special/tests/__init__.py +0 -0
- scipy/special/tests/_cython_examples/extending.pyx +12 -0
- scipy/special/tests/_cython_examples/meson.build +34 -0
- scipy/special/tests/data/__init__.py +0 -0
- scipy/special/tests/data/boost.npz +0 -0
- scipy/special/tests/data/gsl.npz +0 -0
- scipy/special/tests/data/local.npz +0 -0
- scipy/special/tests/test_basic.py +4815 -0
- scipy/special/tests/test_bdtr.py +112 -0
- scipy/special/tests/test_boost_ufuncs.py +64 -0
- scipy/special/tests/test_boxcox.py +125 -0
- scipy/special/tests/test_cdflib.py +712 -0
- scipy/special/tests/test_cdft_asymptotic.py +49 -0
- scipy/special/tests/test_cephes_intp_cast.py +29 -0
- scipy/special/tests/test_cosine_distr.py +83 -0
- scipy/special/tests/test_cython_special.py +363 -0
- scipy/special/tests/test_data.py +719 -0
- scipy/special/tests/test_dd.py +42 -0
- scipy/special/tests/test_digamma.py +45 -0
- scipy/special/tests/test_ellip_harm.py +278 -0
- scipy/special/tests/test_erfinv.py +89 -0
- scipy/special/tests/test_exponential_integrals.py +118 -0
- scipy/special/tests/test_extending.py +28 -0
- scipy/special/tests/test_faddeeva.py +85 -0
- scipy/special/tests/test_gamma.py +12 -0
- scipy/special/tests/test_gammainc.py +152 -0
- scipy/special/tests/test_hyp2f1.py +2566 -0
- scipy/special/tests/test_hypergeometric.py +234 -0
- scipy/special/tests/test_iv_ratio.py +249 -0
- scipy/special/tests/test_kolmogorov.py +491 -0
- scipy/special/tests/test_lambertw.py +109 -0
- scipy/special/tests/test_legendre.py +1518 -0
- scipy/special/tests/test_log1mexp.py +85 -0
- scipy/special/tests/test_loggamma.py +70 -0
- scipy/special/tests/test_logit.py +162 -0
- scipy/special/tests/test_logsumexp.py +469 -0
- scipy/special/tests/test_mpmath.py +2293 -0
- scipy/special/tests/test_nan_inputs.py +65 -0
- scipy/special/tests/test_ndtr.py +77 -0
- scipy/special/tests/test_ndtri_exp.py +94 -0
- scipy/special/tests/test_orthogonal.py +821 -0
- scipy/special/tests/test_orthogonal_eval.py +275 -0
- scipy/special/tests/test_owens_t.py +53 -0
- scipy/special/tests/test_pcf.py +24 -0
- scipy/special/tests/test_pdtr.py +48 -0
- scipy/special/tests/test_powm1.py +65 -0
- scipy/special/tests/test_precompute_expn_asy.py +24 -0
- scipy/special/tests/test_precompute_gammainc.py +108 -0
- scipy/special/tests/test_precompute_utils.py +36 -0
- scipy/special/tests/test_round.py +18 -0
- scipy/special/tests/test_sf_error.py +146 -0
- scipy/special/tests/test_sici.py +36 -0
- scipy/special/tests/test_specfun.py +48 -0
- scipy/special/tests/test_spence.py +32 -0
- scipy/special/tests/test_spfun_stats.py +61 -0
- scipy/special/tests/test_sph_harm.py +85 -0
- scipy/special/tests/test_spherical_bessel.py +400 -0
- scipy/special/tests/test_support_alternative_backends.py +248 -0
- scipy/special/tests/test_trig.py +72 -0
- scipy/special/tests/test_ufunc_signatures.py +46 -0
- scipy/special/tests/test_wright_bessel.py +205 -0
- scipy/special/tests/test_wrightomega.py +117 -0
- scipy/special/tests/test_zeta.py +301 -0
- scipy/stats/__init__.py +670 -0
- scipy/stats/_ansari_swilk_statistics.cp312-win_arm64.lib +0 -0
- scipy/stats/_ansari_swilk_statistics.cp312-win_arm64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +692 -0
- scipy/stats/_biasedurn.cp312-win_arm64.lib +0 -0
- scipy/stats/_biasedurn.cp312-win_arm64.pyd +0 -0
- scipy/stats/_biasedurn.pxd +27 -0
- scipy/stats/_binned_statistic.py +795 -0
- scipy/stats/_binomtest.py +375 -0
- scipy/stats/_bws_test.py +177 -0
- scipy/stats/_censored_data.py +459 -0
- scipy/stats/_common.py +5 -0
- scipy/stats/_constants.py +42 -0
- scipy/stats/_continued_fraction.py +387 -0
- scipy/stats/_continuous_distns.py +12486 -0
- scipy/stats/_correlation.py +210 -0
- scipy/stats/_covariance.py +636 -0
- scipy/stats/_crosstab.py +204 -0
- scipy/stats/_discrete_distns.py +2098 -0
- scipy/stats/_distn_infrastructure.py +4201 -0
- scipy/stats/_distr_params.py +299 -0
- scipy/stats/_distribution_infrastructure.py +5750 -0
- scipy/stats/_entropy.py +428 -0
- scipy/stats/_finite_differences.py +145 -0
- scipy/stats/_fit.py +1351 -0
- scipy/stats/_hypotests.py +2060 -0
- scipy/stats/_kde.py +732 -0
- scipy/stats/_ksstats.py +600 -0
- scipy/stats/_levy_stable/__init__.py +1231 -0
- scipy/stats/_levy_stable/levyst.cp312-win_arm64.lib +0 -0
- scipy/stats/_levy_stable/levyst.cp312-win_arm64.pyd +0 -0
- scipy/stats/_mannwhitneyu.py +492 -0
- scipy/stats/_mgc.py +550 -0
- scipy/stats/_morestats.py +4626 -0
- scipy/stats/_mstats_basic.py +3658 -0
- scipy/stats/_mstats_extras.py +521 -0
- scipy/stats/_multicomp.py +449 -0
- scipy/stats/_multivariate.py +7281 -0
- scipy/stats/_new_distributions.py +452 -0
- scipy/stats/_odds_ratio.py +466 -0
- scipy/stats/_page_trend_test.py +486 -0
- scipy/stats/_probability_distribution.py +1964 -0
- scipy/stats/_qmc.py +2956 -0
- scipy/stats/_qmc_cy.cp312-win_arm64.lib +0 -0
- scipy/stats/_qmc_cy.cp312-win_arm64.pyd +0 -0
- scipy/stats/_qmc_cy.pyi +54 -0
- scipy/stats/_qmvnt.py +454 -0
- scipy/stats/_qmvnt_cy.cp312-win_arm64.lib +0 -0
- scipy/stats/_qmvnt_cy.cp312-win_arm64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/__init__.py +4 -0
- scipy/stats/_rcont/rcont.cp312-win_arm64.lib +0 -0
- scipy/stats/_rcont/rcont.cp312-win_arm64.pyd +0 -0
- scipy/stats/_relative_risk.py +263 -0
- scipy/stats/_resampling.py +2352 -0
- scipy/stats/_result_classes.py +40 -0
- scipy/stats/_sampling.py +1314 -0
- scipy/stats/_sensitivity_analysis.py +713 -0
- scipy/stats/_sobol.cp312-win_arm64.lib +0 -0
- scipy/stats/_sobol.cp312-win_arm64.pyd +0 -0
- scipy/stats/_sobol.pyi +54 -0
- scipy/stats/_sobol_direction_numbers.npz +0 -0
- scipy/stats/_stats.cp312-win_arm64.lib +0 -0
- scipy/stats/_stats.cp312-win_arm64.pyd +0 -0
- scipy/stats/_stats.pxd +10 -0
- scipy/stats/_stats_mstats_common.py +322 -0
- scipy/stats/_stats_py.py +11089 -0
- scipy/stats/_stats_pythran.cp312-win_arm64.lib +0 -0
- scipy/stats/_stats_pythran.cp312-win_arm64.pyd +0 -0
- scipy/stats/_survival.py +683 -0
- scipy/stats/_tukeylambda_stats.py +199 -0
- scipy/stats/_unuran/__init__.py +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp312-win_arm64.lib +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp312-win_arm64.pyd +0 -0
- scipy/stats/_unuran/unuran_wrapper.pyi +179 -0
- scipy/stats/_variation.py +126 -0
- scipy/stats/_warnings_errors.py +38 -0
- scipy/stats/_wilcoxon.py +265 -0
- scipy/stats/biasedurn.py +16 -0
- scipy/stats/contingency.py +521 -0
- scipy/stats/distributions.py +24 -0
- scipy/stats/kde.py +18 -0
- scipy/stats/morestats.py +27 -0
- scipy/stats/mstats.py +140 -0
- scipy/stats/mstats_basic.py +42 -0
- scipy/stats/mstats_extras.py +25 -0
- scipy/stats/mvn.py +17 -0
- scipy/stats/qmc.py +236 -0
- scipy/stats/sampling.py +73 -0
- scipy/stats/stats.py +41 -0
- scipy/stats/tests/__init__.py +0 -0
- scipy/stats/tests/common_tests.py +356 -0
- scipy/stats/tests/data/_mvt.py +171 -0
- scipy/stats/tests/data/fisher_exact_results_from_r.py +607 -0
- scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy +0 -0
- scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy +0 -0
- scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy +0 -0
- scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy +0 -0
- scipy/stats/tests/data/nist_anova/AtmWtAg.dat +108 -0
- scipy/stats/tests/data/nist_anova/SiRstv.dat +85 -0
- scipy/stats/tests/data/nist_anova/SmLs01.dat +249 -0
- scipy/stats/tests/data/nist_anova/SmLs02.dat +1869 -0
- scipy/stats/tests/data/nist_anova/SmLs03.dat +18069 -0
- scipy/stats/tests/data/nist_anova/SmLs04.dat +249 -0
- scipy/stats/tests/data/nist_anova/SmLs05.dat +1869 -0
- scipy/stats/tests/data/nist_anova/SmLs06.dat +18069 -0
- scipy/stats/tests/data/nist_anova/SmLs07.dat +249 -0
- scipy/stats/tests/data/nist_anova/SmLs08.dat +1869 -0
- scipy/stats/tests/data/nist_anova/SmLs09.dat +18069 -0
- scipy/stats/tests/data/nist_linregress/Norris.dat +97 -0
- scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy +0 -0
- scipy/stats/tests/data/studentized_range_mpmath_ref.json +1499 -0
- scipy/stats/tests/test_axis_nan_policy.py +1388 -0
- scipy/stats/tests/test_binned_statistic.py +568 -0
- scipy/stats/tests/test_censored_data.py +152 -0
- scipy/stats/tests/test_contingency.py +294 -0
- scipy/stats/tests/test_continued_fraction.py +173 -0
- scipy/stats/tests/test_continuous.py +2198 -0
- scipy/stats/tests/test_continuous_basic.py +1053 -0
- scipy/stats/tests/test_continuous_fit_censored.py +683 -0
- scipy/stats/tests/test_correlation.py +80 -0
- scipy/stats/tests/test_crosstab.py +115 -0
- scipy/stats/tests/test_discrete_basic.py +580 -0
- scipy/stats/tests/test_discrete_distns.py +700 -0
- scipy/stats/tests/test_distributions.py +10413 -0
- scipy/stats/tests/test_entropy.py +322 -0
- scipy/stats/tests/test_fast_gen_inversion.py +435 -0
- scipy/stats/tests/test_fit.py +1090 -0
- scipy/stats/tests/test_hypotests.py +1991 -0
- scipy/stats/tests/test_kdeoth.py +676 -0
- scipy/stats/tests/test_marray.py +289 -0
- scipy/stats/tests/test_mgc.py +217 -0
- scipy/stats/tests/test_morestats.py +3259 -0
- scipy/stats/tests/test_mstats_basic.py +2071 -0
- scipy/stats/tests/test_mstats_extras.py +172 -0
- scipy/stats/tests/test_multicomp.py +405 -0
- scipy/stats/tests/test_multivariate.py +4381 -0
- scipy/stats/tests/test_odds_ratio.py +148 -0
- scipy/stats/tests/test_qmc.py +1492 -0
- scipy/stats/tests/test_quantile.py +199 -0
- scipy/stats/tests/test_rank.py +345 -0
- scipy/stats/tests/test_relative_risk.py +95 -0
- scipy/stats/tests/test_resampling.py +2000 -0
- scipy/stats/tests/test_sampling.py +1450 -0
- scipy/stats/tests/test_sensitivity_analysis.py +310 -0
- scipy/stats/tests/test_stats.py +9707 -0
- scipy/stats/tests/test_survival.py +466 -0
- scipy/stats/tests/test_tukeylambda_stats.py +85 -0
- scipy/stats/tests/test_variation.py +216 -0
- scipy/version.py +12 -0
- scipy-1.16.2.dist-info/DELVEWHEEL +2 -0
- scipy-1.16.2.dist-info/LICENSE.txt +912 -0
- scipy-1.16.2.dist-info/METADATA +1061 -0
- scipy-1.16.2.dist-info/RECORD +1530 -0
- scipy-1.16.2.dist-info/WHEEL +4 -0
- scipy.libs/msvcp140-5f1c5dd31916990d94181e07bc3afb32.dll +0 -0
- scipy.libs/scipy_openblas-f3ac85b1f412f7e86514c923dc4058d1.dll +0 -0
@@ -0,0 +1,2000 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
from numpy.testing import assert_allclose, assert_equal, suppress_warnings
|
5
|
+
|
6
|
+
from scipy._lib._util import rng_integers
|
7
|
+
from scipy._lib._array_api import is_numpy
|
8
|
+
from scipy._lib._array_api_no_0d import xp_assert_close, xp_assert_equal
|
9
|
+
from scipy import stats, special
|
10
|
+
from scipy.optimize import root
|
11
|
+
|
12
|
+
from scipy.stats import bootstrap, monte_carlo_test, permutation_test, power
|
13
|
+
import scipy.stats._resampling as _resampling
|
14
|
+
|
15
|
+
|
16
|
+
def test_bootstrap_iv():
|
17
|
+
|
18
|
+
message = "`data` must be a sequence of samples."
|
19
|
+
with pytest.raises(ValueError, match=message):
|
20
|
+
bootstrap(1, np.mean)
|
21
|
+
|
22
|
+
message = "`data` must contain at least one sample."
|
23
|
+
with pytest.raises(ValueError, match=message):
|
24
|
+
bootstrap(tuple(), np.mean)
|
25
|
+
|
26
|
+
message = "each sample in `data` must contain two or more observations..."
|
27
|
+
with pytest.raises(ValueError, match=message):
|
28
|
+
bootstrap(([1, 2, 3], [1]), np.mean)
|
29
|
+
|
30
|
+
message = ("When `paired is True`, all samples must have the same length ")
|
31
|
+
with pytest.raises(ValueError, match=message):
|
32
|
+
bootstrap(([1, 2, 3], [1, 2, 3, 4]), np.mean, paired=True)
|
33
|
+
|
34
|
+
message = "`vectorized` must be `True`, `False`, or `None`."
|
35
|
+
with pytest.raises(ValueError, match=message):
|
36
|
+
bootstrap(1, np.mean, vectorized='ekki')
|
37
|
+
|
38
|
+
message = "`axis` must be an integer."
|
39
|
+
with pytest.raises(ValueError, match=message):
|
40
|
+
bootstrap(([1, 2, 3],), np.mean, axis=1.5)
|
41
|
+
|
42
|
+
message = "could not convert string to float"
|
43
|
+
with pytest.raises(ValueError, match=message):
|
44
|
+
bootstrap(([1, 2, 3],), np.mean, confidence_level='ni')
|
45
|
+
|
46
|
+
message = "`n_resamples` must be a non-negative integer."
|
47
|
+
with pytest.raises(ValueError, match=message):
|
48
|
+
bootstrap(([1, 2, 3],), np.mean, n_resamples=-1000)
|
49
|
+
|
50
|
+
message = "`n_resamples` must be a non-negative integer."
|
51
|
+
with pytest.raises(ValueError, match=message):
|
52
|
+
bootstrap(([1, 2, 3],), np.mean, n_resamples=1000.5)
|
53
|
+
|
54
|
+
message = "`batch` must be a positive integer or None."
|
55
|
+
with pytest.raises(ValueError, match=message):
|
56
|
+
bootstrap(([1, 2, 3],), np.mean, batch=-1000)
|
57
|
+
|
58
|
+
message = "`batch` must be a positive integer or None."
|
59
|
+
with pytest.raises(ValueError, match=message):
|
60
|
+
bootstrap(([1, 2, 3],), np.mean, batch=1000.5)
|
61
|
+
|
62
|
+
message = "`method` must be in"
|
63
|
+
with pytest.raises(ValueError, match=message):
|
64
|
+
bootstrap(([1, 2, 3],), np.mean, method='ekki')
|
65
|
+
|
66
|
+
message = "`bootstrap_result` must have attribute `bootstrap_distribution'"
|
67
|
+
with pytest.raises(ValueError, match=message):
|
68
|
+
bootstrap(([1, 2, 3],), np.mean, bootstrap_result=10)
|
69
|
+
|
70
|
+
message = "Either `bootstrap_result.bootstrap_distribution.size`"
|
71
|
+
with pytest.raises(ValueError, match=message):
|
72
|
+
bootstrap(([1, 2, 3],), np.mean, n_resamples=0)
|
73
|
+
|
74
|
+
message = "SeedSequence expects int or sequence of ints"
|
75
|
+
with pytest.raises(TypeError, match=message):
|
76
|
+
bootstrap(([1, 2, 3],), np.mean, rng='herring')
|
77
|
+
|
78
|
+
|
79
|
+
@pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
|
80
|
+
@pytest.mark.parametrize("axis", [0, 1, 2])
|
81
|
+
def test_bootstrap_batch(method, axis):
|
82
|
+
# for one-sample statistics, batch size shouldn't affect the result
|
83
|
+
rng = np.random.RandomState(0)
|
84
|
+
|
85
|
+
x = rng.rand(10, 11, 12)
|
86
|
+
# SPEC-007 leave one call with random_state to ensure it still works
|
87
|
+
res1 = bootstrap((x,), np.mean, batch=None, method=method,
|
88
|
+
random_state=0, axis=axis, n_resamples=100)
|
89
|
+
rng = np.random.RandomState(0)
|
90
|
+
res2 = bootstrap((x,), np.mean, batch=10, method=method,
|
91
|
+
axis=axis, n_resamples=100, random_state=rng)
|
92
|
+
|
93
|
+
assert_equal(res2.confidence_interval.low, res1.confidence_interval.low)
|
94
|
+
assert_equal(res2.confidence_interval.high, res1.confidence_interval.high)
|
95
|
+
assert_equal(res2.standard_error, res1.standard_error)
|
96
|
+
|
97
|
+
|
98
|
+
@pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
|
99
|
+
def test_bootstrap_paired(method):
|
100
|
+
# test that `paired` works as expected
|
101
|
+
rng = np.random.RandomState(0)
|
102
|
+
n = 100
|
103
|
+
x = rng.rand(n)
|
104
|
+
y = rng.rand(n)
|
105
|
+
|
106
|
+
def my_statistic(x, y, axis=-1):
|
107
|
+
return ((x-y)**2).mean(axis=axis)
|
108
|
+
|
109
|
+
def my_paired_statistic(i, axis=-1):
|
110
|
+
a = x[i]
|
111
|
+
b = y[i]
|
112
|
+
res = my_statistic(a, b)
|
113
|
+
return res
|
114
|
+
|
115
|
+
i = np.arange(len(x))
|
116
|
+
|
117
|
+
res1 = bootstrap((i,), my_paired_statistic, rng=0)
|
118
|
+
res2 = bootstrap((x, y), my_statistic, paired=True, rng=0)
|
119
|
+
|
120
|
+
assert_allclose(res1.confidence_interval, res2.confidence_interval)
|
121
|
+
assert_allclose(res1.standard_error, res2.standard_error)
|
122
|
+
|
123
|
+
|
124
|
+
@pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
|
125
|
+
@pytest.mark.parametrize("axis", [0, 1, 2])
|
126
|
+
@pytest.mark.parametrize("paired", [True, False])
|
127
|
+
def test_bootstrap_vectorized(method, axis, paired):
|
128
|
+
# test that paired is vectorized as expected: when samples are tiled,
|
129
|
+
# CI and standard_error of each axis-slice is the same as those of the
|
130
|
+
# original 1d sample
|
131
|
+
|
132
|
+
rng = np.random.RandomState(0)
|
133
|
+
|
134
|
+
def my_statistic(x, y, z, axis=-1):
|
135
|
+
return x.mean(axis=axis) + y.mean(axis=axis) + z.mean(axis=axis)
|
136
|
+
|
137
|
+
shape = 10, 11, 12
|
138
|
+
n_samples = shape[axis]
|
139
|
+
|
140
|
+
x = rng.rand(n_samples)
|
141
|
+
y = rng.rand(n_samples)
|
142
|
+
z = rng.rand(n_samples)
|
143
|
+
res1 = bootstrap((x, y, z), my_statistic, paired=paired, method=method,
|
144
|
+
rng=0, axis=0, n_resamples=100)
|
145
|
+
assert (res1.bootstrap_distribution.shape
|
146
|
+
== res1.standard_error.shape + (100,))
|
147
|
+
|
148
|
+
reshape = [1, 1, 1]
|
149
|
+
reshape[axis] = n_samples
|
150
|
+
x = np.broadcast_to(x.reshape(reshape), shape)
|
151
|
+
y = np.broadcast_to(y.reshape(reshape), shape)
|
152
|
+
z = np.broadcast_to(z.reshape(reshape), shape)
|
153
|
+
res2 = bootstrap((x, y, z), my_statistic, paired=paired, method=method,
|
154
|
+
rng=0, axis=axis, n_resamples=100)
|
155
|
+
|
156
|
+
assert_allclose(res2.confidence_interval.low,
|
157
|
+
res1.confidence_interval.low)
|
158
|
+
assert_allclose(res2.confidence_interval.high,
|
159
|
+
res1.confidence_interval.high)
|
160
|
+
assert_allclose(res2.standard_error, res1.standard_error)
|
161
|
+
|
162
|
+
result_shape = list(shape)
|
163
|
+
result_shape.pop(axis)
|
164
|
+
|
165
|
+
assert_equal(res2.confidence_interval.low.shape, result_shape)
|
166
|
+
assert_equal(res2.confidence_interval.high.shape, result_shape)
|
167
|
+
assert_equal(res2.standard_error.shape, result_shape)
|
168
|
+
|
169
|
+
|
170
|
+
@pytest.mark.slow
|
171
|
+
@pytest.mark.xfail_on_32bit("MemoryError with BCa observed in CI")
|
172
|
+
@pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
|
173
|
+
def test_bootstrap_against_theory(method):
|
174
|
+
# based on https://www.statology.org/confidence-intervals-python/
|
175
|
+
rng = np.random.default_rng(2442101192988600726)
|
176
|
+
data = stats.norm.rvs(loc=5, scale=2, size=5000, random_state=rng)
|
177
|
+
alpha = 0.95
|
178
|
+
dist = stats.t(df=len(data)-1, loc=np.mean(data), scale=stats.sem(data))
|
179
|
+
expected_interval = dist.interval(confidence=alpha)
|
180
|
+
expected_se = dist.std()
|
181
|
+
|
182
|
+
config = dict(data=(data,), statistic=np.mean, n_resamples=5000,
|
183
|
+
method=method, rng=rng)
|
184
|
+
res = bootstrap(**config, confidence_level=alpha)
|
185
|
+
assert_allclose(res.confidence_interval, expected_interval, rtol=5e-4)
|
186
|
+
assert_allclose(res.standard_error, expected_se, atol=3e-4)
|
187
|
+
|
188
|
+
config.update(dict(n_resamples=0, bootstrap_result=res))
|
189
|
+
res = bootstrap(**config, confidence_level=alpha, alternative='less')
|
190
|
+
assert_allclose(res.confidence_interval.high, dist.ppf(alpha), rtol=5e-4)
|
191
|
+
|
192
|
+
config.update(dict(n_resamples=0, bootstrap_result=res))
|
193
|
+
res = bootstrap(**config, confidence_level=alpha, alternative='greater')
|
194
|
+
assert_allclose(res.confidence_interval.low, dist.ppf(1-alpha), rtol=5e-4)
|
195
|
+
|
196
|
+
|
197
|
+
tests_R = {"basic": (23.77, 79.12),
|
198
|
+
"percentile": (28.86, 84.21),
|
199
|
+
"BCa": (32.31, 91.43)}
|
200
|
+
|
201
|
+
|
202
|
+
@pytest.mark.parametrize("method, expected", tests_R.items())
|
203
|
+
def test_bootstrap_against_R(method, expected):
|
204
|
+
# Compare against R's "boot" library
|
205
|
+
# library(boot)
|
206
|
+
|
207
|
+
# stat <- function (x, a) {
|
208
|
+
# mean(x[a])
|
209
|
+
# }
|
210
|
+
|
211
|
+
# x <- c(10, 12, 12.5, 12.5, 13.9, 15, 21, 22,
|
212
|
+
# 23, 34, 50, 81, 89, 121, 134, 213)
|
213
|
+
|
214
|
+
# # Use a large value so we get a few significant digits for the CI.
|
215
|
+
# n = 1000000
|
216
|
+
# bootresult = boot(x, stat, n)
|
217
|
+
# result <- boot.ci(bootresult)
|
218
|
+
# print(result)
|
219
|
+
x = np.array([10, 12, 12.5, 12.5, 13.9, 15, 21, 22,
|
220
|
+
23, 34, 50, 81, 89, 121, 134, 213])
|
221
|
+
res = bootstrap((x,), np.mean, n_resamples=1000000, method=method,
|
222
|
+
rng=0)
|
223
|
+
assert_allclose(res.confidence_interval, expected, rtol=0.005)
|
224
|
+
|
225
|
+
|
226
|
+
def test_multisample_BCa_against_R():
|
227
|
+
# Because bootstrap is stochastic, it's tricky to test against reference
|
228
|
+
# behavior. Here, we show that SciPy's BCa CI matches R wboot's BCa CI
|
229
|
+
# much more closely than the other SciPy CIs do.
|
230
|
+
|
231
|
+
# arbitrary skewed data
|
232
|
+
x = [0.75859206, 0.5910282, -0.4419409, -0.36654601,
|
233
|
+
0.34955357, -1.38835871, 0.76735821]
|
234
|
+
y = [1.41186073, 0.49775975, 0.08275588, 0.24086388,
|
235
|
+
0.03567057, 0.52024419, 0.31966611, 1.32067634]
|
236
|
+
|
237
|
+
# a multi-sample statistic for which the BCa CI tends to be different
|
238
|
+
# from the other CIs
|
239
|
+
def statistic(x, y, axis):
|
240
|
+
s1 = stats.skew(x, axis=axis)
|
241
|
+
s2 = stats.skew(y, axis=axis)
|
242
|
+
return s1 - s2
|
243
|
+
|
244
|
+
# compute confidence intervals using each method
|
245
|
+
rng = np.random.default_rng(468865032284792692)
|
246
|
+
|
247
|
+
res_basic = stats.bootstrap((x, y), statistic, method='basic',
|
248
|
+
batch=100, rng=rng)
|
249
|
+
res_percent = stats.bootstrap((x, y), statistic, method='percentile',
|
250
|
+
batch=100, rng=rng)
|
251
|
+
res_bca = stats.bootstrap((x, y), statistic, method='bca',
|
252
|
+
batch=100, rng=rng)
|
253
|
+
|
254
|
+
# compute midpoints so we can compare just one number for each
|
255
|
+
mid_basic = np.mean(res_basic.confidence_interval)
|
256
|
+
mid_percent = np.mean(res_percent.confidence_interval)
|
257
|
+
mid_bca = np.mean(res_bca.confidence_interval)
|
258
|
+
|
259
|
+
# reference for BCA CI computed using R wboot package:
|
260
|
+
# library(wBoot)
|
261
|
+
# library(moments)
|
262
|
+
|
263
|
+
# x = c(0.75859206, 0.5910282, -0.4419409, -0.36654601,
|
264
|
+
# 0.34955357, -1.38835871, 0.76735821)
|
265
|
+
# y = c(1.41186073, 0.49775975, 0.08275588, 0.24086388,
|
266
|
+
# 0.03567057, 0.52024419, 0.31966611, 1.32067634)
|
267
|
+
|
268
|
+
# twoskew <- function(x1, y1) {skewness(x1) - skewness(y1)}
|
269
|
+
# boot.two.bca(x, y, skewness, conf.level = 0.95,
|
270
|
+
# R = 9999, stacked = FALSE)
|
271
|
+
mid_wboot = -1.5519
|
272
|
+
|
273
|
+
# compute percent difference relative to wboot BCA method
|
274
|
+
diff_basic = (mid_basic - mid_wboot)/abs(mid_wboot)
|
275
|
+
diff_percent = (mid_percent - mid_wboot)/abs(mid_wboot)
|
276
|
+
diff_bca = (mid_bca - mid_wboot)/abs(mid_wboot)
|
277
|
+
|
278
|
+
# SciPy's BCa CI midpoint is much closer than that of the other methods
|
279
|
+
assert diff_basic < -0.15
|
280
|
+
assert diff_percent > 0.15
|
281
|
+
assert abs(diff_bca) < 0.03
|
282
|
+
|
283
|
+
|
284
|
+
def test_BCa_acceleration_against_reference():
|
285
|
+
# Compare the (deterministic) acceleration parameter for a multi-sample
|
286
|
+
# problem against a reference value. The example is from [1], but Efron's
|
287
|
+
# value seems inaccurate. Straightforward code for computing the
|
288
|
+
# reference acceleration (0.011008228344026734) is available at:
|
289
|
+
# https://github.com/scipy/scipy/pull/16455#issuecomment-1193400981
|
290
|
+
|
291
|
+
y = np.array([10, 27, 31, 40, 46, 50, 52, 104, 146])
|
292
|
+
z = np.array([16, 23, 38, 94, 99, 141, 197])
|
293
|
+
|
294
|
+
def statistic(z, y, axis=0):
|
295
|
+
return np.mean(z, axis=axis) - np.mean(y, axis=axis)
|
296
|
+
|
297
|
+
data = [z, y]
|
298
|
+
res = stats.bootstrap(data, statistic)
|
299
|
+
|
300
|
+
axis = -1
|
301
|
+
alpha = 0.95
|
302
|
+
theta_hat_b = res.bootstrap_distribution
|
303
|
+
batch = 100
|
304
|
+
_, _, a_hat = _resampling._bca_interval(data, statistic, axis, alpha,
|
305
|
+
theta_hat_b, batch)
|
306
|
+
assert_allclose(a_hat, 0.011008228344026734)
|
307
|
+
|
308
|
+
|
309
|
+
tests_against_itself_1samp = {"basic": 1789,
|
310
|
+
"percentile": 1790,
|
311
|
+
"BCa": 1789}
|
312
|
+
|
313
|
+
|
314
|
+
@pytest.mark.slow
|
315
|
+
@pytest.mark.parametrize("method, expected",
|
316
|
+
tests_against_itself_1samp.items())
|
317
|
+
def test_bootstrap_against_itself_1samp(method, expected):
|
318
|
+
# The expected values in this test were generated using bootstrap
|
319
|
+
# to check for unintended changes in behavior. The test also makes sure
|
320
|
+
# that bootstrap works with multi-sample statistics and that the
|
321
|
+
# `axis` argument works as expected / function is vectorized.
|
322
|
+
rng = np.random.default_rng(9123847)
|
323
|
+
|
324
|
+
n = 100 # size of sample
|
325
|
+
n_resamples = 999 # number of bootstrap resamples used to form each CI
|
326
|
+
confidence_level = 0.9
|
327
|
+
|
328
|
+
# The true mean is 5
|
329
|
+
dist = stats.norm(loc=5, scale=1)
|
330
|
+
stat_true = dist.mean()
|
331
|
+
|
332
|
+
# Do the same thing 2000 times. (The code is fully vectorized.)
|
333
|
+
n_replications = 2000
|
334
|
+
data = dist.rvs(size=(n_replications, n), random_state=rng)
|
335
|
+
res = bootstrap((data,),
|
336
|
+
statistic=np.mean,
|
337
|
+
confidence_level=confidence_level,
|
338
|
+
n_resamples=n_resamples,
|
339
|
+
batch=50,
|
340
|
+
method=method,
|
341
|
+
axis=-1,
|
342
|
+
rng=rng)
|
343
|
+
ci = res.confidence_interval
|
344
|
+
|
345
|
+
# ci contains vectors of lower and upper confidence interval bounds
|
346
|
+
ci_contains_true = np.sum((ci[0] < stat_true) & (stat_true < ci[1]))
|
347
|
+
assert ci_contains_true == expected
|
348
|
+
|
349
|
+
# ci_contains_true is not inconsistent with confidence_level
|
350
|
+
pvalue = stats.binomtest(ci_contains_true, n_replications,
|
351
|
+
confidence_level).pvalue
|
352
|
+
assert pvalue > 0.1
|
353
|
+
|
354
|
+
|
355
|
+
tests_against_itself_2samp = {"basic": 892,
|
356
|
+
"percentile": 890}
|
357
|
+
|
358
|
+
|
359
|
+
@pytest.mark.slow
|
360
|
+
@pytest.mark.parametrize("method, expected",
|
361
|
+
tests_against_itself_2samp.items())
|
362
|
+
def test_bootstrap_against_itself_2samp(method, expected):
|
363
|
+
# The expected values in this test were generated using bootstrap
|
364
|
+
# to check for unintended changes in behavior. The test also makes sure
|
365
|
+
# that bootstrap works with multi-sample statistics and that the
|
366
|
+
# `axis` argument works as expected / function is vectorized.
|
367
|
+
rng = np.random.RandomState(0)
|
368
|
+
|
369
|
+
n1 = 100 # size of sample 1
|
370
|
+
n2 = 120 # size of sample 2
|
371
|
+
n_resamples = 999 # number of bootstrap resamples used to form each CI
|
372
|
+
confidence_level = 0.9
|
373
|
+
|
374
|
+
# The statistic we're interested in is the difference in means
|
375
|
+
def my_stat(data1, data2, axis=-1):
|
376
|
+
mean1 = np.mean(data1, axis=axis)
|
377
|
+
mean2 = np.mean(data2, axis=axis)
|
378
|
+
return mean1 - mean2
|
379
|
+
|
380
|
+
# The true difference in the means is -0.1
|
381
|
+
dist1 = stats.norm(loc=0, scale=1)
|
382
|
+
dist2 = stats.norm(loc=0.1, scale=1)
|
383
|
+
stat_true = dist1.mean() - dist2.mean()
|
384
|
+
|
385
|
+
# Do the same thing 1000 times. (The code is fully vectorized.)
|
386
|
+
n_replications = 1000
|
387
|
+
data1 = dist1.rvs(size=(n_replications, n1), random_state=rng)
|
388
|
+
data2 = dist2.rvs(size=(n_replications, n2), random_state=rng)
|
389
|
+
res = bootstrap((data1, data2),
|
390
|
+
statistic=my_stat,
|
391
|
+
confidence_level=confidence_level,
|
392
|
+
n_resamples=n_resamples,
|
393
|
+
batch=50,
|
394
|
+
method=method,
|
395
|
+
axis=-1,
|
396
|
+
random_state=rng)
|
397
|
+
ci = res.confidence_interval
|
398
|
+
|
399
|
+
# ci contains vectors of lower and upper confidence interval bounds
|
400
|
+
ci_contains_true = np.sum((ci[0] < stat_true) & (stat_true < ci[1]))
|
401
|
+
assert ci_contains_true == expected
|
402
|
+
|
403
|
+
# ci_contains_true is not inconsistent with confidence_level
|
404
|
+
pvalue = stats.binomtest(ci_contains_true, n_replications,
|
405
|
+
confidence_level).pvalue
|
406
|
+
assert pvalue > 0.1
|
407
|
+
|
408
|
+
|
409
|
+
@pytest.mark.parametrize("method", ["basic", "percentile"])
|
410
|
+
@pytest.mark.parametrize("axis", [0, 1])
|
411
|
+
def test_bootstrap_vectorized_3samp(method, axis):
|
412
|
+
def statistic(*data, axis=0):
|
413
|
+
# an arbitrary, vectorized statistic
|
414
|
+
return sum(sample.mean(axis) for sample in data)
|
415
|
+
|
416
|
+
def statistic_1d(*data):
|
417
|
+
# the same statistic, not vectorized
|
418
|
+
for sample in data:
|
419
|
+
assert sample.ndim == 1
|
420
|
+
return statistic(*data, axis=0)
|
421
|
+
|
422
|
+
rng = np.random.RandomState(0)
|
423
|
+
x = rng.rand(4, 5)
|
424
|
+
y = rng.rand(4, 5)
|
425
|
+
z = rng.rand(4, 5)
|
426
|
+
res1 = bootstrap((x, y, z), statistic, vectorized=True,
|
427
|
+
axis=axis, n_resamples=100, method=method, rng=0)
|
428
|
+
res2 = bootstrap((x, y, z), statistic_1d, vectorized=False,
|
429
|
+
axis=axis, n_resamples=100, method=method, rng=0)
|
430
|
+
assert_allclose(res1.confidence_interval, res2.confidence_interval)
|
431
|
+
assert_allclose(res1.standard_error, res2.standard_error)
|
432
|
+
|
433
|
+
|
434
|
+
@pytest.mark.xfail_on_32bit("Failure is not concerning; see gh-14107")
|
435
|
+
@pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
|
436
|
+
@pytest.mark.parametrize("axis", [0, 1])
|
437
|
+
def test_bootstrap_vectorized_1samp(method, axis):
|
438
|
+
def statistic(x, axis=0):
|
439
|
+
# an arbitrary, vectorized statistic
|
440
|
+
return x.mean(axis=axis)
|
441
|
+
|
442
|
+
def statistic_1d(x):
|
443
|
+
# the same statistic, not vectorized
|
444
|
+
assert x.ndim == 1
|
445
|
+
return statistic(x, axis=0)
|
446
|
+
|
447
|
+
rng = np.random.RandomState(0)
|
448
|
+
x = rng.rand(4, 5)
|
449
|
+
res1 = bootstrap((x,), statistic, vectorized=True, axis=axis,
|
450
|
+
n_resamples=100, batch=None, method=method,
|
451
|
+
rng=0)
|
452
|
+
res2 = bootstrap((x,), statistic_1d, vectorized=False, axis=axis,
|
453
|
+
n_resamples=100, batch=10, method=method,
|
454
|
+
rng=0)
|
455
|
+
assert_allclose(res1.confidence_interval, res2.confidence_interval)
|
456
|
+
assert_allclose(res1.standard_error, res2.standard_error)
|
457
|
+
|
458
|
+
|
459
|
+
@pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
|
460
|
+
def test_bootstrap_degenerate(method):
|
461
|
+
data = 35 * [10000.]
|
462
|
+
if method == "BCa":
|
463
|
+
with np.errstate(invalid='ignore'):
|
464
|
+
msg = "The BCa confidence interval cannot be calculated"
|
465
|
+
with pytest.warns(stats.DegenerateDataWarning, match=msg):
|
466
|
+
res = bootstrap([data, ], np.mean, method=method)
|
467
|
+
assert_equal(res.confidence_interval, (np.nan, np.nan))
|
468
|
+
else:
|
469
|
+
res = bootstrap([data, ], np.mean, method=method)
|
470
|
+
assert_equal(res.confidence_interval, (10000., 10000.))
|
471
|
+
assert_equal(res.standard_error, 0)
|
472
|
+
|
473
|
+
|
474
|
+
@pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
|
475
|
+
def test_bootstrap_gh15678(method):
|
476
|
+
# Check that gh-15678 is fixed: when statistic function returned a Python
|
477
|
+
# float, method="BCa" failed when trying to add a dimension to the float
|
478
|
+
rng = np.random.default_rng(354645618886684)
|
479
|
+
dist = stats.norm(loc=2, scale=4)
|
480
|
+
data = dist.rvs(size=100, random_state=rng)
|
481
|
+
data = (data,)
|
482
|
+
res = bootstrap(data, stats.skew, method=method, n_resamples=100,
|
483
|
+
rng=np.random.default_rng(9563))
|
484
|
+
# this always worked because np.apply_along_axis returns NumPy data type
|
485
|
+
ref = bootstrap(data, stats.skew, method=method, n_resamples=100,
|
486
|
+
rng=np.random.default_rng(9563), vectorized=False)
|
487
|
+
assert_allclose(res.confidence_interval, ref.confidence_interval)
|
488
|
+
assert_allclose(res.standard_error, ref.standard_error)
|
489
|
+
assert isinstance(res.standard_error, np.float64)
|
490
|
+
|
491
|
+
|
492
|
+
def test_bootstrap_min():
|
493
|
+
# Check that gh-15883 is fixed: percentileofscore should
|
494
|
+
# behave according to the 'mean' behavior and not trigger nan for BCa
|
495
|
+
rng = np.random.default_rng(1891289180021102)
|
496
|
+
dist = stats.norm(loc=2, scale=4)
|
497
|
+
data = dist.rvs(size=100, random_state=rng)
|
498
|
+
true_min = np.min(data)
|
499
|
+
data = (data,)
|
500
|
+
res = bootstrap(data, np.min, method="BCa", n_resamples=100,
|
501
|
+
rng=np.random.default_rng(3942))
|
502
|
+
assert true_min == res.confidence_interval.low
|
503
|
+
res2 = bootstrap(-np.array(data), np.max, method="BCa", n_resamples=100,
|
504
|
+
rng=np.random.default_rng(3942))
|
505
|
+
assert_allclose(-res.confidence_interval.low,
|
506
|
+
res2.confidence_interval.high)
|
507
|
+
assert_allclose(-res.confidence_interval.high,
|
508
|
+
res2.confidence_interval.low)
|
509
|
+
|
510
|
+
|
511
|
+
@pytest.mark.parametrize("additional_resamples", [0, 1000])
|
512
|
+
def test_re_bootstrap(additional_resamples):
|
513
|
+
# Test behavior of parameter `bootstrap_result`
|
514
|
+
rng = np.random.default_rng(8958153316228384)
|
515
|
+
x = rng.random(size=100)
|
516
|
+
|
517
|
+
n1 = 1000
|
518
|
+
n2 = additional_resamples
|
519
|
+
n3 = n1 + additional_resamples
|
520
|
+
|
521
|
+
rng = np.random.default_rng(296689032789913033)
|
522
|
+
res = stats.bootstrap((x,), np.mean, n_resamples=n1, rng=rng,
|
523
|
+
confidence_level=0.95, method='percentile')
|
524
|
+
res = stats.bootstrap((x,), np.mean, n_resamples=n2, rng=rng,
|
525
|
+
confidence_level=0.90, method='BCa',
|
526
|
+
bootstrap_result=res)
|
527
|
+
|
528
|
+
rng = np.random.default_rng(296689032789913033)
|
529
|
+
ref = stats.bootstrap((x,), np.mean, n_resamples=n3, rng=rng,
|
530
|
+
confidence_level=0.90, method='BCa')
|
531
|
+
|
532
|
+
assert_allclose(res.standard_error, ref.standard_error, rtol=1e-14)
|
533
|
+
assert_allclose(res.confidence_interval, ref.confidence_interval,
|
534
|
+
rtol=1e-14)
|
535
|
+
|
536
|
+
|
537
|
+
@pytest.mark.xfail_on_32bit("Sensible to machine precision")
|
538
|
+
@pytest.mark.parametrize("method", ['basic', 'percentile', 'BCa'])
|
539
|
+
def test_bootstrap_alternative(method):
|
540
|
+
rng = np.random.default_rng(5894822712842015040)
|
541
|
+
dist = stats.norm(loc=2, scale=4)
|
542
|
+
data = (dist.rvs(size=(100), random_state=rng),)
|
543
|
+
|
544
|
+
config = dict(data=data, statistic=np.std, rng=rng, axis=-1)
|
545
|
+
t = stats.bootstrap(**config, confidence_level=0.9)
|
546
|
+
|
547
|
+
config.update(dict(n_resamples=0, bootstrap_result=t))
|
548
|
+
l = stats.bootstrap(**config, confidence_level=0.95, alternative='less')
|
549
|
+
g = stats.bootstrap(**config, confidence_level=0.95, alternative='greater')
|
550
|
+
|
551
|
+
assert_allclose(l.confidence_interval.high, t.confidence_interval.high,
|
552
|
+
rtol=1e-14)
|
553
|
+
assert_allclose(g.confidence_interval.low, t.confidence_interval.low,
|
554
|
+
rtol=1e-14)
|
555
|
+
assert np.isneginf(l.confidence_interval.low)
|
556
|
+
assert np.isposinf(g.confidence_interval.high)
|
557
|
+
|
558
|
+
with pytest.raises(ValueError, match='`alternative` must be one of'):
|
559
|
+
stats.bootstrap(**config, alternative='ekki-ekki')
|
560
|
+
|
561
|
+
|
562
|
+
def test_jackknife_resample():
|
563
|
+
shape = 3, 4, 5, 6
|
564
|
+
np.random.seed(0)
|
565
|
+
x = np.random.rand(*shape)
|
566
|
+
y = next(_resampling._jackknife_resample(x))
|
567
|
+
|
568
|
+
for i in range(shape[-1]):
|
569
|
+
# each resample is indexed along second to last axis
|
570
|
+
# (last axis is the one the statistic will be taken over / consumed)
|
571
|
+
slc = y[..., i, :]
|
572
|
+
expected = np.delete(x, i, axis=-1)
|
573
|
+
|
574
|
+
assert np.array_equal(slc, expected)
|
575
|
+
|
576
|
+
y2 = np.concatenate(list(_resampling._jackknife_resample(x, batch=2)),
|
577
|
+
axis=-2)
|
578
|
+
assert np.array_equal(y2, y)
|
579
|
+
|
580
|
+
|
581
|
+
@pytest.mark.parametrize("rng_name", ["RandomState", "default_rng"])
|
582
|
+
def test_bootstrap_resample(rng_name):
|
583
|
+
rng = getattr(np.random, rng_name, None)
|
584
|
+
if rng is None:
|
585
|
+
pytest.skip(f"{rng_name} not available.")
|
586
|
+
rng1 = rng(0)
|
587
|
+
rng2 = rng(0)
|
588
|
+
|
589
|
+
n_resamples = 10
|
590
|
+
shape = 3, 4, 5, 6
|
591
|
+
|
592
|
+
np.random.seed(0)
|
593
|
+
x = np.random.rand(*shape)
|
594
|
+
y = _resampling._bootstrap_resample(x, n_resamples, rng=rng1)
|
595
|
+
|
596
|
+
for i in range(n_resamples):
|
597
|
+
# each resample is indexed along second to last axis
|
598
|
+
# (last axis is the one the statistic will be taken over / consumed)
|
599
|
+
slc = y[..., i, :]
|
600
|
+
|
601
|
+
js = rng_integers(rng2, 0, shape[-1], shape[-1])
|
602
|
+
expected = x[..., js]
|
603
|
+
|
604
|
+
assert np.array_equal(slc, expected)
|
605
|
+
|
606
|
+
|
607
|
+
@pytest.mark.parametrize("score", [0, 0.5, 1])
|
608
|
+
@pytest.mark.parametrize("axis", [0, 1, 2])
|
609
|
+
def test_percentile_of_score(score, axis):
|
610
|
+
shape = 10, 20, 30
|
611
|
+
np.random.seed(0)
|
612
|
+
x = np.random.rand(*shape)
|
613
|
+
p = _resampling._percentile_of_score(x, score, axis=-1)
|
614
|
+
|
615
|
+
def vectorized_pos(a, score, axis):
|
616
|
+
return np.apply_along_axis(stats.percentileofscore, axis, a, score)
|
617
|
+
|
618
|
+
p2 = vectorized_pos(x, score, axis=-1)/100
|
619
|
+
|
620
|
+
assert_allclose(p, p2, 1e-15)
|
621
|
+
|
622
|
+
|
623
|
+
def test_percentile_along_axis():
|
624
|
+
# the difference between _percentile_along_axis and np.percentile is that
|
625
|
+
# np.percentile gets _all_ the qs for each axis slice, whereas
|
626
|
+
# _percentile_along_axis gets the q corresponding with each axis slice
|
627
|
+
|
628
|
+
shape = 10, 20
|
629
|
+
rng = np.random.RandomState(0)
|
630
|
+
x = rng.rand(*shape)
|
631
|
+
q = rng.rand(*shape[:-1]) * 100
|
632
|
+
y = _resampling._percentile_along_axis(x, q)
|
633
|
+
|
634
|
+
for i in range(shape[0]):
|
635
|
+
res = y[i]
|
636
|
+
expected = np.percentile(x[i], q[i], axis=-1)
|
637
|
+
assert_allclose(res, expected, 1e-15)
|
638
|
+
|
639
|
+
|
640
|
+
@pytest.mark.parametrize("axis", [0, 1, 2])
|
641
|
+
def test_vectorize_statistic(axis):
|
642
|
+
# test that _vectorize_statistic vectorizes a statistic along `axis`
|
643
|
+
|
644
|
+
def statistic(*data, axis):
|
645
|
+
# an arbitrary, vectorized statistic
|
646
|
+
return sum(sample.mean(axis) for sample in data)
|
647
|
+
|
648
|
+
def statistic_1d(*data):
|
649
|
+
# the same statistic, not vectorized
|
650
|
+
for sample in data:
|
651
|
+
assert sample.ndim == 1
|
652
|
+
return statistic(*data, axis=0)
|
653
|
+
|
654
|
+
# vectorize the non-vectorized statistic
|
655
|
+
statistic2 = _resampling._vectorize_statistic(statistic_1d)
|
656
|
+
|
657
|
+
rng = np.random.RandomState(0)
|
658
|
+
x = rng.rand(4, 5, 6)
|
659
|
+
y = rng.rand(4, 1, 6)
|
660
|
+
z = rng.rand(1, 5, 6)
|
661
|
+
|
662
|
+
res1 = statistic(x, y, z, axis=axis)
|
663
|
+
res2 = statistic2(x, y, z, axis=axis)
|
664
|
+
assert_allclose(res1, res2)
|
665
|
+
|
666
|
+
|
667
|
+
@pytest.mark.slow
|
668
|
+
@pytest.mark.parametrize("method", ["basic", "percentile", "BCa"])
|
669
|
+
def test_vector_valued_statistic(method):
|
670
|
+
# Generate 95% confidence interval around MLE of normal distribution
|
671
|
+
# parameters. Repeat 100 times, each time on sample of size 100.
|
672
|
+
# Check that confidence interval contains true parameters ~95 times.
|
673
|
+
# Confidence intervals are estimated and stochastic; a test failure
|
674
|
+
# does not necessarily indicate that something is wrong. More important
|
675
|
+
# than values of `counts` below is that the shapes of the outputs are
|
676
|
+
# correct.
|
677
|
+
|
678
|
+
rng = np.random.default_rng(2196847219)
|
679
|
+
params = 1, 0.5
|
680
|
+
sample = stats.norm.rvs(*params, size=(100, 100), random_state=rng)
|
681
|
+
|
682
|
+
def statistic(data, axis):
|
683
|
+
return np.asarray([np.mean(data, axis),
|
684
|
+
np.std(data, axis, ddof=1)])
|
685
|
+
|
686
|
+
res = bootstrap((sample,), statistic, method=method, axis=-1,
|
687
|
+
n_resamples=9999, batch=200, random_state=rng)
|
688
|
+
|
689
|
+
counts = np.sum((res.confidence_interval.low.T < params)
|
690
|
+
& (res.confidence_interval.high.T > params),
|
691
|
+
axis=0)
|
692
|
+
assert np.all(counts >= 90)
|
693
|
+
assert np.all(counts <= 100)
|
694
|
+
assert res.confidence_interval.low.shape == (2, 100)
|
695
|
+
assert res.confidence_interval.high.shape == (2, 100)
|
696
|
+
assert res.standard_error.shape == (2, 100)
|
697
|
+
assert res.bootstrap_distribution.shape == (2, 100, 9999)
|
698
|
+
|
699
|
+
|
700
|
+
@pytest.mark.slow
|
701
|
+
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
|
702
|
+
def test_vector_valued_statistic_gh17715():
|
703
|
+
# gh-17715 reported a mistake introduced in the extension of BCa to
|
704
|
+
# multi-sample statistics; a `len` should have been `.shape[-1]`. Check
|
705
|
+
# that this is resolved.
|
706
|
+
|
707
|
+
rng = np.random.default_rng(141921000979291141)
|
708
|
+
|
709
|
+
def concordance(x, y, axis):
|
710
|
+
xm = x.mean(axis)
|
711
|
+
ym = y.mean(axis)
|
712
|
+
cov = ((x - xm[..., None]) * (y - ym[..., None])).mean(axis)
|
713
|
+
return (2 * cov) / (x.var(axis) + y.var(axis) + (xm - ym) ** 2)
|
714
|
+
|
715
|
+
def statistic(tp, tn, fp, fn, axis):
|
716
|
+
actual = tp + fp
|
717
|
+
expected = tp + fn
|
718
|
+
return np.nan_to_num(concordance(actual, expected, axis))
|
719
|
+
|
720
|
+
def statistic_extradim(*args, axis):
|
721
|
+
return statistic(*args, axis)[np.newaxis, ...]
|
722
|
+
|
723
|
+
data = [[4, 0, 0, 2], # (tp, tn, fp, fn)
|
724
|
+
[2, 1, 2, 1],
|
725
|
+
[0, 6, 0, 0],
|
726
|
+
[0, 6, 3, 0],
|
727
|
+
[0, 8, 1, 0]]
|
728
|
+
data = np.array(data).T
|
729
|
+
|
730
|
+
res = bootstrap(data, statistic_extradim, rng=rng, paired=True)
|
731
|
+
ref = bootstrap(data, statistic, rng=rng, paired=True)
|
732
|
+
assert_allclose(res.confidence_interval.low[0],
|
733
|
+
ref.confidence_interval.low, atol=1e-15)
|
734
|
+
assert_allclose(res.confidence_interval.high[0],
|
735
|
+
ref.confidence_interval.high, atol=1e-15)
|
736
|
+
|
737
|
+
|
738
|
+
def test_gh_20850():
|
739
|
+
rng = np.random.default_rng(2085020850)
|
740
|
+
x = rng.random((10, 2))
|
741
|
+
y = rng.random((11, 2))
|
742
|
+
def statistic(x, y, axis):
|
743
|
+
return stats.ttest_ind(x, y, axis=axis).statistic
|
744
|
+
|
745
|
+
# The shapes do *not* need to be the same along axis
|
746
|
+
stats.bootstrap((x, y), statistic)
|
747
|
+
stats.bootstrap((x.T, y.T), statistic, axis=1)
|
748
|
+
# But even when the shapes *are* the same along axis, the lengths
|
749
|
+
# along other dimensions have to be the same (or `bootstrap` warns).
|
750
|
+
message = "Array shapes are incompatible for broadcasting."
|
751
|
+
with pytest.raises(ValueError, match=message):
|
752
|
+
stats.bootstrap((x, y[:10, 0]), statistic) # this won't work after 1.16
|
753
|
+
stats.bootstrap((x, y[:10, 0:1]), statistic) # this will
|
754
|
+
stats.bootstrap((x.T, y.T[0:1, :10]), statistic, axis=1) # this will
|
755
|
+
|
756
|
+
|
757
|
+
# --- Test Monte Carlo Hypothesis Test --- #
|
758
|
+
|
759
|
+
class TestMonteCarloHypothesisTest:
|
760
|
+
atol = 2.5e-2 # for comparing p-value
|
761
|
+
|
762
|
+
def get_rvs(self, rvs_in, rs, dtype=None, xp=np):
|
763
|
+
return lambda *args, **kwds: xp.asarray(rvs_in(*args, random_state=rs, **kwds),
|
764
|
+
dtype=dtype)
|
765
|
+
|
766
|
+
def get_statistic(self, xp):
|
767
|
+
def statistic(x, axis):
|
768
|
+
m = xp.mean(x, axis=axis)
|
769
|
+
v = xp.var(x, axis=axis, correction=1)
|
770
|
+
n = x.shape[axis]
|
771
|
+
return m / (v/n)**0.5
|
772
|
+
# return stats.ttest_1samp(x, popmean=0., axis=axis).statistic)
|
773
|
+
return statistic
|
774
|
+
|
775
|
+
def test_input_validation(self, xp):
|
776
|
+
# test that the appropriate error messages are raised for invalid input
|
777
|
+
|
778
|
+
data = xp.asarray([1., 2., 3.])
|
779
|
+
def stat(x, axis=None):
|
780
|
+
return xp.mean(x, axis=axis)
|
781
|
+
|
782
|
+
message = "Array shapes are incompatible for broadcasting."
|
783
|
+
temp = (xp.zeros((2, 5)), xp.zeros((3, 5)))
|
784
|
+
rvs = (stats.norm.rvs, stats.norm.rvs)
|
785
|
+
with pytest.raises(ValueError, match=message):
|
786
|
+
monte_carlo_test(temp, rvs, lambda x, y, axis: 1, axis=-1)
|
787
|
+
|
788
|
+
message = "`axis` must be an integer."
|
789
|
+
with pytest.raises(ValueError, match=message):
|
790
|
+
monte_carlo_test(data, stats.norm.rvs, stat, axis=1.5)
|
791
|
+
|
792
|
+
message = "`vectorized` must be `True`, `False`, or `None`."
|
793
|
+
with pytest.raises(ValueError, match=message):
|
794
|
+
monte_carlo_test(data, stats.norm.rvs, stat, vectorized=1.5)
|
795
|
+
|
796
|
+
message = "`rvs` must be callable or sequence of callables."
|
797
|
+
with pytest.raises(TypeError, match=message):
|
798
|
+
monte_carlo_test(data, None, stat)
|
799
|
+
with pytest.raises(TypeError, match=message):
|
800
|
+
temp = xp.asarray([[1., 2.], [3., 4.]])
|
801
|
+
monte_carlo_test(temp, [lambda x: x, None], stat)
|
802
|
+
|
803
|
+
message = "If `rvs` is a sequence..."
|
804
|
+
with pytest.raises(ValueError, match=message):
|
805
|
+
temp = xp.asarray([[1., 2., 3.]])
|
806
|
+
monte_carlo_test(temp, [lambda x: x, lambda x: x], stat)
|
807
|
+
|
808
|
+
message = "`statistic` must be callable."
|
809
|
+
with pytest.raises(TypeError, match=message):
|
810
|
+
monte_carlo_test(data, stats.norm.rvs, None)
|
811
|
+
|
812
|
+
message = "`n_resamples` must be a positive integer."
|
813
|
+
with pytest.raises(ValueError, match=message):
|
814
|
+
monte_carlo_test(data, stats.norm.rvs, stat, n_resamples=-1000)
|
815
|
+
|
816
|
+
message = "`n_resamples` must be a positive integer."
|
817
|
+
with pytest.raises(ValueError, match=message):
|
818
|
+
monte_carlo_test(data, stats.norm.rvs, stat, n_resamples=1000.5)
|
819
|
+
|
820
|
+
message = "`batch` must be a positive integer or None."
|
821
|
+
with pytest.raises(ValueError, match=message):
|
822
|
+
monte_carlo_test(data, stats.norm.rvs, stat, batch=-1000)
|
823
|
+
|
824
|
+
message = "`batch` must be a positive integer or None."
|
825
|
+
with pytest.raises(ValueError, match=message):
|
826
|
+
monte_carlo_test(data, stats.norm.rvs, stat, batch=1000.5)
|
827
|
+
|
828
|
+
message = "`alternative` must be in..."
|
829
|
+
with pytest.raises(ValueError, match=message):
|
830
|
+
monte_carlo_test(data, stats.norm.rvs, stat, alternative='ekki')
|
831
|
+
|
832
|
+
# *If* this raises a value error, make sure it has the intended message
|
833
|
+
message = "Signature inspection of statistic"
|
834
|
+
def rvs(size):
|
835
|
+
return xp.asarray(stats.norm.rvs(size=size))
|
836
|
+
try:
|
837
|
+
monte_carlo_test(data, rvs, xp.mean)
|
838
|
+
except ValueError as e:
|
839
|
+
assert str(e).startswith(message)
|
840
|
+
|
841
|
+
def test_input_validation_xp(self, xp):
|
842
|
+
def non_vectorized_statistic(x):
|
843
|
+
return xp.mean(x)
|
844
|
+
|
845
|
+
message = "`statistic` must be vectorized..."
|
846
|
+
sample = xp.asarray([1., 2., 3.])
|
847
|
+
if is_numpy(xp):
|
848
|
+
monte_carlo_test(sample, stats.norm.rvs, non_vectorized_statistic)
|
849
|
+
return
|
850
|
+
|
851
|
+
with pytest.raises(ValueError, match=message):
|
852
|
+
monte_carlo_test(sample, stats.norm.rvs, non_vectorized_statistic)
|
853
|
+
with pytest.raises(ValueError, match=message):
|
854
|
+
monte_carlo_test(sample, stats.norm.rvs, xp.mean, vectorized=False)
|
855
|
+
|
856
|
+
@pytest.mark.xslow
|
857
|
+
def test_batch(self, xp):
|
858
|
+
# make sure that the `batch` parameter is respected by checking the
|
859
|
+
# maximum batch size provided in calls to `statistic`
|
860
|
+
rng = np.random.default_rng(23492340193)
|
861
|
+
x = xp.asarray(rng.standard_normal(size=10))
|
862
|
+
|
863
|
+
def statistic(x, axis):
|
864
|
+
batch_size = 1 if x.ndim == 1 else x.shape[0]
|
865
|
+
statistic.batch_size = max(batch_size, statistic.batch_size)
|
866
|
+
statistic.counter += 1
|
867
|
+
return self.get_statistic(xp)(x, axis=axis)
|
868
|
+
statistic.counter = 0
|
869
|
+
statistic.batch_size = 0
|
870
|
+
|
871
|
+
kwds = {'sample': x, 'statistic': statistic,
|
872
|
+
'n_resamples': 1000, 'vectorized': True}
|
873
|
+
|
874
|
+
kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
|
875
|
+
res1 = monte_carlo_test(batch=1, **kwds)
|
876
|
+
assert_equal(statistic.counter, 1001)
|
877
|
+
assert_equal(statistic.batch_size, 1)
|
878
|
+
|
879
|
+
kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
|
880
|
+
statistic.counter = 0
|
881
|
+
res2 = monte_carlo_test(batch=50, **kwds)
|
882
|
+
assert_equal(statistic.counter, 21)
|
883
|
+
assert_equal(statistic.batch_size, 50)
|
884
|
+
|
885
|
+
kwds['rvs'] = self.get_rvs(stats.norm.rvs, np.random.default_rng(328423), xp=xp)
|
886
|
+
statistic.counter = 0
|
887
|
+
res3 = monte_carlo_test(**kwds)
|
888
|
+
assert_equal(statistic.counter, 2)
|
889
|
+
assert_equal(statistic.batch_size, 1000)
|
890
|
+
|
891
|
+
xp_assert_equal(res1.pvalue, res3.pvalue)
|
892
|
+
xp_assert_equal(res2.pvalue, res3.pvalue)
|
893
|
+
|
894
|
+
@pytest.mark.parametrize('axis', range(-3, 3))
|
895
|
+
def test_axis_dtype(self, axis, xp):
|
896
|
+
# test that Nd-array samples are handled correctly for valid values
|
897
|
+
# of the `axis` parameter; also make sure non-default dtype is maintained
|
898
|
+
rng = np.random.default_rng(2389234)
|
899
|
+
size = [2, 3, 4]
|
900
|
+
size[axis] = 100
|
901
|
+
|
902
|
+
# Determine non-default dtype
|
903
|
+
dtype_default = xp.asarray(1.).dtype
|
904
|
+
dtype_str = 'float32'if ("64" in str(dtype_default)) else 'float64'
|
905
|
+
dtype_np = getattr(np, dtype_str)
|
906
|
+
dtype = getattr(xp, dtype_str)
|
907
|
+
|
908
|
+
# ttest_1samp is CPU array-API compatible, but it would be good to
|
909
|
+
# include CuPy in this test. We'll perform ttest_1samp with a
|
910
|
+
# NumPy array, but all the rest with be done with fully array-API
|
911
|
+
# compatible code.
|
912
|
+
x = rng.standard_normal(size=size, dtype=dtype_np)
|
913
|
+
expected = stats.ttest_1samp(x, popmean=0., axis=axis)
|
914
|
+
|
915
|
+
x = xp.asarray(x, dtype=dtype)
|
916
|
+
statistic = self.get_statistic(xp)
|
917
|
+
rvs = self.get_rvs(stats.norm.rvs, rng, dtype=dtype, xp=xp)
|
918
|
+
|
919
|
+
res = monte_carlo_test(x, rvs, statistic, vectorized=True,
|
920
|
+
n_resamples=20000, axis=axis)
|
921
|
+
|
922
|
+
ref_statistic = xp.asarray(expected.statistic, dtype=dtype)
|
923
|
+
ref_pvalue = xp.asarray(expected.pvalue, dtype=dtype)
|
924
|
+
xp_assert_close(res.statistic, ref_statistic)
|
925
|
+
xp_assert_close(res.pvalue, ref_pvalue, atol=self.atol)
|
926
|
+
|
927
|
+
@pytest.mark.parametrize('alternative', ("two-sided", "less", "greater"))
|
928
|
+
def test_alternative(self, alternative, xp):
|
929
|
+
# test that `alternative` is working as expected
|
930
|
+
rng = np.random.default_rng(65723433)
|
931
|
+
|
932
|
+
x = rng.standard_normal(size=30)
|
933
|
+
ref = stats.ttest_1samp(x, 0., alternative=alternative)
|
934
|
+
|
935
|
+
x = xp.asarray(x)
|
936
|
+
statistic = self.get_statistic(xp)
|
937
|
+
rvs = self.get_rvs(stats.norm.rvs, rng, xp=xp)
|
938
|
+
|
939
|
+
res = monte_carlo_test(x, rvs, statistic, alternative=alternative)
|
940
|
+
|
941
|
+
xp_assert_close(res.statistic, xp.asarray(ref.statistic))
|
942
|
+
xp_assert_close(res.pvalue, xp.asarray(ref.pvalue), atol=self.atol)
|
943
|
+
|
944
|
+
|
945
|
+
# Tests below involve statistics that are not yet array-API compatible.
|
946
|
+
# They can be converted when the statistics are converted.
|
947
|
+
@pytest.mark.slow
|
948
|
+
@pytest.mark.parametrize('alternative', ("less", "greater"))
|
949
|
+
@pytest.mark.parametrize('a', np.linspace(-0.5, 0.5, 5)) # skewness
|
950
|
+
def test_against_ks_1samp(self, alternative, a):
|
951
|
+
# test that monte_carlo_test can reproduce pvalue of ks_1samp
|
952
|
+
rng = np.random.default_rng(65723433)
|
953
|
+
|
954
|
+
x = stats.skewnorm.rvs(a=a, size=30, random_state=rng)
|
955
|
+
expected = stats.ks_1samp(x, stats.norm.cdf, alternative=alternative)
|
956
|
+
|
957
|
+
def statistic1d(x):
|
958
|
+
return stats.ks_1samp(x, stats.norm.cdf, mode='asymp',
|
959
|
+
alternative=alternative).statistic
|
960
|
+
|
961
|
+
norm_rvs = self.get_rvs(stats.norm.rvs, rng)
|
962
|
+
res = monte_carlo_test(x, norm_rvs, statistic1d,
|
963
|
+
n_resamples=1000, vectorized=False,
|
964
|
+
alternative=alternative)
|
965
|
+
|
966
|
+
assert_allclose(res.statistic, expected.statistic)
|
967
|
+
if alternative == 'greater':
|
968
|
+
assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
|
969
|
+
elif alternative == 'less':
|
970
|
+
assert_allclose(1-res.pvalue, expected.pvalue, atol=self.atol)
|
971
|
+
|
972
|
+
@pytest.mark.parametrize('hypotest', (stats.skewtest, stats.kurtosistest))
|
973
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
974
|
+
@pytest.mark.parametrize('a', np.linspace(-2, 2, 5)) # skewness
|
975
|
+
def test_against_normality_tests(self, hypotest, alternative, a):
|
976
|
+
# test that monte_carlo_test can reproduce pvalue of normality tests
|
977
|
+
rng = np.random.default_rng(85723405)
|
978
|
+
|
979
|
+
x = stats.skewnorm.rvs(a=a, size=150, random_state=rng)
|
980
|
+
expected = hypotest(x, alternative=alternative)
|
981
|
+
|
982
|
+
def statistic(x, axis):
|
983
|
+
return hypotest(x, axis=axis).statistic
|
984
|
+
|
985
|
+
norm_rvs = self.get_rvs(stats.norm.rvs, rng)
|
986
|
+
res = monte_carlo_test(x, norm_rvs, statistic, vectorized=True,
|
987
|
+
alternative=alternative)
|
988
|
+
|
989
|
+
assert_allclose(res.statistic, expected.statistic)
|
990
|
+
assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
|
991
|
+
|
992
|
+
@pytest.mark.parametrize('a', np.arange(-2, 3)) # skewness parameter
|
993
|
+
def test_against_normaltest(self, a):
|
994
|
+
# test that monte_carlo_test can reproduce pvalue of normaltest
|
995
|
+
rng = np.random.default_rng(12340513)
|
996
|
+
|
997
|
+
x = stats.skewnorm.rvs(a=a, size=150, random_state=rng)
|
998
|
+
expected = stats.normaltest(x)
|
999
|
+
|
1000
|
+
def statistic(x, axis):
|
1001
|
+
return stats.normaltest(x, axis=axis).statistic
|
1002
|
+
|
1003
|
+
norm_rvs = self.get_rvs(stats.norm.rvs, rng)
|
1004
|
+
res = monte_carlo_test(x, norm_rvs, statistic, vectorized=True,
|
1005
|
+
alternative='greater')
|
1006
|
+
|
1007
|
+
assert_allclose(res.statistic, expected.statistic)
|
1008
|
+
assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
|
1009
|
+
|
1010
|
+
@pytest.mark.xslow
|
1011
|
+
@pytest.mark.parametrize('a', np.linspace(-0.5, 0.5, 5)) # skewness
|
1012
|
+
def test_against_cramervonmises(self, a):
|
1013
|
+
# test that monte_carlo_test can reproduce pvalue of cramervonmises
|
1014
|
+
rng = np.random.default_rng(234874135)
|
1015
|
+
|
1016
|
+
x = stats.skewnorm.rvs(a=a, size=30, random_state=rng)
|
1017
|
+
expected = stats.cramervonmises(x, stats.norm.cdf)
|
1018
|
+
|
1019
|
+
def statistic1d(x):
|
1020
|
+
return stats.cramervonmises(x, stats.norm.cdf).statistic
|
1021
|
+
|
1022
|
+
norm_rvs = self.get_rvs(stats.norm.rvs, rng)
|
1023
|
+
res = monte_carlo_test(x, norm_rvs, statistic1d,
|
1024
|
+
n_resamples=1000, vectorized=False,
|
1025
|
+
alternative='greater')
|
1026
|
+
|
1027
|
+
assert_allclose(res.statistic, expected.statistic)
|
1028
|
+
assert_allclose(res.pvalue, expected.pvalue, atol=self.atol)
|
1029
|
+
|
1030
|
+
@pytest.mark.slow
|
1031
|
+
@pytest.mark.parametrize('dist_name', ('norm', 'logistic'))
|
1032
|
+
@pytest.mark.parametrize('i', range(5))
|
1033
|
+
def test_against_anderson(self, dist_name, i):
|
1034
|
+
# test that monte_carlo_test can reproduce results of `anderson`. Note:
|
1035
|
+
# `anderson` does not provide a p-value; it provides a list of
|
1036
|
+
# significance levels and the associated critical value of the test
|
1037
|
+
# statistic. `i` used to index this list.
|
1038
|
+
|
1039
|
+
# find the skewness for which the sample statistic matches one of the
|
1040
|
+
# critical values provided by `stats.anderson`
|
1041
|
+
|
1042
|
+
def fun(a):
|
1043
|
+
rng = np.random.default_rng(394295467)
|
1044
|
+
x = stats.tukeylambda.rvs(a, size=100, random_state=rng)
|
1045
|
+
expected = stats.anderson(x, dist_name)
|
1046
|
+
return expected.statistic - expected.critical_values[i]
|
1047
|
+
with suppress_warnings() as sup:
|
1048
|
+
sup.filter(RuntimeWarning)
|
1049
|
+
sol = root(fun, x0=0)
|
1050
|
+
assert sol.success
|
1051
|
+
|
1052
|
+
# get the significance level (p-value) associated with that critical
|
1053
|
+
# value
|
1054
|
+
a = sol.x[0]
|
1055
|
+
rng = np.random.default_rng(394295467)
|
1056
|
+
x = stats.tukeylambda.rvs(a, size=100, random_state=rng)
|
1057
|
+
expected = stats.anderson(x, dist_name)
|
1058
|
+
expected_stat = expected.statistic
|
1059
|
+
expected_p = expected.significance_level[i]/100
|
1060
|
+
|
1061
|
+
# perform equivalent Monte Carlo test and compare results
|
1062
|
+
def statistic1d(x):
|
1063
|
+
return stats.anderson(x, dist_name).statistic
|
1064
|
+
|
1065
|
+
dist_rvs = self.get_rvs(getattr(stats, dist_name).rvs, rng)
|
1066
|
+
with suppress_warnings() as sup:
|
1067
|
+
sup.filter(RuntimeWarning)
|
1068
|
+
res = monte_carlo_test(x, dist_rvs,
|
1069
|
+
statistic1d, n_resamples=1000,
|
1070
|
+
vectorized=False, alternative='greater')
|
1071
|
+
|
1072
|
+
assert_allclose(res.statistic, expected_stat)
|
1073
|
+
assert_allclose(res.pvalue, expected_p, atol=2*self.atol)
|
1074
|
+
|
1075
|
+
def test_p_never_zero(self):
|
1076
|
+
# Use biased estimate of p-value to ensure that p-value is never zero
|
1077
|
+
# per monte_carlo_test reference [1]
|
1078
|
+
rng = np.random.default_rng(2190176673029737545)
|
1079
|
+
x = np.zeros(100)
|
1080
|
+
res = monte_carlo_test(x, rng.random, np.mean,
|
1081
|
+
vectorized=True, alternative='less')
|
1082
|
+
assert res.pvalue == 0.0001
|
1083
|
+
|
1084
|
+
def test_against_ttest_ind(self):
|
1085
|
+
# test that `monte_carlo_test` can reproduce results of `ttest_ind`.
|
1086
|
+
rng = np.random.default_rng(219017667302737545)
|
1087
|
+
data = rng.random(size=(2, 5)), rng.random(size=7) # broadcastable
|
1088
|
+
rvs = rng.normal, rng.normal
|
1089
|
+
def statistic(x, y, axis):
|
1090
|
+
return stats.ttest_ind(x, y, axis=axis).statistic
|
1091
|
+
|
1092
|
+
res = stats.monte_carlo_test(data, rvs, statistic, axis=-1)
|
1093
|
+
ref = stats.ttest_ind(data[0], [data[1]], axis=-1)
|
1094
|
+
assert_allclose(res.statistic, ref.statistic)
|
1095
|
+
assert_allclose(res.pvalue, ref.pvalue, rtol=2e-2)
|
1096
|
+
|
1097
|
+
def test_against_f_oneway(self):
|
1098
|
+
# test that `monte_carlo_test` can reproduce results of `f_oneway`.
|
1099
|
+
rng = np.random.default_rng(219017667302737545)
|
1100
|
+
data = (rng.random(size=(2, 100)), rng.random(size=(2, 101)),
|
1101
|
+
rng.random(size=(2, 102)), rng.random(size=(2, 103)))
|
1102
|
+
rvs = rng.normal, rng.normal, rng.normal, rng.normal
|
1103
|
+
|
1104
|
+
def statistic(*args, axis):
|
1105
|
+
return stats.f_oneway(*args, axis=axis).statistic
|
1106
|
+
|
1107
|
+
res = stats.monte_carlo_test(data, rvs, statistic, axis=-1,
|
1108
|
+
alternative='greater')
|
1109
|
+
ref = stats.f_oneway(*data, axis=-1)
|
1110
|
+
|
1111
|
+
assert_allclose(res.statistic, ref.statistic)
|
1112
|
+
assert_allclose(res.pvalue, ref.pvalue, atol=1e-2)
|
1113
|
+
|
1114
|
+
@pytest.mark.fail_slow(2)
|
1115
|
+
@pytest.mark.xfail_on_32bit("Statistic may not depend on sample order on 32-bit")
|
1116
|
+
def test_finite_precision_statistic(self):
|
1117
|
+
# Some statistics return numerically distinct values when the values
|
1118
|
+
# should be equal in theory. Test that `monte_carlo_test` accounts
|
1119
|
+
# for this in some way.
|
1120
|
+
rng = np.random.default_rng(2549824598234528)
|
1121
|
+
n_resamples = 9999
|
1122
|
+
def rvs(size):
|
1123
|
+
return 1. * stats.bernoulli(p=0.333).rvs(size=size, random_state=rng)
|
1124
|
+
|
1125
|
+
x = rvs(100)
|
1126
|
+
res = stats.monte_carlo_test(x, rvs, np.var, alternative='less',
|
1127
|
+
n_resamples=n_resamples)
|
1128
|
+
# show that having a tolerance matters
|
1129
|
+
c0 = np.sum(res.null_distribution <= res.statistic)
|
1130
|
+
c1 = np.sum(res.null_distribution <= res.statistic*(1+1e-15))
|
1131
|
+
assert c0 != c1
|
1132
|
+
assert res.pvalue == (c1 + 1)/(n_resamples + 1)
|
1133
|
+
|
1134
|
+
|
1135
|
+
class TestPower:
|
1136
|
+
def test_input_validation(self):
|
1137
|
+
# test that the appropriate error messages are raised for invalid input
|
1138
|
+
rng = np.random.default_rng(8519895914314711673)
|
1139
|
+
|
1140
|
+
test = stats.ttest_ind
|
1141
|
+
rvs = (rng.normal, rng.normal)
|
1142
|
+
n_observations = (10, 12)
|
1143
|
+
|
1144
|
+
message = "`vectorized` must be `True`, `False`, or `None`."
|
1145
|
+
with pytest.raises(ValueError, match=message):
|
1146
|
+
power(test, rvs, n_observations, vectorized=1.5)
|
1147
|
+
|
1148
|
+
message = "`rvs` must be callable or sequence of callables."
|
1149
|
+
with pytest.raises(TypeError, match=message):
|
1150
|
+
power(test, None, n_observations)
|
1151
|
+
with pytest.raises(TypeError, match=message):
|
1152
|
+
power(test, (rng.normal, 'ekki'), n_observations)
|
1153
|
+
|
1154
|
+
message = "If `rvs` is a sequence..."
|
1155
|
+
with pytest.raises(ValueError, match=message):
|
1156
|
+
power(test, (rng.normal,), n_observations)
|
1157
|
+
with pytest.raises(ValueError, match=message):
|
1158
|
+
power(test, rvs, (10,))
|
1159
|
+
|
1160
|
+
message = "`significance` must contain floats between 0 and 1."
|
1161
|
+
with pytest.raises(ValueError, match=message):
|
1162
|
+
power(test, rvs, n_observations, significance=2)
|
1163
|
+
with pytest.raises(ValueError, match=message):
|
1164
|
+
power(test, rvs, n_observations, significance=np.linspace(-1, 1))
|
1165
|
+
|
1166
|
+
message = "`kwargs` must be a dictionary"
|
1167
|
+
with pytest.raises(TypeError, match=message):
|
1168
|
+
power(test, rvs, n_observations, kwargs=(1, 2, 3))
|
1169
|
+
|
1170
|
+
message = "shape mismatch: objects cannot be broadcast"
|
1171
|
+
with pytest.raises(ValueError, match=message):
|
1172
|
+
power(test, rvs, ([10, 11], [12, 13, 14]))
|
1173
|
+
with pytest.raises(ValueError, match=message):
|
1174
|
+
power(test, rvs, ([10, 11], [12, 13]), kwargs={'x': [1, 2, 3]})
|
1175
|
+
|
1176
|
+
message = "`test` must be callable"
|
1177
|
+
with pytest.raises(TypeError, match=message):
|
1178
|
+
power(None, rvs, n_observations)
|
1179
|
+
|
1180
|
+
message = "`n_resamples` must be a positive integer"
|
1181
|
+
with pytest.raises(ValueError, match=message):
|
1182
|
+
power(test, rvs, n_observations, n_resamples=-10)
|
1183
|
+
with pytest.raises(ValueError, match=message):
|
1184
|
+
power(test, rvs, n_observations, n_resamples=10.5)
|
1185
|
+
|
1186
|
+
message = "`batch` must be a positive integer"
|
1187
|
+
with pytest.raises(ValueError, match=message):
|
1188
|
+
power(test, rvs, n_observations, batch=-10)
|
1189
|
+
with pytest.raises(ValueError, match=message):
|
1190
|
+
power(test, rvs, n_observations, batch=10.5)
|
1191
|
+
|
1192
|
+
@pytest.mark.slow
|
1193
|
+
def test_batch(self):
|
1194
|
+
# make sure that the `batch` parameter is respected by checking the
|
1195
|
+
# maximum batch size provided in calls to `test`
|
1196
|
+
rng = np.random.default_rng(23492340193)
|
1197
|
+
|
1198
|
+
def test(x, axis):
|
1199
|
+
batch_size = 1 if x.ndim == 1 else len(x)
|
1200
|
+
test.batch_size = max(batch_size, test.batch_size)
|
1201
|
+
test.counter += 1
|
1202
|
+
return stats.ttest_1samp(x, 0, axis=axis).pvalue
|
1203
|
+
test.counter = 0
|
1204
|
+
test.batch_size = 0
|
1205
|
+
|
1206
|
+
kwds = dict(test=test, n_observations=10, n_resamples=1000)
|
1207
|
+
|
1208
|
+
rng = np.random.default_rng(23492340193)
|
1209
|
+
res1 = power(**kwds, rvs=rng.normal, batch=1)
|
1210
|
+
assert_equal(test.counter, 1000)
|
1211
|
+
assert_equal(test.batch_size, 1)
|
1212
|
+
|
1213
|
+
rng = np.random.default_rng(23492340193)
|
1214
|
+
test.counter = 0
|
1215
|
+
res2 = power(**kwds, rvs=rng.normal, batch=50)
|
1216
|
+
assert_equal(test.counter, 20)
|
1217
|
+
assert_equal(test.batch_size, 50)
|
1218
|
+
|
1219
|
+
rng = np.random.default_rng(23492340193)
|
1220
|
+
test.counter = 0
|
1221
|
+
res3 = power(**kwds, rvs=rng.normal, batch=1000)
|
1222
|
+
assert_equal(test.counter, 1)
|
1223
|
+
assert_equal(test.batch_size, 1000)
|
1224
|
+
|
1225
|
+
assert_equal(res1.power, res3.power)
|
1226
|
+
assert_equal(res2.power, res3.power)
|
1227
|
+
|
1228
|
+
@pytest.mark.slow
|
1229
|
+
def test_vectorization(self):
|
1230
|
+
# Test that `power` is vectorized as expected
|
1231
|
+
rng = np.random.default_rng(25495254834552)
|
1232
|
+
|
1233
|
+
# Single vectorized call
|
1234
|
+
popmeans = np.array([0, 0.2])
|
1235
|
+
def test(x, alternative, axis=-1):
|
1236
|
+
# ensure that popmeans axis is zeroth and orthogonal to the rest
|
1237
|
+
popmeans_expanded = np.expand_dims(popmeans, tuple(range(1, x.ndim + 1)))
|
1238
|
+
return stats.ttest_1samp(x, popmeans_expanded, alternative=alternative,
|
1239
|
+
axis=axis)
|
1240
|
+
|
1241
|
+
# nx and kwargs broadcast against one another
|
1242
|
+
nx = np.asarray([10, 15, 20, 50, 100])[:, np.newaxis]
|
1243
|
+
kwargs = {'alternative': ['less', 'greater', 'two-sided']}
|
1244
|
+
|
1245
|
+
# This dimension is added to the beginning
|
1246
|
+
significance = np.asarray([0.01, 0.025, 0.05, 0.1])
|
1247
|
+
res = stats.power(test, rng.normal, nx, significance=significance,
|
1248
|
+
kwargs=kwargs)
|
1249
|
+
|
1250
|
+
# Looping over all combinations
|
1251
|
+
ref = []
|
1252
|
+
for significance_i in significance:
|
1253
|
+
for nx_i in nx:
|
1254
|
+
for alternative_i in kwargs['alternative']:
|
1255
|
+
for popmean_i in popmeans:
|
1256
|
+
def test2(x, axis=-1):
|
1257
|
+
return stats.ttest_1samp(x, popmean_i, axis=axis,
|
1258
|
+
alternative=alternative_i)
|
1259
|
+
|
1260
|
+
tmp = stats.power(test2, rng.normal, nx_i,
|
1261
|
+
significance=significance_i)
|
1262
|
+
ref.append(tmp.power)
|
1263
|
+
ref = np.reshape(ref, res.power.shape)
|
1264
|
+
|
1265
|
+
# Show that results are similar
|
1266
|
+
assert_allclose(res.power, ref, rtol=2e-2, atol=1e-2)
|
1267
|
+
|
1268
|
+
def test_ttest_ind_null(self):
|
1269
|
+
# Check that the p-values of `ttest_ind` are uniformly distributed under
|
1270
|
+
# the null hypothesis
|
1271
|
+
rng = np.random.default_rng(254952548345528)
|
1272
|
+
|
1273
|
+
test = stats.ttest_ind
|
1274
|
+
n_observations = rng.integers(10, 100, size=(2, 10))
|
1275
|
+
rvs = rng.normal, rng.normal
|
1276
|
+
significance = np.asarray([0.01, 0.05, 0.1])
|
1277
|
+
res = stats.power(test, rvs, n_observations, significance=significance)
|
1278
|
+
significance = np.broadcast_to(significance[:, np.newaxis], res.power.shape)
|
1279
|
+
assert_allclose(res.power, significance, atol=1e-2)
|
1280
|
+
|
1281
|
+
def test_ttest_1samp_power(self):
|
1282
|
+
# Check simulated ttest_1samp power against reference
|
1283
|
+
rng = np.random.default_rng(254952548345528)
|
1284
|
+
|
1285
|
+
# Reference values computed with statmodels
|
1286
|
+
# import numpy as np
|
1287
|
+
# from statsmodels.stats.power import tt_solve_power
|
1288
|
+
# tt_solve_power = np.vectorize(tt_solve_power)
|
1289
|
+
# tt_solve_power([0.1, 0.5, 0.9], [[10], [20]], [[[0.01]], [[0.05]]])
|
1290
|
+
ref = [[[0.0126515 , 0.10269751, 0.40415802],
|
1291
|
+
[0.01657775, 0.29734608, 0.86228288]],
|
1292
|
+
[[0.0592903 , 0.29317561, 0.71718121],
|
1293
|
+
[0.07094116, 0.56450441, 0.96815163]]]
|
1294
|
+
|
1295
|
+
kwargs = {'popmean': [0.1, 0.5, 0.9]}
|
1296
|
+
n_observations = [[10], [20]]
|
1297
|
+
significance = [0.01, 0.05]
|
1298
|
+
res = stats.power(stats.ttest_1samp, rng.normal, n_observations,
|
1299
|
+
significance=significance, kwargs=kwargs)
|
1300
|
+
assert_allclose(res.power, ref, atol=1e-2)
|
1301
|
+
|
1302
|
+
|
1303
|
+
class TestPermutationTest:
|
1304
|
+
|
1305
|
+
rtol = 1e-14
|
1306
|
+
|
1307
|
+
def setup_method(self):
|
1308
|
+
self.rng = np.random.default_rng(7170559330470561044)
|
1309
|
+
|
1310
|
+
# -- Input validation -- #
|
1311
|
+
|
1312
|
+
def test_permutation_test_iv(self):
|
1313
|
+
|
1314
|
+
def stat(x, y, axis):
|
1315
|
+
return stats.ttest_ind((x, y), axis).statistic
|
1316
|
+
|
1317
|
+
message = "each sample in `data` must contain two or more ..."
|
1318
|
+
with pytest.raises(ValueError, match=message):
|
1319
|
+
permutation_test(([1, 2, 3], [1]), stat)
|
1320
|
+
|
1321
|
+
message = "`data` must be a tuple containing at least two samples"
|
1322
|
+
with pytest.raises(ValueError, match=message):
|
1323
|
+
permutation_test((1,), stat)
|
1324
|
+
with pytest.raises(TypeError, match=message):
|
1325
|
+
permutation_test(1, stat)
|
1326
|
+
|
1327
|
+
message = "`axis` must be an integer."
|
1328
|
+
with pytest.raises(ValueError, match=message):
|
1329
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, axis=1.5)
|
1330
|
+
|
1331
|
+
message = "`permutation_type` must be in..."
|
1332
|
+
with pytest.raises(ValueError, match=message):
|
1333
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat,
|
1334
|
+
permutation_type="ekki")
|
1335
|
+
|
1336
|
+
message = "`vectorized` must be `True`, `False`, or `None`."
|
1337
|
+
with pytest.raises(ValueError, match=message):
|
1338
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, vectorized=1.5)
|
1339
|
+
|
1340
|
+
message = "`n_resamples` must be a positive integer."
|
1341
|
+
with pytest.raises(ValueError, match=message):
|
1342
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, n_resamples=-1000)
|
1343
|
+
|
1344
|
+
message = "`n_resamples` must be a positive integer."
|
1345
|
+
with pytest.raises(ValueError, match=message):
|
1346
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, n_resamples=1000.5)
|
1347
|
+
|
1348
|
+
message = "`batch` must be a positive integer or None."
|
1349
|
+
with pytest.raises(ValueError, match=message):
|
1350
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, batch=-1000)
|
1351
|
+
|
1352
|
+
message = "`batch` must be a positive integer or None."
|
1353
|
+
with pytest.raises(ValueError, match=message):
|
1354
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, batch=1000.5)
|
1355
|
+
|
1356
|
+
message = "`alternative` must be in..."
|
1357
|
+
with pytest.raises(ValueError, match=message):
|
1358
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, alternative='ekki')
|
1359
|
+
|
1360
|
+
message = "SeedSequence expects int or sequence of ints"
|
1361
|
+
with pytest.raises(TypeError, match=message):
|
1362
|
+
permutation_test(([1, 2, 3], [1, 2, 3]), stat, rng='herring')
|
1363
|
+
|
1364
|
+
# -- Test Parameters -- #
|
1365
|
+
# SPEC-007 leave one call with seed to check it still works
|
1366
|
+
@pytest.mark.parametrize('random_state', [np.random.RandomState,
|
1367
|
+
np.random.default_rng])
|
1368
|
+
@pytest.mark.parametrize('permutation_type',
|
1369
|
+
['pairings', 'samples', 'independent'])
|
1370
|
+
def test_batch(self, permutation_type, random_state):
|
1371
|
+
# make sure that the `batch` parameter is respected by checking the
|
1372
|
+
# maximum batch size provided in calls to `statistic`
|
1373
|
+
x = self.rng.random(10)
|
1374
|
+
y = self.rng.random(10)
|
1375
|
+
|
1376
|
+
def statistic(x, y, axis):
|
1377
|
+
batch_size = 1 if x.ndim == 1 else len(x)
|
1378
|
+
statistic.batch_size = max(batch_size, statistic.batch_size)
|
1379
|
+
statistic.counter += 1
|
1380
|
+
return np.mean(x, axis=axis) - np.mean(y, axis=axis)
|
1381
|
+
statistic.counter = 0
|
1382
|
+
statistic.batch_size = 0
|
1383
|
+
|
1384
|
+
kwds = {'n_resamples': 1000, 'permutation_type': permutation_type,
|
1385
|
+
'vectorized': True}
|
1386
|
+
res1 = stats.permutation_test((x, y), statistic, batch=1,
|
1387
|
+
random_state=random_state(0), **kwds)
|
1388
|
+
assert_equal(statistic.counter, 1001)
|
1389
|
+
assert_equal(statistic.batch_size, 1)
|
1390
|
+
|
1391
|
+
statistic.counter = 0
|
1392
|
+
res2 = stats.permutation_test((x, y), statistic, batch=50,
|
1393
|
+
random_state=random_state(0), **kwds)
|
1394
|
+
assert_equal(statistic.counter, 21)
|
1395
|
+
assert_equal(statistic.batch_size, 50)
|
1396
|
+
|
1397
|
+
statistic.counter = 0
|
1398
|
+
res3 = stats.permutation_test((x, y), statistic, batch=1000,
|
1399
|
+
random_state=random_state(0), **kwds)
|
1400
|
+
assert_equal(statistic.counter, 2)
|
1401
|
+
assert_equal(statistic.batch_size, 1000)
|
1402
|
+
|
1403
|
+
assert_equal(res1.pvalue, res3.pvalue)
|
1404
|
+
assert_equal(res2.pvalue, res3.pvalue)
|
1405
|
+
|
1406
|
+
# SPEC-007 leave at least one call with seed to check it still works
|
1407
|
+
@pytest.mark.parametrize('random_state', [np.random.RandomState,
|
1408
|
+
np.random.default_rng])
|
1409
|
+
@pytest.mark.parametrize('permutation_type, exact_size',
|
1410
|
+
[('pairings', special.factorial(3)**2),
|
1411
|
+
('samples', 2**3),
|
1412
|
+
('independent', special.binom(6, 3))])
|
1413
|
+
def test_permutations(self, permutation_type, exact_size, random_state):
|
1414
|
+
# make sure that the `permutations` parameter is respected by checking
|
1415
|
+
# the size of the null distribution
|
1416
|
+
x = self.rng.random(3)
|
1417
|
+
y = self.rng.random(3)
|
1418
|
+
|
1419
|
+
def statistic(x, y, axis):
|
1420
|
+
return np.mean(x, axis=axis) - np.mean(y, axis=axis)
|
1421
|
+
|
1422
|
+
kwds = {'permutation_type': permutation_type,
|
1423
|
+
'vectorized': True}
|
1424
|
+
res = stats.permutation_test((x, y), statistic, n_resamples=3,
|
1425
|
+
random_state=random_state(0), **kwds)
|
1426
|
+
assert_equal(res.null_distribution.size, 3)
|
1427
|
+
|
1428
|
+
res = stats.permutation_test((x, y), statistic, **kwds)
|
1429
|
+
assert_equal(res.null_distribution.size, exact_size)
|
1430
|
+
|
1431
|
+
# -- Randomized Permutation Tests -- #
|
1432
|
+
|
1433
|
+
# To get reasonable accuracy, these next three tests are somewhat slow.
|
1434
|
+
# Originally, I had them passing for all combinations of permutation type,
|
1435
|
+
# alternative, and RNG, but that takes too long for CI. Instead, split
|
1436
|
+
# into three tests, each testing a particular combination of the three
|
1437
|
+
# parameters.
|
1438
|
+
|
1439
|
+
def test_randomized_test_against_exact_both(self):
|
1440
|
+
# check that the randomized and exact tests agree to reasonable
|
1441
|
+
# precision for permutation_type='both
|
1442
|
+
|
1443
|
+
alternative, rng = 'less', 0
|
1444
|
+
|
1445
|
+
nx, ny, permutations = 8, 9, 24000
|
1446
|
+
assert special.binom(nx + ny, nx) > permutations
|
1447
|
+
|
1448
|
+
x = stats.norm.rvs(size=nx)
|
1449
|
+
y = stats.norm.rvs(size=ny)
|
1450
|
+
data = x, y
|
1451
|
+
|
1452
|
+
def statistic(x, y, axis):
|
1453
|
+
return np.mean(x, axis=axis) - np.mean(y, axis=axis)
|
1454
|
+
|
1455
|
+
kwds = {'vectorized': True, 'permutation_type': 'independent',
|
1456
|
+
'batch': 100, 'alternative': alternative, 'rng': rng}
|
1457
|
+
res = permutation_test(data, statistic, n_resamples=permutations,
|
1458
|
+
**kwds)
|
1459
|
+
res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
|
1460
|
+
|
1461
|
+
assert res.statistic == res2.statistic
|
1462
|
+
assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
|
1463
|
+
|
1464
|
+
@pytest.mark.slow()
|
1465
|
+
def test_randomized_test_against_exact_samples(self):
|
1466
|
+
# check that the randomized and exact tests agree to reasonable
|
1467
|
+
# precision for permutation_type='samples'
|
1468
|
+
|
1469
|
+
alternative, rng = 'greater', None
|
1470
|
+
|
1471
|
+
nx, ny, permutations = 15, 15, 32000
|
1472
|
+
assert 2**nx > permutations
|
1473
|
+
|
1474
|
+
x = stats.norm.rvs(size=nx)
|
1475
|
+
y = stats.norm.rvs(size=ny)
|
1476
|
+
data = x, y
|
1477
|
+
|
1478
|
+
def statistic(x, y, axis):
|
1479
|
+
return np.mean(x - y, axis=axis)
|
1480
|
+
|
1481
|
+
kwds = {'vectorized': True, 'permutation_type': 'samples',
|
1482
|
+
'batch': 100, 'alternative': alternative, 'rng': rng}
|
1483
|
+
res = permutation_test(data, statistic, n_resamples=permutations,
|
1484
|
+
**kwds)
|
1485
|
+
res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
|
1486
|
+
|
1487
|
+
assert res.statistic == res2.statistic
|
1488
|
+
assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
|
1489
|
+
|
1490
|
+
def test_randomized_test_against_exact_pairings(self):
|
1491
|
+
# check that the randomized and exact tests agree to reasonable
|
1492
|
+
# precision for permutation_type='pairings'
|
1493
|
+
|
1494
|
+
alternative, rng = 'two-sided', self.rng
|
1495
|
+
|
1496
|
+
nx, ny, permutations = 8, 8, 40000
|
1497
|
+
assert special.factorial(nx) > permutations
|
1498
|
+
|
1499
|
+
x = stats.norm.rvs(size=nx)
|
1500
|
+
y = stats.norm.rvs(size=ny)
|
1501
|
+
data = [x]
|
1502
|
+
|
1503
|
+
def statistic1d(x):
|
1504
|
+
return stats.pearsonr(x, y)[0]
|
1505
|
+
|
1506
|
+
statistic = _resampling._vectorize_statistic(statistic1d)
|
1507
|
+
|
1508
|
+
kwds = {'vectorized': True, 'permutation_type': 'samples',
|
1509
|
+
'batch': 100, 'alternative': alternative, 'rng': rng}
|
1510
|
+
res = permutation_test(data, statistic, n_resamples=permutations,
|
1511
|
+
**kwds)
|
1512
|
+
res2 = permutation_test(data, statistic, n_resamples=np.inf, **kwds)
|
1513
|
+
|
1514
|
+
assert res.statistic == res2.statistic
|
1515
|
+
assert_allclose(res.pvalue, res2.pvalue, atol=1e-2)
|
1516
|
+
|
1517
|
+
# -- Independent (Unpaired) Sample Tests -- #
|
1518
|
+
|
1519
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
1520
|
+
def test_against_ks_2samp(self, alternative):
|
1521
|
+
|
1522
|
+
x = self.rng.normal(size=4, scale=1)
|
1523
|
+
y = self.rng.normal(size=5, loc=3, scale=3)
|
1524
|
+
|
1525
|
+
expected = stats.ks_2samp(x, y, alternative=alternative, mode='exact')
|
1526
|
+
|
1527
|
+
def statistic1d(x, y):
|
1528
|
+
return stats.ks_2samp(x, y, mode='asymp',
|
1529
|
+
alternative=alternative).statistic
|
1530
|
+
|
1531
|
+
# ks_2samp is always a one-tailed 'greater' test
|
1532
|
+
# it's the statistic that changes (D+ vs D- vs max(D+, D-))
|
1533
|
+
res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
|
1534
|
+
alternative='greater', rng=self.rng)
|
1535
|
+
|
1536
|
+
assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
|
1537
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1538
|
+
|
1539
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
1540
|
+
def test_against_ansari(self, alternative):
|
1541
|
+
|
1542
|
+
x = self.rng.normal(size=4, scale=1)
|
1543
|
+
y = self.rng.normal(size=5, scale=3)
|
1544
|
+
|
1545
|
+
# ansari has a different convention for 'alternative'
|
1546
|
+
alternative_correspondence = {"less": "greater",
|
1547
|
+
"greater": "less",
|
1548
|
+
"two-sided": "two-sided"}
|
1549
|
+
alternative_scipy = alternative_correspondence[alternative]
|
1550
|
+
expected = stats.ansari(x, y, alternative=alternative_scipy)
|
1551
|
+
|
1552
|
+
def statistic1d(x, y):
|
1553
|
+
return stats.ansari(x, y).statistic
|
1554
|
+
|
1555
|
+
res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
|
1556
|
+
alternative=alternative, rng=self.rng)
|
1557
|
+
|
1558
|
+
assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
|
1559
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1560
|
+
|
1561
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
1562
|
+
def test_against_mannwhitneyu(self, alternative):
|
1563
|
+
|
1564
|
+
x = stats.uniform.rvs(size=(3, 5, 2), loc=0, random_state=self.rng)
|
1565
|
+
y = stats.uniform.rvs(size=(3, 5, 2), loc=0.05, random_state=self.rng)
|
1566
|
+
|
1567
|
+
expected = stats.mannwhitneyu(x, y, axis=1, alternative=alternative)
|
1568
|
+
|
1569
|
+
def statistic(x, y, axis):
|
1570
|
+
return stats.mannwhitneyu(x, y, axis=axis).statistic
|
1571
|
+
|
1572
|
+
res = permutation_test((x, y), statistic, vectorized=True,
|
1573
|
+
n_resamples=np.inf, alternative=alternative,
|
1574
|
+
axis=1, rng=self.rng)
|
1575
|
+
|
1576
|
+
assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
|
1577
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1578
|
+
|
1579
|
+
def test_against_cvm(self):
|
1580
|
+
|
1581
|
+
x = stats.norm.rvs(size=4, scale=1, random_state=self.rng)
|
1582
|
+
y = stats.norm.rvs(size=5, loc=3, scale=3, random_state=self.rng)
|
1583
|
+
|
1584
|
+
expected = stats.cramervonmises_2samp(x, y, method='exact')
|
1585
|
+
|
1586
|
+
def statistic1d(x, y):
|
1587
|
+
return stats.cramervonmises_2samp(x, y,
|
1588
|
+
method='asymptotic').statistic
|
1589
|
+
|
1590
|
+
# cramervonmises_2samp has only one alternative, greater
|
1591
|
+
res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
|
1592
|
+
alternative='greater', rng=self.rng)
|
1593
|
+
|
1594
|
+
assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
|
1595
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1596
|
+
|
1597
|
+
@pytest.mark.xslow()
|
1598
|
+
@pytest.mark.parametrize('axis', (-1, 2))
|
1599
|
+
def test_vectorized_nsamp_ptype_both(self, axis):
|
1600
|
+
# Test that permutation_test with permutation_type='independent' works
|
1601
|
+
# properly for a 3-sample statistic with nd array samples of different
|
1602
|
+
# (but compatible) shapes and ndims. Show that exact permutation test
|
1603
|
+
# and random permutation tests approximate SciPy's asymptotic pvalues
|
1604
|
+
# and that exact and random permutation test results are even closer
|
1605
|
+
# to one another (than they are to the asymptotic results).
|
1606
|
+
|
1607
|
+
# Three samples, different (but compatible) shapes with different ndims
|
1608
|
+
rng = np.random.default_rng(6709265303529651545)
|
1609
|
+
x = rng.random(size=(3))
|
1610
|
+
y = rng.random(size=(1, 3, 2))
|
1611
|
+
z = rng.random(size=(2, 1, 4))
|
1612
|
+
data = (x, y, z)
|
1613
|
+
|
1614
|
+
# Define the statistic (and pvalue for comparison)
|
1615
|
+
def statistic1d(*data):
|
1616
|
+
return stats.kruskal(*data).statistic
|
1617
|
+
|
1618
|
+
def pvalue1d(*data):
|
1619
|
+
return stats.kruskal(*data).pvalue
|
1620
|
+
|
1621
|
+
statistic = _resampling._vectorize_statistic(statistic1d)
|
1622
|
+
pvalue = _resampling._vectorize_statistic(pvalue1d)
|
1623
|
+
|
1624
|
+
# Calculate the expected results
|
1625
|
+
x2 = np.broadcast_to(x, (2, 3, 3)) # broadcast manually because
|
1626
|
+
y2 = np.broadcast_to(y, (2, 3, 2)) # _vectorize_statistic doesn't
|
1627
|
+
z2 = np.broadcast_to(z, (2, 3, 4))
|
1628
|
+
expected_statistic = statistic(x2, y2, z2, axis=axis)
|
1629
|
+
expected_pvalue = pvalue(x2, y2, z2, axis=axis)
|
1630
|
+
|
1631
|
+
# Calculate exact and randomized permutation results
|
1632
|
+
kwds = {'vectorized': False, 'axis': axis, 'alternative': 'greater',
|
1633
|
+
'permutation_type': 'independent', 'rng': self.rng}
|
1634
|
+
res = permutation_test(data, statistic1d, n_resamples=np.inf, **kwds)
|
1635
|
+
res2 = permutation_test(data, statistic1d, n_resamples=1000, **kwds)
|
1636
|
+
|
1637
|
+
# Check results
|
1638
|
+
assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
|
1639
|
+
assert_allclose(res.statistic, res2.statistic, rtol=self.rtol)
|
1640
|
+
assert_allclose(res.pvalue, expected_pvalue, atol=6e-2)
|
1641
|
+
assert_allclose(res.pvalue, res2.pvalue, atol=3e-2)
|
1642
|
+
|
1643
|
+
# -- Paired-Sample Tests -- #
|
1644
|
+
|
1645
|
+
@pytest.mark.slow
|
1646
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
1647
|
+
def test_against_wilcoxon(self, alternative):
|
1648
|
+
|
1649
|
+
x = stats.uniform.rvs(size=(3, 6, 2), loc=0, random_state=self.rng)
|
1650
|
+
y = stats.uniform.rvs(size=(3, 6, 2), loc=0.05, random_state=self.rng)
|
1651
|
+
|
1652
|
+
# We'll check both 1- and 2-sample versions of the same test;
|
1653
|
+
# we expect identical results to wilcoxon in all cases.
|
1654
|
+
def statistic_1samp_1d(z):
|
1655
|
+
# 'less' ensures we get the same of two statistics every time
|
1656
|
+
return stats.wilcoxon(z, alternative='less').statistic
|
1657
|
+
|
1658
|
+
def statistic_2samp_1d(x, y):
|
1659
|
+
return stats.wilcoxon(x, y, alternative='less').statistic
|
1660
|
+
|
1661
|
+
def test_1d(x, y):
|
1662
|
+
return stats.wilcoxon(x, y, alternative=alternative)
|
1663
|
+
|
1664
|
+
test = _resampling._vectorize_statistic(test_1d)
|
1665
|
+
|
1666
|
+
expected = test(x, y, axis=1)
|
1667
|
+
expected_stat = expected[0]
|
1668
|
+
expected_p = expected[1]
|
1669
|
+
|
1670
|
+
kwds = {'vectorized': False, 'axis': 1, 'alternative': alternative,
|
1671
|
+
'permutation_type': 'samples', 'rng': self.rng,
|
1672
|
+
'n_resamples': np.inf}
|
1673
|
+
res1 = permutation_test((x-y,), statistic_1samp_1d, **kwds)
|
1674
|
+
res2 = permutation_test((x, y), statistic_2samp_1d, **kwds)
|
1675
|
+
|
1676
|
+
# `wilcoxon` returns a different statistic with 'two-sided'
|
1677
|
+
assert_allclose(res1.statistic, res2.statistic, rtol=self.rtol)
|
1678
|
+
if alternative != 'two-sided':
|
1679
|
+
assert_allclose(res2.statistic, expected_stat, rtol=self.rtol)
|
1680
|
+
|
1681
|
+
assert_allclose(res2.pvalue, expected_p, rtol=self.rtol)
|
1682
|
+
assert_allclose(res1.pvalue, res2.pvalue, rtol=self.rtol)
|
1683
|
+
|
1684
|
+
@pytest.mark.parametrize('alternative', ("less", "greater", "two-sided"))
|
1685
|
+
def test_against_binomtest(self, alternative):
|
1686
|
+
|
1687
|
+
x = self.rng.integers(0, 2, size=10)
|
1688
|
+
x[x == 0] = -1
|
1689
|
+
# More naturally, the test would flip elements between 0 and one.
|
1690
|
+
# However, permutation_test will flip the _signs_ of the elements.
|
1691
|
+
# So we have to work with +1/-1 instead of 1/0.
|
1692
|
+
|
1693
|
+
def statistic(x, axis=0):
|
1694
|
+
return np.sum(x > 0, axis=axis)
|
1695
|
+
|
1696
|
+
k, n, p = statistic(x), 10, 0.5
|
1697
|
+
expected = stats.binomtest(k, n, p, alternative=alternative)
|
1698
|
+
|
1699
|
+
res = stats.permutation_test((x,), statistic, vectorized=True,
|
1700
|
+
permutation_type='samples',
|
1701
|
+
n_resamples=np.inf, rng=self.rng,
|
1702
|
+
alternative=alternative)
|
1703
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1704
|
+
|
1705
|
+
# -- Exact Association Tests -- #
|
1706
|
+
|
1707
|
+
def test_against_kendalltau(self):
|
1708
|
+
|
1709
|
+
x = self.rng.normal(size=6)
|
1710
|
+
y = x + self.rng.normal(size=6)
|
1711
|
+
|
1712
|
+
expected = stats.kendalltau(x, y, method='exact')
|
1713
|
+
|
1714
|
+
def statistic1d(x):
|
1715
|
+
return stats.kendalltau(x, y, method='asymptotic').statistic
|
1716
|
+
|
1717
|
+
# kendalltau currently has only one alternative, two-sided
|
1718
|
+
res = permutation_test((x,), statistic1d, permutation_type='pairings',
|
1719
|
+
n_resamples=np.inf, rng=self.rng)
|
1720
|
+
|
1721
|
+
assert_allclose(res.statistic, expected.statistic, rtol=self.rtol)
|
1722
|
+
assert_allclose(res.pvalue, expected.pvalue, rtol=self.rtol)
|
1723
|
+
|
1724
|
+
@pytest.mark.parametrize('alternative', ('less', 'greater', 'two-sided'))
|
1725
|
+
def test_against_fisher_exact(self, alternative):
|
1726
|
+
|
1727
|
+
def statistic(x,):
|
1728
|
+
return np.sum((x == 1) & (y == 1))
|
1729
|
+
|
1730
|
+
# x and y are binary random variables with some dependence
|
1731
|
+
rng = np.random.default_rng(6235696159000529929)
|
1732
|
+
x = (rng.random(7) > 0.6).astype(float)
|
1733
|
+
y = (rng.random(7) + 0.25*x > 0.6).astype(float)
|
1734
|
+
tab = stats.contingency.crosstab(x, y)[1]
|
1735
|
+
|
1736
|
+
res = permutation_test((x,), statistic, permutation_type='pairings',
|
1737
|
+
n_resamples=np.inf, alternative=alternative,
|
1738
|
+
rng=rng)
|
1739
|
+
res2 = stats.fisher_exact(tab, alternative=alternative)
|
1740
|
+
|
1741
|
+
assert_allclose(res.pvalue, res2[1])
|
1742
|
+
|
1743
|
+
@pytest.mark.xslow()
|
1744
|
+
@pytest.mark.parametrize('axis', (-2, 1))
|
1745
|
+
def test_vectorized_nsamp_ptype_samples(self, axis):
|
1746
|
+
# Test that permutation_test with permutation_type='samples' works
|
1747
|
+
# properly for a 3-sample statistic with nd array samples of different
|
1748
|
+
# (but compatible) shapes and ndims. Show that exact permutation test
|
1749
|
+
# reproduces SciPy's exact pvalue and that random permutation test
|
1750
|
+
# approximates it.
|
1751
|
+
|
1752
|
+
x = self.rng.random(size=(2, 4, 3))
|
1753
|
+
y = self.rng.random(size=(1, 4, 3))
|
1754
|
+
z = self.rng.random(size=(2, 4, 1))
|
1755
|
+
x = stats.rankdata(x, axis=axis)
|
1756
|
+
y = stats.rankdata(y, axis=axis)
|
1757
|
+
z = stats.rankdata(z, axis=axis)
|
1758
|
+
y = y[0] # to check broadcast with different ndim
|
1759
|
+
data = (x, y, z)
|
1760
|
+
|
1761
|
+
def statistic1d(*data):
|
1762
|
+
return stats.page_trend_test(data, ranked=True,
|
1763
|
+
method='asymptotic').statistic
|
1764
|
+
|
1765
|
+
def pvalue1d(*data):
|
1766
|
+
return stats.page_trend_test(data, ranked=True,
|
1767
|
+
method='exact').pvalue
|
1768
|
+
|
1769
|
+
statistic = _resampling._vectorize_statistic(statistic1d)
|
1770
|
+
pvalue = _resampling._vectorize_statistic(pvalue1d)
|
1771
|
+
|
1772
|
+
expected_statistic = statistic(*np.broadcast_arrays(*data), axis=axis)
|
1773
|
+
expected_pvalue = pvalue(*np.broadcast_arrays(*data), axis=axis)
|
1774
|
+
|
1775
|
+
# Let's forgive this use of an integer seed, please.
|
1776
|
+
kwds = {'vectorized': False, 'axis': axis, 'alternative': 'greater',
|
1777
|
+
'permutation_type': 'pairings', 'rng': 0}
|
1778
|
+
res = permutation_test(data, statistic1d, n_resamples=np.inf, **kwds)
|
1779
|
+
res2 = permutation_test(data, statistic1d, n_resamples=5000, **kwds)
|
1780
|
+
|
1781
|
+
assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
|
1782
|
+
assert_allclose(res.statistic, res2.statistic, rtol=self.rtol)
|
1783
|
+
assert_allclose(res.pvalue, expected_pvalue, rtol=self.rtol)
|
1784
|
+
assert_allclose(res.pvalue, res2.pvalue, atol=3e-2)
|
1785
|
+
|
1786
|
+
# -- Test Against External References -- #
|
1787
|
+
|
1788
|
+
tie_case_1 = {'x': [1, 2, 3, 4], 'y': [1.5, 2, 2.5],
|
1789
|
+
'expected_less': 0.2000000000,
|
1790
|
+
'expected_2sided': 0.4, # 2*expected_less
|
1791
|
+
'expected_Pr_gte_S_mean': 0.3428571429, # see note below
|
1792
|
+
'expected_statistic': 7.5,
|
1793
|
+
'expected_avg': 9.142857, 'expected_std': 1.40698}
|
1794
|
+
tie_case_2 = {'x': [111, 107, 100, 99, 102, 106, 109, 108],
|
1795
|
+
'y': [107, 108, 106, 98, 105, 103, 110, 105, 104],
|
1796
|
+
'expected_less': 0.1555738379,
|
1797
|
+
'expected_2sided': 0.3111476758,
|
1798
|
+
'expected_Pr_gte_S_mean': 0.2969971205, # see note below
|
1799
|
+
'expected_statistic': 32.5,
|
1800
|
+
'expected_avg': 38.117647, 'expected_std': 5.172124}
|
1801
|
+
|
1802
|
+
@pytest.mark.xslow() # only the second case is slow, really
|
1803
|
+
@pytest.mark.parametrize('case', (tie_case_1, tie_case_2))
|
1804
|
+
def test_with_ties(self, case):
|
1805
|
+
"""
|
1806
|
+
Results above from SAS PROC NPAR1WAY, e.g.
|
1807
|
+
|
1808
|
+
DATA myData;
|
1809
|
+
INPUT X Y;
|
1810
|
+
CARDS;
|
1811
|
+
1 1
|
1812
|
+
1 2
|
1813
|
+
1 3
|
1814
|
+
1 4
|
1815
|
+
2 1.5
|
1816
|
+
2 2
|
1817
|
+
2 2.5
|
1818
|
+
ods graphics on;
|
1819
|
+
proc npar1way AB data=myData;
|
1820
|
+
class X;
|
1821
|
+
EXACT;
|
1822
|
+
run;
|
1823
|
+
ods graphics off;
|
1824
|
+
|
1825
|
+
Note: SAS provides Pr >= |S-Mean|, which is different from our
|
1826
|
+
definition of a two-sided p-value.
|
1827
|
+
|
1828
|
+
"""
|
1829
|
+
|
1830
|
+
x = case['x']
|
1831
|
+
y = case['y']
|
1832
|
+
|
1833
|
+
expected_statistic = case['expected_statistic']
|
1834
|
+
expected_less = case['expected_less']
|
1835
|
+
expected_2sided = case['expected_2sided']
|
1836
|
+
expected_Pr_gte_S_mean = case['expected_Pr_gte_S_mean']
|
1837
|
+
expected_avg = case['expected_avg']
|
1838
|
+
expected_std = case['expected_std']
|
1839
|
+
|
1840
|
+
def statistic1d(x, y):
|
1841
|
+
return stats.ansari(x, y).statistic
|
1842
|
+
|
1843
|
+
with np.testing.suppress_warnings() as sup:
|
1844
|
+
sup.filter(UserWarning, "Ties preclude use of exact statistic")
|
1845
|
+
res = permutation_test((x, y), statistic1d, n_resamples=np.inf,
|
1846
|
+
alternative='less')
|
1847
|
+
res2 = permutation_test((x, y), statistic1d, n_resamples=np.inf,
|
1848
|
+
alternative='two-sided')
|
1849
|
+
|
1850
|
+
assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
|
1851
|
+
assert_allclose(res.pvalue, expected_less, atol=1e-10)
|
1852
|
+
assert_allclose(res2.pvalue, expected_2sided, atol=1e-10)
|
1853
|
+
assert_allclose(res2.null_distribution.mean(), expected_avg, rtol=1e-6)
|
1854
|
+
assert_allclose(res2.null_distribution.std(), expected_std, rtol=1e-6)
|
1855
|
+
|
1856
|
+
# SAS provides Pr >= |S-Mean|; might as well check against that, too
|
1857
|
+
S = res.statistic
|
1858
|
+
mean = res.null_distribution.mean()
|
1859
|
+
n = len(res.null_distribution)
|
1860
|
+
Pr_gte_S_mean = np.sum(np.abs(res.null_distribution-mean)
|
1861
|
+
>= np.abs(S-mean))/n
|
1862
|
+
assert_allclose(expected_Pr_gte_S_mean, Pr_gte_S_mean)
|
1863
|
+
|
1864
|
+
@pytest.mark.slow
|
1865
|
+
@pytest.mark.parametrize('alternative, expected_pvalue',
|
1866
|
+
(('less', 0.9708333333333),
|
1867
|
+
('greater', 0.05138888888889),
|
1868
|
+
('two-sided', 0.1027777777778)))
|
1869
|
+
def test_against_spearmanr_in_R(self, alternative, expected_pvalue):
|
1870
|
+
"""
|
1871
|
+
Results above from R cor.test, e.g.
|
1872
|
+
|
1873
|
+
options(digits=16)
|
1874
|
+
x <- c(1.76405235, 0.40015721, 0.97873798,
|
1875
|
+
2.2408932, 1.86755799, -0.97727788)
|
1876
|
+
y <- c(2.71414076, 0.2488, 0.87551913,
|
1877
|
+
2.6514917, 2.01160156, 0.47699563)
|
1878
|
+
cor.test(x, y, method = "spearm", alternative = "t")
|
1879
|
+
"""
|
1880
|
+
# data comes from
|
1881
|
+
# np.random.seed(0)
|
1882
|
+
# x = stats.norm.rvs(size=6)
|
1883
|
+
# y = x + stats.norm.rvs(size=6)
|
1884
|
+
x = [1.76405235, 0.40015721, 0.97873798,
|
1885
|
+
2.2408932, 1.86755799, -0.97727788]
|
1886
|
+
y = [2.71414076, 0.2488, 0.87551913,
|
1887
|
+
2.6514917, 2.01160156, 0.47699563]
|
1888
|
+
expected_statistic = 0.7714285714285715
|
1889
|
+
|
1890
|
+
def statistic1d(x):
|
1891
|
+
return stats.spearmanr(x, y).statistic
|
1892
|
+
|
1893
|
+
res = permutation_test((x,), statistic1d, permutation_type='pairings',
|
1894
|
+
n_resamples=np.inf, alternative=alternative)
|
1895
|
+
|
1896
|
+
assert_allclose(res.statistic, expected_statistic, rtol=self.rtol)
|
1897
|
+
assert_allclose(res.pvalue, expected_pvalue, atol=1e-13)
|
1898
|
+
|
1899
|
+
@pytest.mark.parametrize("batch", (-1, 0))
|
1900
|
+
def test_batch_generator_iv(self, batch):
|
1901
|
+
with pytest.raises(ValueError, match="`batch` must be positive."):
|
1902
|
+
list(_resampling._batch_generator([1, 2, 3], batch))
|
1903
|
+
|
1904
|
+
batch_generator_cases = [(range(0), 3, []),
|
1905
|
+
(range(6), 3, [[0, 1, 2], [3, 4, 5]]),
|
1906
|
+
(range(8), 3, [[0, 1, 2], [3, 4, 5], [6, 7]])]
|
1907
|
+
|
1908
|
+
@pytest.mark.parametrize("iterable, batch, expected",
|
1909
|
+
batch_generator_cases)
|
1910
|
+
def test_batch_generator(self, iterable, batch, expected):
|
1911
|
+
got = list(_resampling._batch_generator(iterable, batch))
|
1912
|
+
assert got == expected
|
1913
|
+
|
1914
|
+
@pytest.mark.fail_slow(2)
|
1915
|
+
def test_finite_precision_statistic(self):
|
1916
|
+
# Some statistics return numerically distinct values when the values
|
1917
|
+
# should be equal in theory. Test that `permutation_test` accounts
|
1918
|
+
# for this in some way.
|
1919
|
+
x = [1, 2, 4, 3]
|
1920
|
+
y = [2, 4, 6, 8]
|
1921
|
+
|
1922
|
+
def statistic(x, y):
|
1923
|
+
return stats.pearsonr(x, y)[0]
|
1924
|
+
|
1925
|
+
res = stats.permutation_test((x, y), statistic, vectorized=False,
|
1926
|
+
permutation_type='pairings')
|
1927
|
+
r, pvalue, null = res.statistic, res.pvalue, res.null_distribution
|
1928
|
+
|
1929
|
+
correct_p = 2 * np.sum(null >= r - 1e-14) / len(null)
|
1930
|
+
assert pvalue == correct_p == 1/3
|
1931
|
+
# Compare against other exact correlation tests using R corr.test
|
1932
|
+
# options(digits=16)
|
1933
|
+
# x = c(1, 2, 4, 3)
|
1934
|
+
# y = c(2, 4, 6, 8)
|
1935
|
+
# cor.test(x, y, alternative = "t", method = "spearman") # 0.333333333
|
1936
|
+
# cor.test(x, y, alternative = "t", method = "kendall") # 0.333333333
|
1937
|
+
|
1938
|
+
|
1939
|
+
def test_all_partitions_concatenated():
|
1940
|
+
# make sure that _all_paritions_concatenated produces the correct number
|
1941
|
+
# of partitions of the data into samples of the given sizes and that
|
1942
|
+
# all are unique
|
1943
|
+
n = np.array([3, 2, 4], dtype=int)
|
1944
|
+
nc = np.cumsum(n)
|
1945
|
+
|
1946
|
+
all_partitions = set()
|
1947
|
+
counter = 0
|
1948
|
+
for partition_concatenated in _resampling._all_partitions_concatenated(n):
|
1949
|
+
counter += 1
|
1950
|
+
partitioning = np.split(partition_concatenated, nc[:-1])
|
1951
|
+
all_partitions.add(tuple([frozenset(i) for i in partitioning]))
|
1952
|
+
|
1953
|
+
expected = np.prod([special.binom(sum(n[i:]), sum(n[i+1:]))
|
1954
|
+
for i in range(len(n)-1)])
|
1955
|
+
|
1956
|
+
assert_equal(counter, expected)
|
1957
|
+
assert_equal(len(all_partitions), expected)
|
1958
|
+
|
1959
|
+
|
1960
|
+
@pytest.mark.parametrize('fun_name',
|
1961
|
+
['bootstrap', 'permutation_test', 'monte_carlo_test'])
|
1962
|
+
def test_parameter_vectorized(fun_name):
|
1963
|
+
# Check that parameter `vectorized` is working as desired for all
|
1964
|
+
# resampling functions. Results don't matter; just don't fail asserts.
|
1965
|
+
rng = np.random.default_rng(75245098234592)
|
1966
|
+
sample = rng.random(size=10)
|
1967
|
+
|
1968
|
+
def rvs(size): # needed by `monte_carlo_test`
|
1969
|
+
return stats.norm.rvs(size=size, random_state=rng)
|
1970
|
+
|
1971
|
+
fun_options = {'bootstrap': {'data': (sample,), 'rng': rng,
|
1972
|
+
'method': 'percentile'},
|
1973
|
+
'permutation_test': {'data': (sample,), 'rng': rng,
|
1974
|
+
'permutation_type': 'samples'},
|
1975
|
+
'monte_carlo_test': {'sample': sample, 'rvs': rvs}}
|
1976
|
+
common_options = {'n_resamples': 100}
|
1977
|
+
|
1978
|
+
fun = getattr(stats, fun_name)
|
1979
|
+
options = fun_options[fun_name]
|
1980
|
+
options.update(common_options)
|
1981
|
+
|
1982
|
+
def statistic(x, axis):
|
1983
|
+
assert x.ndim > 1 or np.array_equal(x, sample)
|
1984
|
+
return np.mean(x, axis=axis)
|
1985
|
+
fun(statistic=statistic, vectorized=None, **options)
|
1986
|
+
fun(statistic=statistic, vectorized=True, **options)
|
1987
|
+
|
1988
|
+
def statistic(x):
|
1989
|
+
assert x.ndim == 1
|
1990
|
+
return np.mean(x)
|
1991
|
+
fun(statistic=statistic, vectorized=None, **options)
|
1992
|
+
fun(statistic=statistic, vectorized=False, **options)
|
1993
|
+
|
1994
|
+
|
1995
|
+
class TestMonteCarloMethod:
|
1996
|
+
def test_rvs_and_random_state(self):
|
1997
|
+
message = "Use of `rvs` and `rng` are mutually exclusive."
|
1998
|
+
rng = np.random.default_rng(34982345)
|
1999
|
+
with pytest.raises(ValueError, match=message):
|
2000
|
+
stats.MonteCarloMethod(rvs=rng.random, rng=rng)
|