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,1991 @@
|
|
1
|
+
from itertools import product
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
import random
|
5
|
+
import functools
|
6
|
+
import pytest
|
7
|
+
from numpy.testing import (assert_, assert_equal, assert_allclose,
|
8
|
+
assert_almost_equal) # avoid new uses
|
9
|
+
from pytest import raises as assert_raises
|
10
|
+
|
11
|
+
import scipy.stats as stats
|
12
|
+
from scipy.stats import distributions
|
13
|
+
from scipy.stats._hypotests import (epps_singleton_2samp, cramervonmises,
|
14
|
+
_cdf_cvm, cramervonmises_2samp,
|
15
|
+
_pval_cvm_2samp_exact, barnard_exact,
|
16
|
+
boschloo_exact)
|
17
|
+
from scipy.stats._mannwhitneyu import mannwhitneyu, _mwu_state, _MWU
|
18
|
+
from .common_tests import check_named_results
|
19
|
+
from scipy._lib._testutils import _TestPythranFunc
|
20
|
+
from scipy.stats._axis_nan_policy import SmallSampleWarning, too_small_1d_not_omit
|
21
|
+
|
22
|
+
|
23
|
+
class TestEppsSingleton:
|
24
|
+
def test_statistic_1(self):
|
25
|
+
# first example in Goerg & Kaiser, also in original paper of
|
26
|
+
# Epps & Singleton. Note: values do not match exactly, the
|
27
|
+
# value of the interquartile range varies depending on how
|
28
|
+
# quantiles are computed
|
29
|
+
x = np.array([-0.35, 2.55, 1.73, 0.73, 0.35,
|
30
|
+
2.69, 0.46, -0.94, -0.37, 12.07])
|
31
|
+
y = np.array([-1.15, -0.15, 2.48, 3.25, 3.71,
|
32
|
+
4.29, 5.00, 7.74, 8.38, 8.60])
|
33
|
+
w, p = epps_singleton_2samp(x, y)
|
34
|
+
assert_almost_equal(w, 15.14, decimal=1)
|
35
|
+
assert_almost_equal(p, 0.00442, decimal=3)
|
36
|
+
|
37
|
+
def test_statistic_2(self):
|
38
|
+
# second example in Goerg & Kaiser, again not a perfect match
|
39
|
+
x = np.array((0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 10,
|
40
|
+
10, 10, 10))
|
41
|
+
y = np.array((10, 4, 0, 5, 10, 10, 0, 5, 6, 7, 10, 3, 1, 7, 0, 8, 1,
|
42
|
+
5, 8, 10))
|
43
|
+
w, p = epps_singleton_2samp(x, y)
|
44
|
+
assert_allclose(w, 8.900, atol=0.001)
|
45
|
+
assert_almost_equal(p, 0.06364, decimal=3)
|
46
|
+
|
47
|
+
def test_epps_singleton_array_like(self):
|
48
|
+
np.random.seed(1234)
|
49
|
+
x, y = np.arange(30), np.arange(28)
|
50
|
+
|
51
|
+
w1, p1 = epps_singleton_2samp(list(x), list(y))
|
52
|
+
w2, p2 = epps_singleton_2samp(tuple(x), tuple(y))
|
53
|
+
w3, p3 = epps_singleton_2samp(x, y)
|
54
|
+
|
55
|
+
assert_(w1 == w2 == w3)
|
56
|
+
assert_(p1 == p2 == p3)
|
57
|
+
|
58
|
+
def test_epps_singleton_size(self):
|
59
|
+
# warns if sample contains fewer than 5 elements
|
60
|
+
x, y = (1, 2, 3, 4), np.arange(10)
|
61
|
+
with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
|
62
|
+
res = epps_singleton_2samp(x, y)
|
63
|
+
assert_equal(res.statistic, np.nan)
|
64
|
+
assert_equal(res.pvalue, np.nan)
|
65
|
+
|
66
|
+
def test_epps_singleton_nonfinite(self):
|
67
|
+
# raise error if there are non-finite values
|
68
|
+
x, y = (1, 2, 3, 4, 5, np.inf), np.arange(10)
|
69
|
+
assert_raises(ValueError, epps_singleton_2samp, x, y)
|
70
|
+
|
71
|
+
def test_names(self):
|
72
|
+
x, y = np.arange(20), np.arange(30)
|
73
|
+
res = epps_singleton_2samp(x, y)
|
74
|
+
attributes = ('statistic', 'pvalue')
|
75
|
+
check_named_results(res, attributes)
|
76
|
+
|
77
|
+
|
78
|
+
class TestCvm:
|
79
|
+
# the expected values of the cdfs are taken from Table 1 in
|
80
|
+
# Csorgo / Faraway: The Exact and Asymptotic Distribution of
|
81
|
+
# Cramér-von Mises Statistics, 1996.
|
82
|
+
def test_cdf_4(self):
|
83
|
+
assert_allclose(
|
84
|
+
_cdf_cvm([0.02983, 0.04111, 0.12331, 0.94251], 4),
|
85
|
+
[0.01, 0.05, 0.5, 0.999],
|
86
|
+
atol=1e-4)
|
87
|
+
|
88
|
+
def test_cdf_10(self):
|
89
|
+
assert_allclose(
|
90
|
+
_cdf_cvm([0.02657, 0.03830, 0.12068, 0.56643], 10),
|
91
|
+
[0.01, 0.05, 0.5, 0.975],
|
92
|
+
atol=1e-4)
|
93
|
+
|
94
|
+
def test_cdf_1000(self):
|
95
|
+
assert_allclose(
|
96
|
+
_cdf_cvm([0.02481, 0.03658, 0.11889, 1.16120], 1000),
|
97
|
+
[0.01, 0.05, 0.5, 0.999],
|
98
|
+
atol=1e-4)
|
99
|
+
|
100
|
+
def test_cdf_inf(self):
|
101
|
+
assert_allclose(
|
102
|
+
_cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204]),
|
103
|
+
[0.01, 0.05, 0.5, 0.999],
|
104
|
+
atol=1e-4)
|
105
|
+
|
106
|
+
def test_cdf_support(self):
|
107
|
+
# cdf has support on [1/(12*n), n/3]
|
108
|
+
assert_equal(_cdf_cvm([1/(12*533), 533/3], 533), [0, 1])
|
109
|
+
assert_equal(_cdf_cvm([1/(12*(27 + 1)), (27 + 1)/3], 27), [0, 1])
|
110
|
+
|
111
|
+
def test_cdf_large_n(self):
|
112
|
+
# test that asymptotic cdf and cdf for large samples are close
|
113
|
+
assert_allclose(
|
114
|
+
_cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204, 100], 10000),
|
115
|
+
_cdf_cvm([0.02480, 0.03656, 0.11888, 1.16204, 100]),
|
116
|
+
atol=1e-4)
|
117
|
+
|
118
|
+
def test_large_x(self):
|
119
|
+
# for large values of x and n, the series used to compute the cdf
|
120
|
+
# converges slowly.
|
121
|
+
# this leads to bug in R package goftest and MAPLE code that is
|
122
|
+
# the basis of the implementation in scipy
|
123
|
+
# note: cdf = 1 for x >= 1000/3 and n = 1000
|
124
|
+
assert_(0.99999 < _cdf_cvm(333.3, 1000) < 1.0)
|
125
|
+
assert_(0.99999 < _cdf_cvm(333.3) < 1.0)
|
126
|
+
|
127
|
+
def test_low_p(self):
|
128
|
+
# _cdf_cvm can return values larger than 1. In that case, we just
|
129
|
+
# return a p-value of zero.
|
130
|
+
n = 12
|
131
|
+
res = cramervonmises(np.ones(n)*0.8, 'norm')
|
132
|
+
assert_(_cdf_cvm(res.statistic, n) > 1.0)
|
133
|
+
assert_equal(res.pvalue, 0)
|
134
|
+
|
135
|
+
@pytest.mark.parametrize('x', [(), [1.5]])
|
136
|
+
def test_invalid_input(self, x):
|
137
|
+
with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
|
138
|
+
res = cramervonmises(x, "norm")
|
139
|
+
assert_equal(res.statistic, np.nan)
|
140
|
+
assert_equal(res.pvalue, np.nan)
|
141
|
+
|
142
|
+
def test_values_R(self):
|
143
|
+
# compared against R package goftest, version 1.1.1
|
144
|
+
# goftest::cvm.test(c(-1.7, 2, 0, 1.3, 4, 0.1, 0.6), "pnorm")
|
145
|
+
res = cramervonmises([-1.7, 2, 0, 1.3, 4, 0.1, 0.6], "norm")
|
146
|
+
assert_allclose(res.statistic, 0.288156, atol=1e-6)
|
147
|
+
assert_allclose(res.pvalue, 0.1453465, atol=1e-6)
|
148
|
+
|
149
|
+
# goftest::cvm.test(c(-1.7, 2, 0, 1.3, 4, 0.1, 0.6),
|
150
|
+
# "pnorm", mean = 3, sd = 1.5)
|
151
|
+
res = cramervonmises([-1.7, 2, 0, 1.3, 4, 0.1, 0.6], "norm", (3, 1.5))
|
152
|
+
assert_allclose(res.statistic, 0.9426685, atol=1e-6)
|
153
|
+
assert_allclose(res.pvalue, 0.002026417, atol=1e-6)
|
154
|
+
|
155
|
+
# goftest::cvm.test(c(1, 2, 5, 1.4, 0.14, 11, 13, 0.9, 7.5), "pexp")
|
156
|
+
res = cramervonmises([1, 2, 5, 1.4, 0.14, 11, 13, 0.9, 7.5], "expon")
|
157
|
+
assert_allclose(res.statistic, 0.8421854, atol=1e-6)
|
158
|
+
assert_allclose(res.pvalue, 0.004433406, atol=1e-6)
|
159
|
+
|
160
|
+
def test_callable_cdf(self):
|
161
|
+
x, args = np.arange(5), (1.4, 0.7)
|
162
|
+
r1 = cramervonmises(x, distributions.expon.cdf)
|
163
|
+
r2 = cramervonmises(x, "expon")
|
164
|
+
assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
|
165
|
+
|
166
|
+
r1 = cramervonmises(x, distributions.beta.cdf, args)
|
167
|
+
r2 = cramervonmises(x, "beta", args)
|
168
|
+
assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
|
169
|
+
|
170
|
+
|
171
|
+
class TestMannWhitneyU:
|
172
|
+
|
173
|
+
# All magic numbers are from R wilcox.test unless otherwise specified
|
174
|
+
# https://rdrr.io/r/stats/wilcox.test.html
|
175
|
+
|
176
|
+
# --- Test Input Validation ---
|
177
|
+
|
178
|
+
@pytest.mark.parametrize('kwargs_update', [{'x': []}, {'y': []},
|
179
|
+
{'x': [], 'y': []}])
|
180
|
+
def test_empty(self, kwargs_update):
|
181
|
+
x = np.array([1, 2]) # generic, valid inputs
|
182
|
+
y = np.array([3, 4])
|
183
|
+
kwargs = dict(x=x, y=y)
|
184
|
+
kwargs.update(kwargs_update)
|
185
|
+
with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
|
186
|
+
res = mannwhitneyu(**kwargs)
|
187
|
+
assert_equal(res.statistic, np.nan)
|
188
|
+
assert_equal(res.pvalue, np.nan)
|
189
|
+
|
190
|
+
def test_input_validation(self):
|
191
|
+
x = np.array([1, 2]) # generic, valid inputs
|
192
|
+
y = np.array([3, 4])
|
193
|
+
with assert_raises(ValueError, match="`use_continuity` must be one"):
|
194
|
+
mannwhitneyu(x, y, use_continuity='ekki')
|
195
|
+
with assert_raises(ValueError, match="`alternative` must be one of"):
|
196
|
+
mannwhitneyu(x, y, alternative='ekki')
|
197
|
+
with assert_raises(ValueError, match="`axis` must be an integer"):
|
198
|
+
mannwhitneyu(x, y, axis=1.5)
|
199
|
+
with assert_raises(ValueError, match="`method` must be one of"):
|
200
|
+
mannwhitneyu(x, y, method='ekki')
|
201
|
+
|
202
|
+
def test_auto(self):
|
203
|
+
# Test that default method ('auto') chooses intended method
|
204
|
+
|
205
|
+
rng = np.random.RandomState(1)
|
206
|
+
n = 8 # threshold to switch from exact to asymptotic
|
207
|
+
|
208
|
+
# both inputs are smaller than threshold; should use exact
|
209
|
+
x = rng.rand(n-1)
|
210
|
+
y = rng.rand(n-1)
|
211
|
+
auto = mannwhitneyu(x, y)
|
212
|
+
asymptotic = mannwhitneyu(x, y, method='asymptotic')
|
213
|
+
exact = mannwhitneyu(x, y, method='exact')
|
214
|
+
assert auto.pvalue == exact.pvalue
|
215
|
+
assert auto.pvalue != asymptotic.pvalue
|
216
|
+
|
217
|
+
# one input is smaller than threshold; should use exact
|
218
|
+
x = rng.rand(n-1)
|
219
|
+
y = rng.rand(n+1)
|
220
|
+
auto = mannwhitneyu(x, y)
|
221
|
+
asymptotic = mannwhitneyu(x, y, method='asymptotic')
|
222
|
+
exact = mannwhitneyu(x, y, method='exact')
|
223
|
+
assert auto.pvalue == exact.pvalue
|
224
|
+
assert auto.pvalue != asymptotic.pvalue
|
225
|
+
|
226
|
+
# other input is smaller than threshold; should use exact
|
227
|
+
auto = mannwhitneyu(y, x)
|
228
|
+
asymptotic = mannwhitneyu(x, y, method='asymptotic')
|
229
|
+
exact = mannwhitneyu(x, y, method='exact')
|
230
|
+
assert auto.pvalue == exact.pvalue
|
231
|
+
assert auto.pvalue != asymptotic.pvalue
|
232
|
+
|
233
|
+
# both inputs are larger than threshold; should use asymptotic
|
234
|
+
x = rng.rand(n+1)
|
235
|
+
y = rng.rand(n+1)
|
236
|
+
auto = mannwhitneyu(x, y)
|
237
|
+
asymptotic = mannwhitneyu(x, y, method='asymptotic')
|
238
|
+
exact = mannwhitneyu(x, y, method='exact')
|
239
|
+
assert auto.pvalue != exact.pvalue
|
240
|
+
assert auto.pvalue == asymptotic.pvalue
|
241
|
+
|
242
|
+
# both inputs are smaller than threshold, but there is a tie
|
243
|
+
# should use asymptotic
|
244
|
+
x = rng.rand(n-1)
|
245
|
+
y = rng.rand(n-1)
|
246
|
+
y[3] = x[3]
|
247
|
+
auto = mannwhitneyu(x, y)
|
248
|
+
asymptotic = mannwhitneyu(x, y, method='asymptotic')
|
249
|
+
exact = mannwhitneyu(x, y, method='exact')
|
250
|
+
assert auto.pvalue != exact.pvalue
|
251
|
+
assert auto.pvalue == asymptotic.pvalue
|
252
|
+
|
253
|
+
# --- Test Basic Functionality ---
|
254
|
+
|
255
|
+
x = [210.052110, 110.190630, 307.918612]
|
256
|
+
y = [436.08811482466416, 416.37397329768191, 179.96975939463582,
|
257
|
+
197.8118754228619, 34.038757281225756, 138.54220550921517,
|
258
|
+
128.7769351470246, 265.92721427951852, 275.6617533155341,
|
259
|
+
592.34083395416258, 448.73177590617018, 300.61495185038905,
|
260
|
+
187.97508449019588]
|
261
|
+
|
262
|
+
# This test was written for mann_whitney_u in gh-4933.
|
263
|
+
# Originally, the p-values for alternatives were swapped;
|
264
|
+
# this has been corrected and the tests have been refactored for
|
265
|
+
# compactness, but otherwise the tests are unchanged.
|
266
|
+
# R code for comparison, e.g.:
|
267
|
+
# options(digits = 16)
|
268
|
+
# x = c(210.052110, 110.190630, 307.918612)
|
269
|
+
# y = c(436.08811482466416, 416.37397329768191, 179.96975939463582,
|
270
|
+
# 197.8118754228619, 34.038757281225756, 138.54220550921517,
|
271
|
+
# 128.7769351470246, 265.92721427951852, 275.6617533155341,
|
272
|
+
# 592.34083395416258, 448.73177590617018, 300.61495185038905,
|
273
|
+
# 187.97508449019588)
|
274
|
+
# wilcox.test(x, y, alternative="g", exact=TRUE)
|
275
|
+
cases_basic = [[{"alternative": 'two-sided', "method": "asymptotic"},
|
276
|
+
(16, 0.6865041817876)],
|
277
|
+
[{"alternative": 'less', "method": "asymptotic"},
|
278
|
+
(16, 0.3432520908938)],
|
279
|
+
[{"alternative": 'greater', "method": "asymptotic"},
|
280
|
+
(16, 0.7047591913255)],
|
281
|
+
[{"alternative": 'two-sided', "method": "exact"},
|
282
|
+
(16, 0.7035714285714)],
|
283
|
+
[{"alternative": 'less', "method": "exact"},
|
284
|
+
(16, 0.3517857142857)],
|
285
|
+
[{"alternative": 'greater', "method": "exact"},
|
286
|
+
(16, 0.6946428571429)]]
|
287
|
+
|
288
|
+
@pytest.mark.parametrize(("kwds", "expected"), cases_basic)
|
289
|
+
def test_basic(self, kwds, expected):
|
290
|
+
res = mannwhitneyu(self.x, self.y, **kwds)
|
291
|
+
assert_allclose(res, expected)
|
292
|
+
|
293
|
+
cases_continuity = [[{"alternative": 'two-sided', "use_continuity": True},
|
294
|
+
(23, 0.6865041817876)],
|
295
|
+
[{"alternative": 'less', "use_continuity": True},
|
296
|
+
(23, 0.7047591913255)],
|
297
|
+
[{"alternative": 'greater', "use_continuity": True},
|
298
|
+
(23, 0.3432520908938)],
|
299
|
+
[{"alternative": 'two-sided', "use_continuity": False},
|
300
|
+
(23, 0.6377328900502)],
|
301
|
+
[{"alternative": 'less', "use_continuity": False},
|
302
|
+
(23, 0.6811335549749)],
|
303
|
+
[{"alternative": 'greater', "use_continuity": False},
|
304
|
+
(23, 0.3188664450251)]]
|
305
|
+
|
306
|
+
@pytest.mark.parametrize(("kwds", "expected"), cases_continuity)
|
307
|
+
def test_continuity(self, kwds, expected):
|
308
|
+
# When x and y are interchanged, less and greater p-values should
|
309
|
+
# swap (compare to above). This wouldn't happen if the continuity
|
310
|
+
# correction were applied in the wrong direction. Note that less and
|
311
|
+
# greater p-values do not sum to 1 when continuity correction is on,
|
312
|
+
# which is what we'd expect. Also check that results match R when
|
313
|
+
# continuity correction is turned off.
|
314
|
+
# Note that method='asymptotic' -> exact=FALSE
|
315
|
+
# and use_continuity=False -> correct=FALSE, e.g.:
|
316
|
+
# wilcox.test(x, y, alternative="t", exact=FALSE, correct=FALSE)
|
317
|
+
res = mannwhitneyu(self.y, self.x, method='asymptotic', **kwds)
|
318
|
+
assert_allclose(res, expected)
|
319
|
+
|
320
|
+
def test_tie_correct(self):
|
321
|
+
# Test tie correction against R's wilcox.test
|
322
|
+
# options(digits = 16)
|
323
|
+
# x = c(1, 2, 3, 4)
|
324
|
+
# y = c(1, 2, 3, 4, 5)
|
325
|
+
# wilcox.test(x, y, exact=FALSE)
|
326
|
+
x = [1, 2, 3, 4]
|
327
|
+
y0 = np.array([1, 2, 3, 4, 5])
|
328
|
+
dy = np.array([0, 1, 0, 1, 0])*0.01
|
329
|
+
dy2 = np.array([0, 0, 1, 0, 0])*0.01
|
330
|
+
y = [y0-0.01, y0-dy, y0-dy2, y0, y0+dy2, y0+dy, y0+0.01]
|
331
|
+
res = mannwhitneyu(x, y, axis=-1, method="asymptotic")
|
332
|
+
U_expected = [10, 9, 8.5, 8, 7.5, 7, 6]
|
333
|
+
p_expected = [1, 0.9017048037317, 0.804080657472, 0.7086240584439,
|
334
|
+
0.6197963884941, 0.5368784563079, 0.3912672792826]
|
335
|
+
assert_equal(res.statistic, U_expected)
|
336
|
+
assert_allclose(res.pvalue, p_expected)
|
337
|
+
|
338
|
+
# --- Test Exact Distribution of U ---
|
339
|
+
|
340
|
+
# These are tabulated values of the CDF of the exact distribution of
|
341
|
+
# the test statistic from pg 52 of reference [1] (Mann-Whitney Original)
|
342
|
+
pn3 = {1: [0.25, 0.5, 0.75], 2: [0.1, 0.2, 0.4, 0.6],
|
343
|
+
3: [0.05, .1, 0.2, 0.35, 0.5, 0.65]}
|
344
|
+
pn4 = {1: [0.2, 0.4, 0.6], 2: [0.067, 0.133, 0.267, 0.4, 0.6],
|
345
|
+
3: [0.028, 0.057, 0.114, 0.2, .314, 0.429, 0.571],
|
346
|
+
4: [0.014, 0.029, 0.057, 0.1, 0.171, 0.243, 0.343, 0.443, 0.557]}
|
347
|
+
pm5 = {1: [0.167, 0.333, 0.5, 0.667],
|
348
|
+
2: [0.047, 0.095, 0.19, 0.286, 0.429, 0.571],
|
349
|
+
3: [0.018, 0.036, 0.071, 0.125, 0.196, 0.286, 0.393, 0.5, 0.607],
|
350
|
+
4: [0.008, 0.016, 0.032, 0.056, 0.095, 0.143,
|
351
|
+
0.206, 0.278, 0.365, 0.452, 0.548],
|
352
|
+
5: [0.004, 0.008, 0.016, 0.028, 0.048, 0.075, 0.111,
|
353
|
+
0.155, 0.21, 0.274, 0.345, .421, 0.5, 0.579]}
|
354
|
+
pm6 = {1: [0.143, 0.286, 0.428, 0.571],
|
355
|
+
2: [0.036, 0.071, 0.143, 0.214, 0.321, 0.429, 0.571],
|
356
|
+
3: [0.012, 0.024, 0.048, 0.083, 0.131,
|
357
|
+
0.19, 0.274, 0.357, 0.452, 0.548],
|
358
|
+
4: [0.005, 0.01, 0.019, 0.033, 0.057, 0.086, 0.129,
|
359
|
+
0.176, 0.238, 0.305, 0.381, 0.457, 0.543], # the last element
|
360
|
+
# of the previous list, 0.543, has been modified from 0.545;
|
361
|
+
# I assume it was a typo
|
362
|
+
5: [0.002, 0.004, 0.009, 0.015, 0.026, 0.041, 0.063, 0.089,
|
363
|
+
0.123, 0.165, 0.214, 0.268, 0.331, 0.396, 0.465, 0.535],
|
364
|
+
6: [0.001, 0.002, 0.004, 0.008, 0.013, 0.021, 0.032, 0.047,
|
365
|
+
0.066, 0.09, 0.12, 0.155, 0.197, 0.242, 0.294, 0.350,
|
366
|
+
0.409, 0.469, 0.531]}
|
367
|
+
|
368
|
+
def test_exact_distribution(self):
|
369
|
+
# I considered parametrize. I decided against it.
|
370
|
+
setattr(_mwu_state, 's', _MWU(0, 0))
|
371
|
+
|
372
|
+
p_tables = {3: self.pn3, 4: self.pn4, 5: self.pm5, 6: self.pm6}
|
373
|
+
for n, table in p_tables.items():
|
374
|
+
for m, p in table.items():
|
375
|
+
# check p-value against table
|
376
|
+
u = np.arange(0, len(p))
|
377
|
+
_mwu_state.s.set_shapes(m, n)
|
378
|
+
assert_allclose(_mwu_state.s.cdf(k=u), p, atol=1e-3)
|
379
|
+
|
380
|
+
# check identity CDF + SF - PMF = 1
|
381
|
+
# ( In this implementation, SF(U) includes PMF(U) )
|
382
|
+
u2 = np.arange(0, m*n+1)
|
383
|
+
assert_allclose(_mwu_state.s.cdf(k=u2)
|
384
|
+
+ _mwu_state.s.sf(k=u2)
|
385
|
+
- _mwu_state.s.pmf(k=u2), 1)
|
386
|
+
|
387
|
+
# check symmetry about mean of U, i.e. pmf(U) = pmf(m*n-U)
|
388
|
+
pmf = _mwu_state.s.pmf(k=u2)
|
389
|
+
assert_allclose(pmf, pmf[::-1])
|
390
|
+
|
391
|
+
# check symmetry w.r.t. interchange of m, n
|
392
|
+
_mwu_state.s.set_shapes(n, m)
|
393
|
+
pmf2 = _mwu_state.s.pmf(k=u2)
|
394
|
+
assert_allclose(pmf, pmf2)
|
395
|
+
|
396
|
+
def test_asymptotic_behavior(self):
|
397
|
+
rng = np.random.default_rng(12543)
|
398
|
+
|
399
|
+
# for small samples, the asymptotic test is not very accurate
|
400
|
+
x = rng.random(5)
|
401
|
+
y = rng.random(5)
|
402
|
+
res1 = mannwhitneyu(x, y, method="exact")
|
403
|
+
res2 = mannwhitneyu(x, y, method="asymptotic")
|
404
|
+
assert res1.statistic == res2.statistic
|
405
|
+
assert np.abs(res1.pvalue - res2.pvalue) > 1e-2
|
406
|
+
|
407
|
+
# for large samples, they agree reasonably well
|
408
|
+
x = rng.random(40)
|
409
|
+
y = rng.random(40)
|
410
|
+
res1 = mannwhitneyu(x, y, method="exact")
|
411
|
+
res2 = mannwhitneyu(x, y, method="asymptotic")
|
412
|
+
assert res1.statistic == res2.statistic
|
413
|
+
assert np.abs(res1.pvalue - res2.pvalue) < 1e-3
|
414
|
+
|
415
|
+
# --- Test Corner Cases ---
|
416
|
+
|
417
|
+
def test_exact_U_equals_mean(self):
|
418
|
+
# Test U == m*n/2 with exact method
|
419
|
+
# Without special treatment, two-sided p-value > 1 because both
|
420
|
+
# one-sided p-values are > 0.5
|
421
|
+
res_l = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="less",
|
422
|
+
method="exact")
|
423
|
+
res_g = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="greater",
|
424
|
+
method="exact")
|
425
|
+
assert_equal(res_l.pvalue, res_g.pvalue)
|
426
|
+
assert res_l.pvalue > 0.5
|
427
|
+
|
428
|
+
res = mannwhitneyu([1, 2, 3], [1.5, 2.5], alternative="two-sided",
|
429
|
+
method="exact")
|
430
|
+
assert_equal(res, (3, 1))
|
431
|
+
# U == m*n/2 for asymptotic case tested in test_gh_2118
|
432
|
+
# The reason it's tricky for the asymptotic test has to do with
|
433
|
+
# continuity correction.
|
434
|
+
|
435
|
+
cases_scalar = [[{"alternative": 'two-sided', "method": "asymptotic"},
|
436
|
+
(0, 1)],
|
437
|
+
[{"alternative": 'less', "method": "asymptotic"},
|
438
|
+
(0, 0.5)],
|
439
|
+
[{"alternative": 'greater', "method": "asymptotic"},
|
440
|
+
(0, 0.977249868052)],
|
441
|
+
[{"alternative": 'two-sided', "method": "exact"}, (0, 1)],
|
442
|
+
[{"alternative": 'less', "method": "exact"}, (0, 0.5)],
|
443
|
+
[{"alternative": 'greater', "method": "exact"}, (0, 1)]]
|
444
|
+
|
445
|
+
@pytest.mark.parametrize(("kwds", "result"), cases_scalar)
|
446
|
+
def test_scalar_data(self, kwds, result):
|
447
|
+
# just making sure scalars work
|
448
|
+
assert_allclose(mannwhitneyu(1, 2, **kwds), result)
|
449
|
+
|
450
|
+
def test_equal_scalar_data(self):
|
451
|
+
# when two scalars are equal, there is an -0.5/0 in the asymptotic
|
452
|
+
# approximation. R gives pvalue=1.0 for alternatives 'less' and
|
453
|
+
# 'greater' but NA for 'two-sided'. I don't see why, so I don't
|
454
|
+
# see a need for a special case to match that behavior.
|
455
|
+
assert_equal(mannwhitneyu(1, 1, method="exact"), (0.5, 1))
|
456
|
+
assert_equal(mannwhitneyu(1, 1, method="asymptotic"), (0.5, 1))
|
457
|
+
|
458
|
+
# without continuity correction, this becomes 0/0, which really
|
459
|
+
# is undefined
|
460
|
+
assert_equal(mannwhitneyu(1, 1, method="asymptotic",
|
461
|
+
use_continuity=False), (0.5, np.nan))
|
462
|
+
|
463
|
+
# --- Test Enhancements / Bug Reports ---
|
464
|
+
|
465
|
+
@pytest.mark.parametrize("method", ["asymptotic", "exact"])
|
466
|
+
def test_gh_12837_11113(self, method):
|
467
|
+
# Test that behavior for broadcastable nd arrays is appropriate:
|
468
|
+
# output shape is correct and all values are equal to when the test
|
469
|
+
# is performed on one pair of samples at a time.
|
470
|
+
# Tests that gh-12837 and gh-11113 (requests for n-d input)
|
471
|
+
# are resolved
|
472
|
+
np.random.seed(0)
|
473
|
+
|
474
|
+
# arrays are broadcastable except for axis = -3
|
475
|
+
axis = -3
|
476
|
+
m, n = 7, 10 # sample sizes
|
477
|
+
x = np.random.rand(m, 3, 8)
|
478
|
+
y = np.random.rand(6, n, 1, 8) + 0.1
|
479
|
+
res = mannwhitneyu(x, y, method=method, axis=axis)
|
480
|
+
|
481
|
+
shape = (6, 3, 8) # appropriate shape of outputs, given inputs
|
482
|
+
assert res.pvalue.shape == shape
|
483
|
+
assert res.statistic.shape == shape
|
484
|
+
|
485
|
+
# move axis of test to end for simplicity
|
486
|
+
x, y = np.moveaxis(x, axis, -1), np.moveaxis(y, axis, -1)
|
487
|
+
|
488
|
+
x = x[None, ...] # give x a zeroth dimension
|
489
|
+
assert x.ndim == y.ndim
|
490
|
+
|
491
|
+
x = np.broadcast_to(x, shape + (m,))
|
492
|
+
y = np.broadcast_to(y, shape + (n,))
|
493
|
+
assert x.shape[:-1] == shape
|
494
|
+
assert y.shape[:-1] == shape
|
495
|
+
|
496
|
+
# loop over pairs of samples
|
497
|
+
statistics = np.zeros(shape)
|
498
|
+
pvalues = np.zeros(shape)
|
499
|
+
for indices in product(*[range(i) for i in shape]):
|
500
|
+
xi = x[indices]
|
501
|
+
yi = y[indices]
|
502
|
+
temp = mannwhitneyu(xi, yi, method=method)
|
503
|
+
statistics[indices] = temp.statistic
|
504
|
+
pvalues[indices] = temp.pvalue
|
505
|
+
|
506
|
+
np.testing.assert_equal(res.pvalue, pvalues)
|
507
|
+
np.testing.assert_equal(res.statistic, statistics)
|
508
|
+
|
509
|
+
def test_gh_11355(self):
|
510
|
+
# Test for correct behavior with NaN/Inf in input
|
511
|
+
x = [1, 2, 3, 4]
|
512
|
+
y = [3, 6, 7, 8, 9, 3, 2, 1, 4, 4, 5]
|
513
|
+
res1 = mannwhitneyu(x, y)
|
514
|
+
|
515
|
+
# Inf is not a problem. This is a rank test, and it's the largest value
|
516
|
+
y[4] = np.inf
|
517
|
+
res2 = mannwhitneyu(x, y)
|
518
|
+
|
519
|
+
assert_equal(res1.statistic, res2.statistic)
|
520
|
+
assert_equal(res1.pvalue, res2.pvalue)
|
521
|
+
|
522
|
+
# NaNs should propagate by default.
|
523
|
+
y[4] = np.nan
|
524
|
+
res3 = mannwhitneyu(x, y)
|
525
|
+
assert_equal(res3.statistic, np.nan)
|
526
|
+
assert_equal(res3.pvalue, np.nan)
|
527
|
+
|
528
|
+
cases_11355 = [([1, 2, 3, 4],
|
529
|
+
[3, 6, 7, 8, np.inf, 3, 2, 1, 4, 4, 5],
|
530
|
+
10, 0.1297704873477),
|
531
|
+
([1, 2, 3, 4],
|
532
|
+
[3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
|
533
|
+
8.5, 0.08735617507695),
|
534
|
+
([1, 2, np.inf, 4],
|
535
|
+
[3, 6, 7, 8, np.inf, 3, 2, 1, 4, 4, 5],
|
536
|
+
17.5, 0.5988856695752),
|
537
|
+
([1, 2, np.inf, 4],
|
538
|
+
[3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
|
539
|
+
16, 0.4687165824462),
|
540
|
+
([1, np.inf, np.inf, 4],
|
541
|
+
[3, 6, 7, 8, np.inf, np.inf, 2, 1, 4, 4, 5],
|
542
|
+
24.5, 0.7912517950119)]
|
543
|
+
|
544
|
+
@pytest.mark.parametrize(("x", "y", "statistic", "pvalue"), cases_11355)
|
545
|
+
def test_gh_11355b(self, x, y, statistic, pvalue):
|
546
|
+
# Test for correct behavior with NaN/Inf in input
|
547
|
+
res = mannwhitneyu(x, y, method='asymptotic')
|
548
|
+
assert_allclose(res.statistic, statistic, atol=1e-12)
|
549
|
+
assert_allclose(res.pvalue, pvalue, atol=1e-12)
|
550
|
+
|
551
|
+
cases_9184 = [[True, "less", "asymptotic", 0.900775348204],
|
552
|
+
[True, "greater", "asymptotic", 0.1223118025635],
|
553
|
+
[True, "two-sided", "asymptotic", 0.244623605127],
|
554
|
+
[False, "less", "asymptotic", 0.8896643190401],
|
555
|
+
[False, "greater", "asymptotic", 0.1103356809599],
|
556
|
+
[False, "two-sided", "asymptotic", 0.2206713619198],
|
557
|
+
[True, "less", "exact", 0.8967698967699],
|
558
|
+
[True, "greater", "exact", 0.1272061272061],
|
559
|
+
[True, "two-sided", "exact", 0.2544122544123]]
|
560
|
+
|
561
|
+
@pytest.mark.parametrize(("use_continuity", "alternative",
|
562
|
+
"method", "pvalue_exp"), cases_9184)
|
563
|
+
def test_gh_9184(self, use_continuity, alternative, method, pvalue_exp):
|
564
|
+
# gh-9184 might be considered a doc-only bug. Please see the
|
565
|
+
# documentation to confirm that mannwhitneyu correctly notes
|
566
|
+
# that the output statistic is that of the first sample (x). In any
|
567
|
+
# case, check the case provided there against output from R.
|
568
|
+
# R code:
|
569
|
+
# options(digits=16)
|
570
|
+
# x <- c(0.80, 0.83, 1.89, 1.04, 1.45, 1.38, 1.91, 1.64, 0.73, 1.46)
|
571
|
+
# y <- c(1.15, 0.88, 0.90, 0.74, 1.21)
|
572
|
+
# wilcox.test(x, y, alternative = "less", exact = FALSE)
|
573
|
+
# wilcox.test(x, y, alternative = "greater", exact = FALSE)
|
574
|
+
# wilcox.test(x, y, alternative = "two.sided", exact = FALSE)
|
575
|
+
# wilcox.test(x, y, alternative = "less", exact = FALSE,
|
576
|
+
# correct=FALSE)
|
577
|
+
# wilcox.test(x, y, alternative = "greater", exact = FALSE,
|
578
|
+
# correct=FALSE)
|
579
|
+
# wilcox.test(x, y, alternative = "two.sided", exact = FALSE,
|
580
|
+
# correct=FALSE)
|
581
|
+
# wilcox.test(x, y, alternative = "less", exact = TRUE)
|
582
|
+
# wilcox.test(x, y, alternative = "greater", exact = TRUE)
|
583
|
+
# wilcox.test(x, y, alternative = "two.sided", exact = TRUE)
|
584
|
+
statistic_exp = 35
|
585
|
+
x = (0.80, 0.83, 1.89, 1.04, 1.45, 1.38, 1.91, 1.64, 0.73, 1.46)
|
586
|
+
y = (1.15, 0.88, 0.90, 0.74, 1.21)
|
587
|
+
res = mannwhitneyu(x, y, use_continuity=use_continuity,
|
588
|
+
alternative=alternative, method=method)
|
589
|
+
assert_equal(res.statistic, statistic_exp)
|
590
|
+
assert_allclose(res.pvalue, pvalue_exp)
|
591
|
+
|
592
|
+
def test_gh_4067(self):
|
593
|
+
# Test for correct behavior with all NaN input - default is propagate
|
594
|
+
a = np.array([np.nan, np.nan, np.nan, np.nan, np.nan])
|
595
|
+
b = np.array([np.nan, np.nan, np.nan, np.nan, np.nan])
|
596
|
+
res = mannwhitneyu(a, b)
|
597
|
+
assert_equal(res.statistic, np.nan)
|
598
|
+
assert_equal(res.pvalue, np.nan)
|
599
|
+
|
600
|
+
# All cases checked against R wilcox.test, e.g.
|
601
|
+
# options(digits=16)
|
602
|
+
# x = c(1, 2, 3)
|
603
|
+
# y = c(1.5, 2.5)
|
604
|
+
# wilcox.test(x, y, exact=FALSE, alternative='less')
|
605
|
+
|
606
|
+
cases_2118 = [[[1, 2, 3], [1.5, 2.5], "greater", (3, 0.6135850036578)],
|
607
|
+
[[1, 2, 3], [1.5, 2.5], "less", (3, 0.6135850036578)],
|
608
|
+
[[1, 2, 3], [1.5, 2.5], "two-sided", (3, 1.0)],
|
609
|
+
[[1, 2, 3], [2], "greater", (1.5, 0.681324055883)],
|
610
|
+
[[1, 2, 3], [2], "less", (1.5, 0.681324055883)],
|
611
|
+
[[1, 2, 3], [2], "two-sided", (1.5, 1)],
|
612
|
+
[[1, 2], [1, 2], "greater", (2, 0.667497228949)],
|
613
|
+
[[1, 2], [1, 2], "less", (2, 0.667497228949)],
|
614
|
+
[[1, 2], [1, 2], "two-sided", (2, 1)]]
|
615
|
+
|
616
|
+
@pytest.mark.parametrize(["x", "y", "alternative", "expected"], cases_2118)
|
617
|
+
def test_gh_2118(self, x, y, alternative, expected):
|
618
|
+
# test cases in which U == m*n/2 when method is asymptotic
|
619
|
+
# applying continuity correction could result in p-value > 1
|
620
|
+
res = mannwhitneyu(x, y, use_continuity=True, alternative=alternative,
|
621
|
+
method="asymptotic")
|
622
|
+
assert_allclose(res, expected, rtol=1e-12)
|
623
|
+
|
624
|
+
def test_gh19692_smaller_table(self):
|
625
|
+
# In gh-19692, we noted that the shape of the cache used in calculating
|
626
|
+
# p-values was dependent on the order of the inputs because the sample
|
627
|
+
# sizes n1 and n2 changed. This was indicative of unnecessary cache
|
628
|
+
# growth and redundant calculation. Check that this is resolved.
|
629
|
+
rng = np.random.default_rng(7600451795963068007)
|
630
|
+
m, n = 5, 11
|
631
|
+
x = rng.random(size=m)
|
632
|
+
y = rng.random(size=n)
|
633
|
+
|
634
|
+
setattr(_mwu_state, 's', _MWU(0, 0))
|
635
|
+
_mwu_state.s.reset() # reset cache
|
636
|
+
|
637
|
+
res = stats.mannwhitneyu(x, y, method='exact')
|
638
|
+
shape = _mwu_state.s.configurations.shape
|
639
|
+
assert shape[-1] == min(res.statistic, m*n - res.statistic) + 1
|
640
|
+
stats.mannwhitneyu(y, x, method='exact')
|
641
|
+
assert shape == _mwu_state.s.configurations.shape # same with reversed sizes
|
642
|
+
|
643
|
+
# Also, we weren't exploiting the symmetry of the null distribution
|
644
|
+
# to its full potential. Ensure that the null distribution is not
|
645
|
+
# evaluated explicitly for `k > m*n/2`.
|
646
|
+
_mwu_state.s.reset() # reset cache
|
647
|
+
stats.mannwhitneyu(x, 0*y, method='exact', alternative='greater')
|
648
|
+
shape = _mwu_state.s.configurations.shape
|
649
|
+
assert shape[-1] == 1 # k is smallest possible
|
650
|
+
stats.mannwhitneyu(0*x, y, method='exact', alternative='greater')
|
651
|
+
assert shape == _mwu_state.s.configurations.shape
|
652
|
+
|
653
|
+
@pytest.mark.parametrize('alternative', ['less', 'greater', 'two-sided'])
|
654
|
+
def test_permutation_method(self, alternative):
|
655
|
+
rng = np.random.default_rng(7600451795963068007)
|
656
|
+
x = rng.random(size=(2, 5))
|
657
|
+
y = rng.random(size=(2, 6))
|
658
|
+
res = stats.mannwhitneyu(x, y, method=stats.PermutationMethod(),
|
659
|
+
alternative=alternative, axis=1)
|
660
|
+
res2 = stats.mannwhitneyu(x, y, method='exact',
|
661
|
+
alternative=alternative, axis=1)
|
662
|
+
assert_allclose(res.statistic, res2.statistic, rtol=1e-15)
|
663
|
+
assert_allclose(res.pvalue, res2.pvalue, rtol=1e-15)
|
664
|
+
|
665
|
+
|
666
|
+
class TestSomersD(_TestPythranFunc):
|
667
|
+
def setup_method(self):
|
668
|
+
self.dtypes = self.ALL_INTEGER + self.ALL_FLOAT
|
669
|
+
self.arguments = {0: (np.arange(10),
|
670
|
+
self.ALL_INTEGER + self.ALL_FLOAT),
|
671
|
+
1: (np.arange(10),
|
672
|
+
self.ALL_INTEGER + self.ALL_FLOAT)}
|
673
|
+
input_array = [self.arguments[idx][0] for idx in self.arguments]
|
674
|
+
# In this case, self.partialfunc can simply be stats.somersd,
|
675
|
+
# since `alternative` is an optional argument. If it is required,
|
676
|
+
# we can use functools.partial to freeze the value, because
|
677
|
+
# we only mainly test various array inputs, not str, etc.
|
678
|
+
self.partialfunc = functools.partial(stats.somersd,
|
679
|
+
alternative='two-sided')
|
680
|
+
self.expected = self.partialfunc(*input_array)
|
681
|
+
|
682
|
+
def pythranfunc(self, *args):
|
683
|
+
res = self.partialfunc(*args)
|
684
|
+
assert_allclose(res.statistic, self.expected.statistic, atol=1e-15)
|
685
|
+
assert_allclose(res.pvalue, self.expected.pvalue, atol=1e-15)
|
686
|
+
|
687
|
+
def test_pythranfunc_keywords(self):
|
688
|
+
# Not specifying the optional keyword args
|
689
|
+
table = [[27, 25, 14, 7, 0], [7, 14, 18, 35, 12], [1, 3, 2, 7, 17]]
|
690
|
+
res1 = stats.somersd(table)
|
691
|
+
# Specifying the optional keyword args with default value
|
692
|
+
optional_args = self.get_optional_args(stats.somersd)
|
693
|
+
res2 = stats.somersd(table, **optional_args)
|
694
|
+
# Check if the results are the same in two cases
|
695
|
+
assert_allclose(res1.statistic, res2.statistic, atol=1e-15)
|
696
|
+
assert_allclose(res1.pvalue, res2.pvalue, atol=1e-15)
|
697
|
+
|
698
|
+
def test_like_kendalltau(self):
|
699
|
+
# All tests correspond with one in test_stats.py `test_kendalltau`
|
700
|
+
|
701
|
+
# case without ties, con-dis equal zero
|
702
|
+
x = [5, 2, 1, 3, 6, 4, 7, 8]
|
703
|
+
y = [5, 2, 6, 3, 1, 8, 7, 4]
|
704
|
+
# Cross-check with result from SAS FREQ:
|
705
|
+
expected = (0.000000000000000, 1.000000000000000)
|
706
|
+
res = stats.somersd(x, y)
|
707
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
708
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
709
|
+
|
710
|
+
# case without ties, con-dis equal zero
|
711
|
+
x = [0, 5, 2, 1, 3, 6, 4, 7, 8]
|
712
|
+
y = [5, 2, 0, 6, 3, 1, 8, 7, 4]
|
713
|
+
# Cross-check with result from SAS FREQ:
|
714
|
+
expected = (0.000000000000000, 1.000000000000000)
|
715
|
+
res = stats.somersd(x, y)
|
716
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
717
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
718
|
+
|
719
|
+
# case without ties, con-dis close to zero
|
720
|
+
x = [5, 2, 1, 3, 6, 4, 7]
|
721
|
+
y = [5, 2, 6, 3, 1, 7, 4]
|
722
|
+
# Cross-check with result from SAS FREQ:
|
723
|
+
expected = (-0.142857142857140, 0.630326953157670)
|
724
|
+
res = stats.somersd(x, y)
|
725
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
726
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
727
|
+
|
728
|
+
# simple case without ties
|
729
|
+
x = np.arange(10)
|
730
|
+
y = np.arange(10)
|
731
|
+
# Cross-check with result from SAS FREQ:
|
732
|
+
# SAS p value is not provided.
|
733
|
+
expected = (1.000000000000000, 0)
|
734
|
+
res = stats.somersd(x, y)
|
735
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
736
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
737
|
+
|
738
|
+
# swap a couple values and a couple more
|
739
|
+
x = np.arange(10)
|
740
|
+
y = np.array([0, 2, 1, 3, 4, 6, 5, 7, 8, 9])
|
741
|
+
# Cross-check with result from SAS FREQ:
|
742
|
+
expected = (0.911111111111110, 0.000000000000000)
|
743
|
+
res = stats.somersd(x, y)
|
744
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
745
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
746
|
+
|
747
|
+
# same in opposite direction
|
748
|
+
x = np.arange(10)
|
749
|
+
y = np.arange(10)[::-1]
|
750
|
+
# Cross-check with result from SAS FREQ:
|
751
|
+
# SAS p value is not provided.
|
752
|
+
expected = (-1.000000000000000, 0)
|
753
|
+
res = stats.somersd(x, y)
|
754
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
755
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
756
|
+
|
757
|
+
# swap a couple values and a couple more
|
758
|
+
x = np.arange(10)
|
759
|
+
y = np.array([9, 7, 8, 6, 5, 3, 4, 2, 1, 0])
|
760
|
+
# Cross-check with result from SAS FREQ:
|
761
|
+
expected = (-0.9111111111111111, 0.000000000000000)
|
762
|
+
res = stats.somersd(x, y)
|
763
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
764
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
765
|
+
|
766
|
+
# with some ties
|
767
|
+
x1 = [12, 2, 1, 12, 2]
|
768
|
+
x2 = [1, 4, 7, 1, 0]
|
769
|
+
# Cross-check with result from SAS FREQ:
|
770
|
+
expected = (-0.500000000000000, 0.304901788178780)
|
771
|
+
res = stats.somersd(x1, x2)
|
772
|
+
assert_allclose(res.statistic, expected[0], atol=1e-15)
|
773
|
+
assert_allclose(res.pvalue, expected[1], atol=1e-15)
|
774
|
+
|
775
|
+
# with only ties in one or both inputs
|
776
|
+
# SAS will not produce an output for these:
|
777
|
+
# NOTE: No statistics are computed for x * y because x has fewer
|
778
|
+
# than 2 nonmissing levels.
|
779
|
+
# WARNING: No OUTPUT data set is produced for this table because a
|
780
|
+
# row or column variable has fewer than 2 nonmissing levels and no
|
781
|
+
# statistics are computed.
|
782
|
+
|
783
|
+
res = stats.somersd([2, 2, 2], [2, 2, 2])
|
784
|
+
assert_allclose(res.statistic, np.nan)
|
785
|
+
assert_allclose(res.pvalue, np.nan)
|
786
|
+
|
787
|
+
res = stats.somersd([2, 0, 2], [2, 2, 2])
|
788
|
+
assert_allclose(res.statistic, np.nan)
|
789
|
+
assert_allclose(res.pvalue, np.nan)
|
790
|
+
|
791
|
+
res = stats.somersd([2, 2, 2], [2, 0, 2])
|
792
|
+
assert_allclose(res.statistic, np.nan)
|
793
|
+
assert_allclose(res.pvalue, np.nan)
|
794
|
+
|
795
|
+
res = stats.somersd([0], [0])
|
796
|
+
assert_allclose(res.statistic, np.nan)
|
797
|
+
assert_allclose(res.pvalue, np.nan)
|
798
|
+
|
799
|
+
# empty arrays provided as input
|
800
|
+
res = stats.somersd([], [])
|
801
|
+
assert_allclose(res.statistic, np.nan)
|
802
|
+
assert_allclose(res.pvalue, np.nan)
|
803
|
+
|
804
|
+
# test unequal length inputs
|
805
|
+
x = np.arange(10.)
|
806
|
+
y = np.arange(20.)
|
807
|
+
assert_raises(ValueError, stats.somersd, x, y)
|
808
|
+
|
809
|
+
def test_asymmetry(self):
|
810
|
+
# test that somersd is asymmetric w.r.t. input order and that
|
811
|
+
# convention is as described: first input is row variable & independent
|
812
|
+
# data is from Wikipedia:
|
813
|
+
# https://en.wikipedia.org/wiki/Somers%27_D
|
814
|
+
# but currently that example contradicts itself - it says X is
|
815
|
+
# independent yet take D_XY
|
816
|
+
|
817
|
+
x = [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 1, 2,
|
818
|
+
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
|
819
|
+
y = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
|
820
|
+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
821
|
+
# Cross-check with result from SAS FREQ:
|
822
|
+
d_cr = 0.272727272727270
|
823
|
+
d_rc = 0.342857142857140
|
824
|
+
p = 0.092891940883700 # same p-value for either direction
|
825
|
+
res = stats.somersd(x, y)
|
826
|
+
assert_allclose(res.statistic, d_cr, atol=1e-15)
|
827
|
+
assert_allclose(res.pvalue, p, atol=1e-4)
|
828
|
+
assert_equal(res.table.shape, (3, 2))
|
829
|
+
res = stats.somersd(y, x)
|
830
|
+
assert_allclose(res.statistic, d_rc, atol=1e-15)
|
831
|
+
assert_allclose(res.pvalue, p, atol=1e-15)
|
832
|
+
assert_equal(res.table.shape, (2, 3))
|
833
|
+
|
834
|
+
def test_somers_original(self):
|
835
|
+
# test against Somers' original paper [1]
|
836
|
+
|
837
|
+
# Table 5A
|
838
|
+
# Somers' convention was column IV
|
839
|
+
table = np.array([[8, 2], [6, 5], [3, 4], [1, 3], [2, 3]])
|
840
|
+
# Our convention (and that of SAS FREQ) is row IV
|
841
|
+
table = table.T
|
842
|
+
dyx = 129/340
|
843
|
+
assert_allclose(stats.somersd(table).statistic, dyx)
|
844
|
+
|
845
|
+
# table 7A - d_yx = 1
|
846
|
+
table = np.array([[25, 0], [85, 0], [0, 30]])
|
847
|
+
dxy, dyx = 3300/5425, 3300/3300
|
848
|
+
assert_allclose(stats.somersd(table).statistic, dxy)
|
849
|
+
assert_allclose(stats.somersd(table.T).statistic, dyx)
|
850
|
+
|
851
|
+
# table 7B - d_yx < 0
|
852
|
+
table = np.array([[25, 0], [0, 30], [85, 0]])
|
853
|
+
dyx = -1800/3300
|
854
|
+
assert_allclose(stats.somersd(table.T).statistic, dyx)
|
855
|
+
|
856
|
+
def test_contingency_table_with_zero_rows_cols(self):
|
857
|
+
# test that zero rows/cols in contingency table don't affect result
|
858
|
+
|
859
|
+
N = 100
|
860
|
+
shape = 4, 6
|
861
|
+
size = np.prod(shape)
|
862
|
+
|
863
|
+
rng = np.random.RandomState(0)
|
864
|
+
s = stats.multinomial.rvs(N, p=np.ones(size)/size,
|
865
|
+
random_state=rng).reshape(shape)
|
866
|
+
res = stats.somersd(s)
|
867
|
+
|
868
|
+
s2 = np.insert(s, 2, np.zeros(shape[1]), axis=0)
|
869
|
+
res2 = stats.somersd(s2)
|
870
|
+
|
871
|
+
s3 = np.insert(s, 2, np.zeros(shape[0]), axis=1)
|
872
|
+
res3 = stats.somersd(s3)
|
873
|
+
|
874
|
+
s4 = np.insert(s2, 2, np.zeros(shape[0]+1), axis=1)
|
875
|
+
res4 = stats.somersd(s4)
|
876
|
+
|
877
|
+
# Cross-check with result from SAS FREQ:
|
878
|
+
assert_allclose(res.statistic, -0.116981132075470, atol=1e-15)
|
879
|
+
assert_allclose(res.statistic, res2.statistic)
|
880
|
+
assert_allclose(res.statistic, res3.statistic)
|
881
|
+
assert_allclose(res.statistic, res4.statistic)
|
882
|
+
|
883
|
+
assert_allclose(res.pvalue, 0.156376448188150, atol=1e-15)
|
884
|
+
assert_allclose(res.pvalue, res2.pvalue)
|
885
|
+
assert_allclose(res.pvalue, res3.pvalue)
|
886
|
+
assert_allclose(res.pvalue, res4.pvalue)
|
887
|
+
|
888
|
+
def test_invalid_contingency_tables(self):
|
889
|
+
N = 100
|
890
|
+
shape = 4, 6
|
891
|
+
size = np.prod(shape)
|
892
|
+
|
893
|
+
rng = np.random.default_rng(0)
|
894
|
+
# start with a valid contingency table
|
895
|
+
s = stats.multinomial.rvs(N, p=np.ones(size)/size,
|
896
|
+
random_state=rng).reshape(shape)
|
897
|
+
|
898
|
+
s5 = s - 2
|
899
|
+
message = "All elements of the contingency table must be non-negative"
|
900
|
+
with assert_raises(ValueError, match=message):
|
901
|
+
stats.somersd(s5)
|
902
|
+
|
903
|
+
s6 = s + 0.01
|
904
|
+
message = "All elements of the contingency table must be integer"
|
905
|
+
with assert_raises(ValueError, match=message):
|
906
|
+
stats.somersd(s6)
|
907
|
+
|
908
|
+
message = ("At least two elements of the contingency "
|
909
|
+
"table must be nonzero.")
|
910
|
+
with assert_raises(ValueError, match=message):
|
911
|
+
stats.somersd([[]])
|
912
|
+
|
913
|
+
with assert_raises(ValueError, match=message):
|
914
|
+
stats.somersd([[1]])
|
915
|
+
|
916
|
+
s7 = np.zeros((3, 3))
|
917
|
+
with assert_raises(ValueError, match=message):
|
918
|
+
stats.somersd(s7)
|
919
|
+
|
920
|
+
s7[0, 1] = 1
|
921
|
+
with assert_raises(ValueError, match=message):
|
922
|
+
stats.somersd(s7)
|
923
|
+
|
924
|
+
def test_only_ranks_matter(self):
|
925
|
+
# only ranks of input data should matter
|
926
|
+
x = [1, 2, 3]
|
927
|
+
x2 = [-1, 2.1, np.inf]
|
928
|
+
y = [3, 2, 1]
|
929
|
+
y2 = [0, -0.5, -np.inf]
|
930
|
+
res = stats.somersd(x, y)
|
931
|
+
res2 = stats.somersd(x2, y2)
|
932
|
+
assert_equal(res.statistic, res2.statistic)
|
933
|
+
assert_equal(res.pvalue, res2.pvalue)
|
934
|
+
|
935
|
+
def test_contingency_table_return(self):
|
936
|
+
# check that contingency table is returned
|
937
|
+
x = np.arange(10)
|
938
|
+
y = np.arange(10)
|
939
|
+
res = stats.somersd(x, y)
|
940
|
+
assert_equal(res.table, np.eye(10))
|
941
|
+
|
942
|
+
def test_somersd_alternative(self):
|
943
|
+
# Test alternative parameter, asymptotic method (due to tie)
|
944
|
+
|
945
|
+
# Based on scipy.stats.test_stats.TestCorrSpearman2::test_alternative
|
946
|
+
x1 = [1, 2, 3, 4, 5]
|
947
|
+
x2 = [5, 6, 7, 8, 7]
|
948
|
+
|
949
|
+
# strong positive correlation
|
950
|
+
expected = stats.somersd(x1, x2, alternative="two-sided")
|
951
|
+
assert expected.statistic > 0
|
952
|
+
|
953
|
+
# rank correlation > 0 -> large "less" p-value
|
954
|
+
res = stats.somersd(x1, x2, alternative="less")
|
955
|
+
assert_equal(res.statistic, expected.statistic)
|
956
|
+
assert_allclose(res.pvalue, 1 - (expected.pvalue / 2))
|
957
|
+
|
958
|
+
# rank correlation > 0 -> small "greater" p-value
|
959
|
+
res = stats.somersd(x1, x2, alternative="greater")
|
960
|
+
assert_equal(res.statistic, expected.statistic)
|
961
|
+
assert_allclose(res.pvalue, expected.pvalue / 2)
|
962
|
+
|
963
|
+
# reverse the direction of rank correlation
|
964
|
+
x2.reverse()
|
965
|
+
|
966
|
+
# strong negative correlation
|
967
|
+
expected = stats.somersd(x1, x2, alternative="two-sided")
|
968
|
+
assert expected.statistic < 0
|
969
|
+
|
970
|
+
# rank correlation < 0 -> large "greater" p-value
|
971
|
+
res = stats.somersd(x1, x2, alternative="greater")
|
972
|
+
assert_equal(res.statistic, expected.statistic)
|
973
|
+
assert_allclose(res.pvalue, 1 - (expected.pvalue / 2))
|
974
|
+
|
975
|
+
# rank correlation < 0 -> small "less" p-value
|
976
|
+
res = stats.somersd(x1, x2, alternative="less")
|
977
|
+
assert_equal(res.statistic, expected.statistic)
|
978
|
+
assert_allclose(res.pvalue, expected.pvalue / 2)
|
979
|
+
|
980
|
+
with pytest.raises(ValueError, match="`alternative` must be..."):
|
981
|
+
stats.somersd(x1, x2, alternative="ekki-ekki")
|
982
|
+
|
983
|
+
@pytest.mark.parametrize("positive_correlation", (False, True))
|
984
|
+
def test_somersd_perfect_correlation(self, positive_correlation):
|
985
|
+
# Before the addition of `alternative`, perfect correlation was
|
986
|
+
# treated as a special case. Now it is treated like any other case, but
|
987
|
+
# make sure there are no divide by zero warnings or associated errors
|
988
|
+
|
989
|
+
x1 = np.arange(10)
|
990
|
+
x2 = x1 if positive_correlation else np.flip(x1)
|
991
|
+
expected_statistic = 1 if positive_correlation else -1
|
992
|
+
|
993
|
+
# perfect correlation -> small "two-sided" p-value (0)
|
994
|
+
res = stats.somersd(x1, x2, alternative="two-sided")
|
995
|
+
assert res.statistic == expected_statistic
|
996
|
+
assert res.pvalue == 0
|
997
|
+
|
998
|
+
# rank correlation > 0 -> large "less" p-value (1)
|
999
|
+
res = stats.somersd(x1, x2, alternative="less")
|
1000
|
+
assert res.statistic == expected_statistic
|
1001
|
+
assert res.pvalue == (1 if positive_correlation else 0)
|
1002
|
+
|
1003
|
+
# rank correlation > 0 -> small "greater" p-value (0)
|
1004
|
+
res = stats.somersd(x1, x2, alternative="greater")
|
1005
|
+
assert res.statistic == expected_statistic
|
1006
|
+
assert res.pvalue == (0 if positive_correlation else 1)
|
1007
|
+
|
1008
|
+
@pytest.mark.thread_unsafe
|
1009
|
+
def test_somersd_large_inputs_gh18132(self):
|
1010
|
+
# Test that large inputs where potential overflows could occur give
|
1011
|
+
# the expected output. This is tested in the case of binary inputs.
|
1012
|
+
# See gh-18126.
|
1013
|
+
|
1014
|
+
# generate lists of random classes 1-2 (binary)
|
1015
|
+
classes = [1, 2]
|
1016
|
+
n_samples = 10 ** 6
|
1017
|
+
random.seed(6272161)
|
1018
|
+
x = random.choices(classes, k=n_samples)
|
1019
|
+
y = random.choices(classes, k=n_samples)
|
1020
|
+
|
1021
|
+
# get value to compare with: sklearn output
|
1022
|
+
# from sklearn import metrics
|
1023
|
+
# val_auc_sklearn = metrics.roc_auc_score(x, y)
|
1024
|
+
# # convert to the Gini coefficient (Gini = (AUC*2)-1)
|
1025
|
+
# val_sklearn = 2 * val_auc_sklearn - 1
|
1026
|
+
val_sklearn = -0.001528138777036947
|
1027
|
+
|
1028
|
+
# calculate the Somers' D statistic, which should be equal to the
|
1029
|
+
# result of val_sklearn until approximately machine precision
|
1030
|
+
val_scipy = stats.somersd(x, y).statistic
|
1031
|
+
assert_allclose(val_sklearn, val_scipy, atol=1e-15)
|
1032
|
+
|
1033
|
+
|
1034
|
+
class TestBarnardExact:
|
1035
|
+
"""Some tests to show that barnard_exact() works correctly."""
|
1036
|
+
|
1037
|
+
@pytest.mark.parametrize(
|
1038
|
+
"input_sample,expected",
|
1039
|
+
[
|
1040
|
+
([[43, 40], [10, 39]], (3.555406779643, 0.000362832367)),
|
1041
|
+
([[100, 2], [1000, 5]], (-1.776382925679, 0.135126970878)),
|
1042
|
+
([[2, 7], [8, 2]], (-2.518474945157, 0.019210815430)),
|
1043
|
+
([[5, 1], [10, 10]], (1.449486150679, 0.156277546306)),
|
1044
|
+
([[5, 15], [20, 20]], (-1.851640199545, 0.066363501421)),
|
1045
|
+
([[5, 16], [20, 25]], (-1.609639949352, 0.116984852192)),
|
1046
|
+
([[10, 5], [10, 1]], (-1.449486150679, 0.177536588915)),
|
1047
|
+
([[5, 0], [1, 4]], (2.581988897472, 0.013671875000)),
|
1048
|
+
([[0, 1], [3, 2]], (-1.095445115010, 0.509667991877)),
|
1049
|
+
([[0, 2], [6, 4]], (-1.549193338483, 0.197019618792)),
|
1050
|
+
([[2, 7], [8, 2]], (-2.518474945157, 0.019210815430)),
|
1051
|
+
],
|
1052
|
+
)
|
1053
|
+
def test_precise(self, input_sample, expected):
|
1054
|
+
"""The expected values have been generated by R, using a resolution
|
1055
|
+
for the nuisance parameter of 1e-6 :
|
1056
|
+
```R
|
1057
|
+
library(Barnard)
|
1058
|
+
options(digits=10)
|
1059
|
+
barnard.test(43, 40, 10, 39, dp=1e-6, pooled=TRUE)
|
1060
|
+
```
|
1061
|
+
"""
|
1062
|
+
res = barnard_exact(input_sample)
|
1063
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1064
|
+
assert_allclose([statistic, pvalue], expected)
|
1065
|
+
|
1066
|
+
@pytest.mark.parametrize(
|
1067
|
+
"input_sample,expected",
|
1068
|
+
[
|
1069
|
+
([[43, 40], [10, 39]], (3.920362887717, 0.000289470662)),
|
1070
|
+
([[100, 2], [1000, 5]], (-1.139432816087, 0.950272080594)),
|
1071
|
+
([[2, 7], [8, 2]], (-3.079373904042, 0.020172119141)),
|
1072
|
+
([[5, 1], [10, 10]], (1.622375939458, 0.150599922226)),
|
1073
|
+
([[5, 15], [20, 20]], (-1.974771239528, 0.063038448651)),
|
1074
|
+
([[5, 16], [20, 25]], (-1.722122973346, 0.133329494287)),
|
1075
|
+
([[10, 5], [10, 1]], (-1.765469659009, 0.250566655215)),
|
1076
|
+
([[5, 0], [1, 4]], (5.477225575052, 0.007812500000)),
|
1077
|
+
([[0, 1], [3, 2]], (-1.224744871392, 0.509667991877)),
|
1078
|
+
([[0, 2], [6, 4]], (-1.732050807569, 0.197019618792)),
|
1079
|
+
([[2, 7], [8, 2]], (-3.079373904042, 0.020172119141)),
|
1080
|
+
],
|
1081
|
+
)
|
1082
|
+
def test_pooled_param(self, input_sample, expected):
|
1083
|
+
"""The expected values have been generated by R, using a resolution
|
1084
|
+
for the nuisance parameter of 1e-6 :
|
1085
|
+
```R
|
1086
|
+
library(Barnard)
|
1087
|
+
options(digits=10)
|
1088
|
+
barnard.test(43, 40, 10, 39, dp=1e-6, pooled=FALSE)
|
1089
|
+
```
|
1090
|
+
"""
|
1091
|
+
res = barnard_exact(input_sample, pooled=False)
|
1092
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1093
|
+
assert_allclose([statistic, pvalue], expected)
|
1094
|
+
|
1095
|
+
def test_raises(self):
|
1096
|
+
# test we raise an error for wrong input number of nuisances.
|
1097
|
+
error_msg = (
|
1098
|
+
"Number of points `n` must be strictly positive, found 0"
|
1099
|
+
)
|
1100
|
+
with assert_raises(ValueError, match=error_msg):
|
1101
|
+
barnard_exact([[1, 2], [3, 4]], n=0)
|
1102
|
+
|
1103
|
+
# test we raise an error for wrong shape of input.
|
1104
|
+
error_msg = "The input `table` must be of shape \\(2, 2\\)."
|
1105
|
+
with assert_raises(ValueError, match=error_msg):
|
1106
|
+
barnard_exact(np.arange(6).reshape(2, 3))
|
1107
|
+
|
1108
|
+
# Test all values must be positives
|
1109
|
+
error_msg = "All values in `table` must be nonnegative."
|
1110
|
+
with assert_raises(ValueError, match=error_msg):
|
1111
|
+
barnard_exact([[-1, 2], [3, 4]])
|
1112
|
+
|
1113
|
+
# Test value error on wrong alternative param
|
1114
|
+
error_msg = (
|
1115
|
+
"`alternative` should be one of {'two-sided', 'less', 'greater'},"
|
1116
|
+
" found .*"
|
1117
|
+
)
|
1118
|
+
with assert_raises(ValueError, match=error_msg):
|
1119
|
+
barnard_exact([[1, 2], [3, 4]], "not-correct")
|
1120
|
+
|
1121
|
+
@pytest.mark.parametrize(
|
1122
|
+
"input_sample,expected",
|
1123
|
+
[
|
1124
|
+
([[0, 0], [4, 3]], (1.0, 0)),
|
1125
|
+
],
|
1126
|
+
)
|
1127
|
+
def test_edge_cases(self, input_sample, expected):
|
1128
|
+
res = barnard_exact(input_sample)
|
1129
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1130
|
+
assert_equal(pvalue, expected[0])
|
1131
|
+
assert_equal(statistic, expected[1])
|
1132
|
+
|
1133
|
+
@pytest.mark.parametrize(
|
1134
|
+
"input_sample,expected",
|
1135
|
+
[
|
1136
|
+
([[0, 5], [0, 10]], (1.0, np.nan)),
|
1137
|
+
([[5, 0], [10, 0]], (1.0, np.nan)),
|
1138
|
+
],
|
1139
|
+
)
|
1140
|
+
def test_row_or_col_zero(self, input_sample, expected):
|
1141
|
+
res = barnard_exact(input_sample)
|
1142
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1143
|
+
assert_equal(pvalue, expected[0])
|
1144
|
+
assert_equal(statistic, expected[1])
|
1145
|
+
|
1146
|
+
@pytest.mark.parametrize(
|
1147
|
+
"input_sample,expected",
|
1148
|
+
[
|
1149
|
+
([[2, 7], [8, 2]], (-2.518474945157, 0.009886140845)),
|
1150
|
+
([[7, 200], [300, 8]], (-21.320036698460, 0.0)),
|
1151
|
+
([[21, 28], [1957, 6]], (-30.489638143953, 0.0)),
|
1152
|
+
],
|
1153
|
+
)
|
1154
|
+
@pytest.mark.parametrize("alternative", ["greater", "less"])
|
1155
|
+
def test_less_greater(self, input_sample, expected, alternative):
|
1156
|
+
"""
|
1157
|
+
"The expected values have been generated by R, using a resolution
|
1158
|
+
for the nuisance parameter of 1e-6 :
|
1159
|
+
```R
|
1160
|
+
library(Barnard)
|
1161
|
+
options(digits=10)
|
1162
|
+
a = barnard.test(2, 7, 8, 2, dp=1e-6, pooled=TRUE)
|
1163
|
+
a$p.value[1]
|
1164
|
+
```
|
1165
|
+
In this test, we are using the "one-sided" return value `a$p.value[1]`
|
1166
|
+
to test our pvalue.
|
1167
|
+
"""
|
1168
|
+
expected_stat, less_pvalue_expect = expected
|
1169
|
+
|
1170
|
+
if alternative == "greater":
|
1171
|
+
input_sample = np.array(input_sample)[:, ::-1]
|
1172
|
+
expected_stat = -expected_stat
|
1173
|
+
|
1174
|
+
res = barnard_exact(input_sample, alternative=alternative)
|
1175
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1176
|
+
assert_allclose(
|
1177
|
+
[statistic, pvalue], [expected_stat, less_pvalue_expect], atol=1e-7
|
1178
|
+
)
|
1179
|
+
|
1180
|
+
|
1181
|
+
class TestBoschlooExact:
|
1182
|
+
"""Some tests to show that boschloo_exact() works correctly."""
|
1183
|
+
|
1184
|
+
ATOL = 1e-7
|
1185
|
+
|
1186
|
+
@pytest.mark.parametrize(
|
1187
|
+
"input_sample,expected",
|
1188
|
+
[
|
1189
|
+
([[2, 7], [8, 2]], (0.01852173, 0.009886142)),
|
1190
|
+
([[5, 1], [10, 10]], (0.9782609, 0.9450994)),
|
1191
|
+
([[5, 16], [20, 25]], (0.08913823, 0.05827348)),
|
1192
|
+
([[10, 5], [10, 1]], (0.1652174, 0.08565611)),
|
1193
|
+
([[5, 0], [1, 4]], (1, 1)),
|
1194
|
+
([[0, 1], [3, 2]], (0.5, 0.34375)),
|
1195
|
+
([[2, 7], [8, 2]], (0.01852173, 0.009886142)),
|
1196
|
+
([[7, 12], [8, 3]], (0.06406797, 0.03410916)),
|
1197
|
+
([[10, 24], [25, 37]], (0.2009359, 0.1512882)),
|
1198
|
+
],
|
1199
|
+
)
|
1200
|
+
def test_less(self, input_sample, expected):
|
1201
|
+
"""The expected values have been generated by R, using a resolution
|
1202
|
+
for the nuisance parameter of 1e-8 :
|
1203
|
+
```R
|
1204
|
+
library(Exact)
|
1205
|
+
options(digits=10)
|
1206
|
+
data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
|
1207
|
+
a = exact.test(data, method="Boschloo", alternative="less",
|
1208
|
+
tsmethod="central", np.interval=TRUE, beta=1e-8)
|
1209
|
+
```
|
1210
|
+
"""
|
1211
|
+
res = boschloo_exact(input_sample, alternative="less")
|
1212
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1213
|
+
assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
|
1214
|
+
|
1215
|
+
@pytest.mark.parametrize(
|
1216
|
+
"input_sample,expected",
|
1217
|
+
[
|
1218
|
+
([[43, 40], [10, 39]], (0.0002875544, 0.0001615562)),
|
1219
|
+
([[2, 7], [8, 2]], (0.9990149, 0.9918327)),
|
1220
|
+
([[5, 1], [10, 10]], (0.1652174, 0.09008534)),
|
1221
|
+
([[5, 15], [20, 20]], (0.9849087, 0.9706997)),
|
1222
|
+
([[5, 16], [20, 25]], (0.972349, 0.9524124)),
|
1223
|
+
([[5, 0], [1, 4]], (0.02380952, 0.006865367)),
|
1224
|
+
([[0, 1], [3, 2]], (1, 1)),
|
1225
|
+
([[0, 2], [6, 4]], (1, 1)),
|
1226
|
+
([[2, 7], [8, 2]], (0.9990149, 0.9918327)),
|
1227
|
+
([[7, 12], [8, 3]], (0.9895302, 0.9771215)),
|
1228
|
+
([[10, 24], [25, 37]], (0.9012936, 0.8633275)),
|
1229
|
+
],
|
1230
|
+
)
|
1231
|
+
def test_greater(self, input_sample, expected):
|
1232
|
+
"""The expected values have been generated by R, using a resolution
|
1233
|
+
for the nuisance parameter of 1e-8 :
|
1234
|
+
```R
|
1235
|
+
library(Exact)
|
1236
|
+
options(digits=10)
|
1237
|
+
data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
|
1238
|
+
a = exact.test(data, method="Boschloo", alternative="greater",
|
1239
|
+
tsmethod="central", np.interval=TRUE, beta=1e-8)
|
1240
|
+
```
|
1241
|
+
"""
|
1242
|
+
res = boschloo_exact(input_sample, alternative="greater")
|
1243
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1244
|
+
assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
|
1245
|
+
|
1246
|
+
@pytest.mark.parametrize(
|
1247
|
+
"input_sample,expected",
|
1248
|
+
[
|
1249
|
+
([[43, 40], [10, 39]], (0.0002875544, 0.0003231115)),
|
1250
|
+
([[2, 7], [8, 2]], (0.01852173, 0.01977228)),
|
1251
|
+
([[5, 1], [10, 10]], (0.1652174, 0.1801707)),
|
1252
|
+
([[5, 16], [20, 25]], (0.08913823, 0.116547)),
|
1253
|
+
([[5, 0], [1, 4]], (0.02380952, 0.01373073)),
|
1254
|
+
([[0, 1], [3, 2]], (0.5, 0.6875)),
|
1255
|
+
([[2, 7], [8, 2]], (0.01852173, 0.01977228)),
|
1256
|
+
([[7, 12], [8, 3]], (0.06406797, 0.06821831)),
|
1257
|
+
],
|
1258
|
+
)
|
1259
|
+
def test_two_sided(self, input_sample, expected):
|
1260
|
+
"""The expected values have been generated by R, using a resolution
|
1261
|
+
for the nuisance parameter of 1e-8 :
|
1262
|
+
```R
|
1263
|
+
library(Exact)
|
1264
|
+
options(digits=10)
|
1265
|
+
data <- matrix(c(43, 10, 40, 39), 2, 2, byrow=TRUE)
|
1266
|
+
a = exact.test(data, method="Boschloo", alternative="two.sided",
|
1267
|
+
tsmethod="central", np.interval=TRUE, beta=1e-8)
|
1268
|
+
```
|
1269
|
+
"""
|
1270
|
+
res = boschloo_exact(input_sample, alternative="two-sided", n=64)
|
1271
|
+
# Need n = 64 for python 32-bit
|
1272
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1273
|
+
assert_allclose([statistic, pvalue], expected, atol=self.ATOL)
|
1274
|
+
|
1275
|
+
def test_raises(self):
|
1276
|
+
# test we raise an error for wrong input number of nuisances.
|
1277
|
+
error_msg = (
|
1278
|
+
"Number of points `n` must be strictly positive, found 0"
|
1279
|
+
)
|
1280
|
+
with assert_raises(ValueError, match=error_msg):
|
1281
|
+
boschloo_exact([[1, 2], [3, 4]], n=0)
|
1282
|
+
|
1283
|
+
# test we raise an error for wrong shape of input.
|
1284
|
+
error_msg = "The input `table` must be of shape \\(2, 2\\)."
|
1285
|
+
with assert_raises(ValueError, match=error_msg):
|
1286
|
+
boschloo_exact(np.arange(6).reshape(2, 3))
|
1287
|
+
|
1288
|
+
# Test all values must be positives
|
1289
|
+
error_msg = "All values in `table` must be nonnegative."
|
1290
|
+
with assert_raises(ValueError, match=error_msg):
|
1291
|
+
boschloo_exact([[-1, 2], [3, 4]])
|
1292
|
+
|
1293
|
+
# Test value error on wrong alternative param
|
1294
|
+
error_msg = (
|
1295
|
+
r"`alternative` should be one of \('two-sided', 'less', "
|
1296
|
+
r"'greater'\), found .*"
|
1297
|
+
)
|
1298
|
+
with assert_raises(ValueError, match=error_msg):
|
1299
|
+
boschloo_exact([[1, 2], [3, 4]], "not-correct")
|
1300
|
+
|
1301
|
+
@pytest.mark.parametrize(
|
1302
|
+
"input_sample,expected",
|
1303
|
+
[
|
1304
|
+
([[0, 5], [0, 10]], (np.nan, np.nan)),
|
1305
|
+
([[5, 0], [10, 0]], (np.nan, np.nan)),
|
1306
|
+
],
|
1307
|
+
)
|
1308
|
+
def test_row_or_col_zero(self, input_sample, expected):
|
1309
|
+
res = boschloo_exact(input_sample)
|
1310
|
+
statistic, pvalue = res.statistic, res.pvalue
|
1311
|
+
assert_equal(pvalue, expected[0])
|
1312
|
+
assert_equal(statistic, expected[1])
|
1313
|
+
|
1314
|
+
def test_two_sided_gt_1(self):
|
1315
|
+
# Check that returned p-value does not exceed 1 even when twice
|
1316
|
+
# the minimum of the one-sided p-values does. See gh-15345.
|
1317
|
+
tbl = [[1, 1], [13, 12]]
|
1318
|
+
pl = boschloo_exact(tbl, alternative='less').pvalue
|
1319
|
+
pg = boschloo_exact(tbl, alternative='greater').pvalue
|
1320
|
+
assert 2*min(pl, pg) > 1
|
1321
|
+
pt = boschloo_exact(tbl, alternative='two-sided').pvalue
|
1322
|
+
assert pt == 1.0
|
1323
|
+
|
1324
|
+
@pytest.mark.parametrize("alternative", ("less", "greater"))
|
1325
|
+
def test_against_fisher_exact(self, alternative):
|
1326
|
+
# Check that the statistic of `boschloo_exact` is the same as the
|
1327
|
+
# p-value of `fisher_exact` (for one-sided tests). See gh-15345.
|
1328
|
+
tbl = [[2, 7], [8, 2]]
|
1329
|
+
boschloo_stat = boschloo_exact(tbl, alternative=alternative).statistic
|
1330
|
+
fisher_p = stats.fisher_exact(tbl, alternative=alternative)[1]
|
1331
|
+
assert_allclose(boschloo_stat, fisher_p)
|
1332
|
+
|
1333
|
+
|
1334
|
+
class TestCvm_2samp:
|
1335
|
+
@pytest.mark.parametrize('args', [([], np.arange(5)),
|
1336
|
+
(np.arange(5), [1])])
|
1337
|
+
def test_too_small_input(self, args):
|
1338
|
+
with pytest.warns(SmallSampleWarning, match=too_small_1d_not_omit):
|
1339
|
+
res = cramervonmises_2samp(*args)
|
1340
|
+
assert_equal(res.statistic, np.nan)
|
1341
|
+
assert_equal(res.pvalue, np.nan)
|
1342
|
+
|
1343
|
+
def test_invalid_input(self):
|
1344
|
+
y = np.arange(5)
|
1345
|
+
msg = 'method must be either auto, exact or asymptotic'
|
1346
|
+
with pytest.raises(ValueError, match=msg):
|
1347
|
+
cramervonmises_2samp(y, y, 'xyz')
|
1348
|
+
|
1349
|
+
def test_list_input(self):
|
1350
|
+
x = [2, 3, 4, 7, 6]
|
1351
|
+
y = [0.2, 0.7, 12, 18]
|
1352
|
+
r1 = cramervonmises_2samp(x, y)
|
1353
|
+
r2 = cramervonmises_2samp(np.array(x), np.array(y))
|
1354
|
+
assert_equal((r1.statistic, r1.pvalue), (r2.statistic, r2.pvalue))
|
1355
|
+
|
1356
|
+
def test_example_conover(self):
|
1357
|
+
# Example 2 in Section 6.2 of W.J. Conover: Practical Nonparametric
|
1358
|
+
# Statistics, 1971.
|
1359
|
+
x = [7.6, 8.4, 8.6, 8.7, 9.3, 9.9, 10.1, 10.6, 11.2]
|
1360
|
+
y = [5.2, 5.7, 5.9, 6.5, 6.8, 8.2, 9.1, 9.8, 10.8, 11.3, 11.5, 12.3,
|
1361
|
+
12.5, 13.4, 14.6]
|
1362
|
+
r = cramervonmises_2samp(x, y)
|
1363
|
+
assert_allclose(r.statistic, 0.262, atol=1e-3)
|
1364
|
+
assert_allclose(r.pvalue, 0.18, atol=1e-2)
|
1365
|
+
|
1366
|
+
@pytest.mark.parametrize('statistic, m, n, pval',
|
1367
|
+
[(710, 5, 6, 48./462),
|
1368
|
+
(1897, 7, 7, 117./1716),
|
1369
|
+
(576, 4, 6, 2./210),
|
1370
|
+
(1764, 6, 7, 2./1716)])
|
1371
|
+
def test_exact_pvalue(self, statistic, m, n, pval):
|
1372
|
+
# the exact values are taken from Anderson: On the distribution of the
|
1373
|
+
# two-sample Cramer-von-Mises criterion, 1962.
|
1374
|
+
# The values are taken from Table 2, 3, 4 and 5
|
1375
|
+
assert_equal(_pval_cvm_2samp_exact(statistic, m, n), pval)
|
1376
|
+
|
1377
|
+
@pytest.mark.xslow
|
1378
|
+
def test_large_sample(self):
|
1379
|
+
# for large samples, the statistic U gets very large
|
1380
|
+
# do a sanity check that p-value is not 0, 1 or nan
|
1381
|
+
rng = np.random.default_rng(4367)
|
1382
|
+
x = distributions.norm.rvs(size=1000000, random_state=rng)
|
1383
|
+
y = distributions.norm.rvs(size=900000, random_state=rng)
|
1384
|
+
r = cramervonmises_2samp(x, y)
|
1385
|
+
assert_(0 < r.pvalue < 1)
|
1386
|
+
r = cramervonmises_2samp(x, y+0.1)
|
1387
|
+
assert_(0 < r.pvalue < 1)
|
1388
|
+
|
1389
|
+
def test_exact_vs_asymptotic(self):
|
1390
|
+
rng = np.random.RandomState(0)
|
1391
|
+
x = rng.rand(7)
|
1392
|
+
y = rng.rand(8)
|
1393
|
+
r1 = cramervonmises_2samp(x, y, method='exact')
|
1394
|
+
r2 = cramervonmises_2samp(x, y, method='asymptotic')
|
1395
|
+
assert_equal(r1.statistic, r2.statistic)
|
1396
|
+
assert_allclose(r1.pvalue, r2.pvalue, atol=1e-2)
|
1397
|
+
|
1398
|
+
def test_method_auto(self):
|
1399
|
+
x = np.arange(20)
|
1400
|
+
y = [0.5, 4.7, 13.1]
|
1401
|
+
r1 = cramervonmises_2samp(x, y, method='exact')
|
1402
|
+
r2 = cramervonmises_2samp(x, y, method='auto')
|
1403
|
+
assert_equal(r1.pvalue, r2.pvalue)
|
1404
|
+
# switch to asymptotic if one sample has more than 20 observations
|
1405
|
+
x = np.arange(21)
|
1406
|
+
r1 = cramervonmises_2samp(x, y, method='asymptotic')
|
1407
|
+
r2 = cramervonmises_2samp(x, y, method='auto')
|
1408
|
+
assert_equal(r1.pvalue, r2.pvalue)
|
1409
|
+
|
1410
|
+
def test_same_input(self):
|
1411
|
+
# make sure trivial edge case can be handled
|
1412
|
+
# note that _cdf_cvm_inf(0) = nan. implementation avoids nan by
|
1413
|
+
# returning pvalue=1 for very small values of the statistic
|
1414
|
+
x = np.arange(15)
|
1415
|
+
res = cramervonmises_2samp(x, x)
|
1416
|
+
assert_equal((res.statistic, res.pvalue), (0.0, 1.0))
|
1417
|
+
# check exact p-value
|
1418
|
+
res = cramervonmises_2samp(x[:4], x[:4])
|
1419
|
+
assert_equal((res.statistic, res.pvalue), (0.0, 1.0))
|
1420
|
+
|
1421
|
+
|
1422
|
+
class TestTukeyHSD:
|
1423
|
+
|
1424
|
+
data_same_size = ([24.5, 23.5, 26.4, 27.1, 29.9],
|
1425
|
+
[28.4, 34.2, 29.5, 32.2, 30.1],
|
1426
|
+
[26.1, 28.3, 24.3, 26.2, 27.8])
|
1427
|
+
data_diff_size = ([24.5, 23.5, 26.28, 26.4, 27.1, 29.9, 30.1, 30.1],
|
1428
|
+
[28.4, 34.2, 29.5, 32.2, 30.1],
|
1429
|
+
[26.1, 28.3, 24.3, 26.2, 27.8])
|
1430
|
+
extreme_size = ([24.5, 23.5, 26.4],
|
1431
|
+
[28.4, 34.2, 29.5, 32.2, 30.1, 28.4, 34.2, 29.5, 32.2,
|
1432
|
+
30.1],
|
1433
|
+
[26.1, 28.3, 24.3, 26.2, 27.8])
|
1434
|
+
|
1435
|
+
sas_same_size = """
|
1436
|
+
Comparison LowerCL Difference UpperCL Significance
|
1437
|
+
2 - 3 0.6908830568 4.34 7.989116943 1
|
1438
|
+
2 - 1 0.9508830568 4.6 8.249116943 1
|
1439
|
+
3 - 2 -7.989116943 -4.34 -0.6908830568 1
|
1440
|
+
3 - 1 -3.389116943 0.26 3.909116943 0
|
1441
|
+
1 - 2 -8.249116943 -4.6 -0.9508830568 1
|
1442
|
+
1 - 3 -3.909116943 -0.26 3.389116943 0
|
1443
|
+
"""
|
1444
|
+
|
1445
|
+
sas_diff_size = """
|
1446
|
+
Comparison LowerCL Difference UpperCL Significance
|
1447
|
+
2 - 1 0.2679292645 3.645 7.022070736 1
|
1448
|
+
2 - 3 0.5934764007 4.34 8.086523599 1
|
1449
|
+
1 - 2 -7.022070736 -3.645 -0.2679292645 1
|
1450
|
+
1 - 3 -2.682070736 0.695 4.072070736 0
|
1451
|
+
3 - 2 -8.086523599 -4.34 -0.5934764007 1
|
1452
|
+
3 - 1 -4.072070736 -0.695 2.682070736 0
|
1453
|
+
"""
|
1454
|
+
|
1455
|
+
sas_extreme = """
|
1456
|
+
Comparison LowerCL Difference UpperCL Significance
|
1457
|
+
2 - 3 1.561605075 4.34 7.118394925 1
|
1458
|
+
2 - 1 2.740784879 6.08 9.419215121 1
|
1459
|
+
3 - 2 -7.118394925 -4.34 -1.561605075 1
|
1460
|
+
3 - 1 -1.964526566 1.74 5.444526566 0
|
1461
|
+
1 - 2 -9.419215121 -6.08 -2.740784879 1
|
1462
|
+
1 - 3 -5.444526566 -1.74 1.964526566 0
|
1463
|
+
"""
|
1464
|
+
|
1465
|
+
@pytest.mark.parametrize("data,res_expect_str,atol",
|
1466
|
+
((data_same_size, sas_same_size, 1e-4),
|
1467
|
+
(data_diff_size, sas_diff_size, 1e-4),
|
1468
|
+
(extreme_size, sas_extreme, 1e-10),
|
1469
|
+
),
|
1470
|
+
ids=["equal size sample",
|
1471
|
+
"unequal sample size",
|
1472
|
+
"extreme sample size differences"])
|
1473
|
+
def test_compare_sas(self, data, res_expect_str, atol):
|
1474
|
+
'''
|
1475
|
+
SAS code used to generate results for each sample:
|
1476
|
+
DATA ACHE;
|
1477
|
+
INPUT BRAND RELIEF;
|
1478
|
+
CARDS;
|
1479
|
+
1 24.5
|
1480
|
+
...
|
1481
|
+
3 27.8
|
1482
|
+
;
|
1483
|
+
ods graphics on; ODS RTF;ODS LISTING CLOSE;
|
1484
|
+
PROC ANOVA DATA=ACHE;
|
1485
|
+
CLASS BRAND;
|
1486
|
+
MODEL RELIEF=BRAND;
|
1487
|
+
MEANS BRAND/TUKEY CLDIFF;
|
1488
|
+
TITLE 'COMPARE RELIEF ACROSS MEDICINES - ANOVA EXAMPLE';
|
1489
|
+
ods output CLDiffs =tc;
|
1490
|
+
proc print data=tc;
|
1491
|
+
format LowerCL 17.16 UpperCL 17.16 Difference 17.16;
|
1492
|
+
title "Output with many digits";
|
1493
|
+
RUN;
|
1494
|
+
QUIT;
|
1495
|
+
ODS RTF close;
|
1496
|
+
ODS LISTING;
|
1497
|
+
'''
|
1498
|
+
res_expect = np.asarray(res_expect_str.replace(" - ", " ").split()[5:],
|
1499
|
+
dtype=float).reshape((6, 6))
|
1500
|
+
res_tukey = stats.tukey_hsd(*data)
|
1501
|
+
conf = res_tukey.confidence_interval()
|
1502
|
+
# loop over the comparisons
|
1503
|
+
for i, j, l, s, h, sig in res_expect:
|
1504
|
+
i, j = int(i) - 1, int(j) - 1
|
1505
|
+
assert_allclose(conf.low[i, j], l, atol=atol)
|
1506
|
+
assert_allclose(res_tukey.statistic[i, j], s, atol=atol)
|
1507
|
+
assert_allclose(conf.high[i, j], h, atol=atol)
|
1508
|
+
assert_allclose((res_tukey.pvalue[i, j] <= .05), sig == 1)
|
1509
|
+
|
1510
|
+
matlab_sm_siz = """
|
1511
|
+
1 2 -8.2491590248597 -4.6 -0.9508409751403 0.0144483269098
|
1512
|
+
1 3 -3.9091590248597 -0.26 3.3891590248597 0.9803107240900
|
1513
|
+
2 3 0.6908409751403 4.34 7.9891590248597 0.0203311368795
|
1514
|
+
"""
|
1515
|
+
|
1516
|
+
matlab_diff_sz = """
|
1517
|
+
1 2 -7.02207069748501 -3.645 -0.26792930251500 0.03371498443080
|
1518
|
+
1 3 -2.68207069748500 0.695 4.07207069748500 0.85572267328807
|
1519
|
+
2 3 0.59347644287720 4.34 8.08652355712281 0.02259047020620
|
1520
|
+
"""
|
1521
|
+
|
1522
|
+
@pytest.mark.parametrize("data,res_expect_str,atol",
|
1523
|
+
((data_same_size, matlab_sm_siz, 1e-12),
|
1524
|
+
(data_diff_size, matlab_diff_sz, 1e-7)),
|
1525
|
+
ids=["equal size sample",
|
1526
|
+
"unequal size sample"])
|
1527
|
+
def test_compare_matlab(self, data, res_expect_str, atol):
|
1528
|
+
"""
|
1529
|
+
vals = [24.5, 23.5, 26.4, 27.1, 29.9, 28.4, 34.2, 29.5, 32.2, 30.1,
|
1530
|
+
26.1, 28.3, 24.3, 26.2, 27.8]
|
1531
|
+
names = {'zero', 'zero', 'zero', 'zero', 'zero', 'one', 'one', 'one',
|
1532
|
+
'one', 'one', 'two', 'two', 'two', 'two', 'two'}
|
1533
|
+
[p,t,stats] = anova1(vals,names,"off");
|
1534
|
+
[c,m,h,nms] = multcompare(stats, "CType","hsd");
|
1535
|
+
"""
|
1536
|
+
res_expect = np.asarray(res_expect_str.split(),
|
1537
|
+
dtype=float).reshape((3, 6))
|
1538
|
+
res_tukey = stats.tukey_hsd(*data)
|
1539
|
+
conf = res_tukey.confidence_interval()
|
1540
|
+
# loop over the comparisons
|
1541
|
+
for i, j, l, s, h, p in res_expect:
|
1542
|
+
i, j = int(i) - 1, int(j) - 1
|
1543
|
+
assert_allclose(conf.low[i, j], l, atol=atol)
|
1544
|
+
assert_allclose(res_tukey.statistic[i, j], s, atol=atol)
|
1545
|
+
assert_allclose(conf.high[i, j], h, atol=atol)
|
1546
|
+
assert_allclose(res_tukey.pvalue[i, j], p, atol=atol)
|
1547
|
+
|
1548
|
+
def test_compare_r(self):
|
1549
|
+
"""
|
1550
|
+
Testing against results and p-values from R:
|
1551
|
+
from: https://www.rdocumentation.org/packages/stats/versions/3.6.2/
|
1552
|
+
topics/TukeyHSD
|
1553
|
+
> require(graphics)
|
1554
|
+
> summary(fm1 <- aov(breaks ~ tension, data = warpbreaks))
|
1555
|
+
> TukeyHSD(fm1, "tension", ordered = TRUE)
|
1556
|
+
> plot(TukeyHSD(fm1, "tension"))
|
1557
|
+
Tukey multiple comparisons of means
|
1558
|
+
95% family-wise confidence level
|
1559
|
+
factor levels have been ordered
|
1560
|
+
Fit: aov(formula = breaks ~ tension, data = warpbreaks)
|
1561
|
+
$tension
|
1562
|
+
"""
|
1563
|
+
str_res = """
|
1564
|
+
diff lwr upr p adj
|
1565
|
+
2 - 3 4.722222 -4.8376022 14.28205 0.4630831
|
1566
|
+
1 - 3 14.722222 5.1623978 24.28205 0.0014315
|
1567
|
+
1 - 2 10.000000 0.4401756 19.55982 0.0384598
|
1568
|
+
"""
|
1569
|
+
res_expect = np.asarray(str_res.replace(" - ", " ").split()[5:],
|
1570
|
+
dtype=float).reshape((3, 6))
|
1571
|
+
data = ([26, 30, 54, 25, 70, 52, 51, 26, 67,
|
1572
|
+
27, 14, 29, 19, 29, 31, 41, 20, 44],
|
1573
|
+
[18, 21, 29, 17, 12, 18, 35, 30, 36,
|
1574
|
+
42, 26, 19, 16, 39, 28, 21, 39, 29],
|
1575
|
+
[36, 21, 24, 18, 10, 43, 28, 15, 26,
|
1576
|
+
20, 21, 24, 17, 13, 15, 15, 16, 28])
|
1577
|
+
|
1578
|
+
res_tukey = stats.tukey_hsd(*data)
|
1579
|
+
conf = res_tukey.confidence_interval()
|
1580
|
+
# loop over the comparisons
|
1581
|
+
for i, j, s, l, h, p in res_expect:
|
1582
|
+
i, j = int(i) - 1, int(j) - 1
|
1583
|
+
# atols are set to the number of digits present in the r result.
|
1584
|
+
assert_allclose(conf.low[i, j], l, atol=1e-7)
|
1585
|
+
assert_allclose(res_tukey.statistic[i, j], s, atol=1e-6)
|
1586
|
+
assert_allclose(conf.high[i, j], h, atol=1e-5)
|
1587
|
+
assert_allclose(res_tukey.pvalue[i, j], p, atol=1e-7)
|
1588
|
+
|
1589
|
+
def test_engineering_stat_handbook(self):
|
1590
|
+
'''
|
1591
|
+
Example sourced from:
|
1592
|
+
https://www.itl.nist.gov/div898/handbook/prc/section4/prc471.htm
|
1593
|
+
'''
|
1594
|
+
group1 = [6.9, 5.4, 5.8, 4.6, 4.0]
|
1595
|
+
group2 = [8.3, 6.8, 7.8, 9.2, 6.5]
|
1596
|
+
group3 = [8.0, 10.5, 8.1, 6.9, 9.3]
|
1597
|
+
group4 = [5.8, 3.8, 6.1, 5.6, 6.2]
|
1598
|
+
res = stats.tukey_hsd(group1, group2, group3, group4)
|
1599
|
+
conf = res.confidence_interval()
|
1600
|
+
lower = np.asarray([
|
1601
|
+
[0, 0, 0, -2.25],
|
1602
|
+
[.29, 0, -2.93, .13],
|
1603
|
+
[1.13, 0, 0, .97],
|
1604
|
+
[0, 0, 0, 0]])
|
1605
|
+
upper = np.asarray([
|
1606
|
+
[0, 0, 0, 1.93],
|
1607
|
+
[4.47, 0, 1.25, 4.31],
|
1608
|
+
[5.31, 0, 0, 5.15],
|
1609
|
+
[0, 0, 0, 0]])
|
1610
|
+
|
1611
|
+
for (i, j) in [(1, 0), (2, 0), (0, 3), (1, 2), (2, 3)]:
|
1612
|
+
assert_allclose(conf.low[i, j], lower[i, j], atol=1e-2)
|
1613
|
+
assert_allclose(conf.high[i, j], upper[i, j], atol=1e-2)
|
1614
|
+
|
1615
|
+
def test_rand_symm(self):
|
1616
|
+
# test some expected identities of the results
|
1617
|
+
np.random.seed(1234)
|
1618
|
+
data = np.random.rand(3, 100)
|
1619
|
+
res = stats.tukey_hsd(*data)
|
1620
|
+
conf = res.confidence_interval()
|
1621
|
+
# the confidence intervals should be negated symmetric of each other
|
1622
|
+
assert_equal(conf.low, -conf.high.T)
|
1623
|
+
# the `high` and `low` center diagonals should be the same since the
|
1624
|
+
# mean difference in a self comparison is 0.
|
1625
|
+
assert_equal(np.diagonal(conf.high), conf.high[0, 0])
|
1626
|
+
assert_equal(np.diagonal(conf.low), conf.low[0, 0])
|
1627
|
+
# statistic array should be antisymmetric with zeros on the diagonal
|
1628
|
+
assert_equal(res.statistic, -res.statistic.T)
|
1629
|
+
assert_equal(np.diagonal(res.statistic), 0)
|
1630
|
+
# p-values should be symmetric and 1 when compared to itself
|
1631
|
+
assert_equal(res.pvalue, res.pvalue.T)
|
1632
|
+
assert_equal(np.diagonal(res.pvalue), 1)
|
1633
|
+
|
1634
|
+
def test_no_inf(self):
|
1635
|
+
with assert_raises(ValueError, match="...must be finite."):
|
1636
|
+
stats.tukey_hsd([1, 2, 3], [2, np.inf], [6, 7, 3])
|
1637
|
+
|
1638
|
+
def test_is_1d(self):
|
1639
|
+
with assert_raises(ValueError, match="...must be one-dimensional"):
|
1640
|
+
stats.tukey_hsd([[1, 2], [2, 3]], [2, 5], [5, 23, 6])
|
1641
|
+
|
1642
|
+
def test_no_empty(self):
|
1643
|
+
with assert_raises(ValueError, match="...must be greater than one"):
|
1644
|
+
stats.tukey_hsd([], [2, 5], [4, 5, 6])
|
1645
|
+
|
1646
|
+
def test_equal_var_input_validation(self):
|
1647
|
+
msg = "Expected a boolean value for 'equal_var'"
|
1648
|
+
with assert_raises(TypeError, match=msg):
|
1649
|
+
stats.tukey_hsd([1, 2, 3], [2, 5], [6, 7], equal_var="False")
|
1650
|
+
|
1651
|
+
@pytest.mark.parametrize("nargs", (0, 1))
|
1652
|
+
def test_not_enough_treatments(self, nargs):
|
1653
|
+
with assert_raises(ValueError, match="...more than 1 treatment."):
|
1654
|
+
stats.tukey_hsd(*([[23, 7, 3]] * nargs))
|
1655
|
+
|
1656
|
+
@pytest.mark.parametrize("cl", [-.5, 0, 1, 2])
|
1657
|
+
def test_conf_level_invalid(self, cl):
|
1658
|
+
with assert_raises(ValueError, match="must be between 0 and 1"):
|
1659
|
+
r = stats.tukey_hsd([23, 7, 3], [3, 4], [9, 4])
|
1660
|
+
r.confidence_interval(cl)
|
1661
|
+
|
1662
|
+
def test_2_args_ttest(self):
|
1663
|
+
# that with 2 treatments the `pvalue` is equal to that of `ttest_ind`
|
1664
|
+
res_tukey = stats.tukey_hsd(*self.data_diff_size[:2])
|
1665
|
+
res_ttest = stats.ttest_ind(*self.data_diff_size[:2])
|
1666
|
+
assert_allclose(res_ttest.pvalue, res_tukey.pvalue[0, 1])
|
1667
|
+
assert_allclose(res_ttest.pvalue, res_tukey.pvalue[1, 0])
|
1668
|
+
|
1669
|
+
|
1670
|
+
class TestGamesHowell:
|
1671
|
+
# data with unequal variances
|
1672
|
+
data_same_size = ([24., 23., 31., 51.],
|
1673
|
+
[34., 18., 18., 26.],
|
1674
|
+
[17., 68., 59., 7.])
|
1675
|
+
|
1676
|
+
data_diff_size = ([30., 23., 51.],
|
1677
|
+
[-81., 71., -27., 63.],
|
1678
|
+
[42., 11., 29., 19., 50.],
|
1679
|
+
[23., 22., 20., 18., 9.])
|
1680
|
+
|
1681
|
+
spss_same_size = """
|
1682
|
+
Mean Diff Lower Bound Upper Bound Sig
|
1683
|
+
0 - 1 8.25000000 -16.5492749527311 33.0492749527311 0.558733632413559
|
1684
|
+
0 - 2 -5.50000000 -63.6702454316458 52.6702454316458 0.941147750599221
|
1685
|
+
1 - 2 -13.7500000 -74.3174374251372 46.8174374251372 0.682983914946841
|
1686
|
+
"""
|
1687
|
+
|
1688
|
+
spss_diff_size = """
|
1689
|
+
Mean Diff Lower Bound Upper Bound Sig
|
1690
|
+
0 - 1 28.16666667 -141.985416377670 198.318749711003 0.8727542747886180
|
1691
|
+
0 - 2 4.466666667 -37.2830676783904 46.2164010117237 0.9752628408671710
|
1692
|
+
0 - 3 16.26666667 -35.0933112382470 67.6266445715803 0.4262506151302880
|
1693
|
+
1 - 2 -23.70000000 -195.315617201249 147.915617201249 0.9148950609000590
|
1694
|
+
1 - 3 -11.90000000 -188.105478728519 164.305478728519 0.9861432250093960
|
1695
|
+
2 - 3 11.80000000 -16.2894857524254 39.8894857524254 0.4755344436335670
|
1696
|
+
"""
|
1697
|
+
|
1698
|
+
@pytest.mark.xslow
|
1699
|
+
@pytest.mark.parametrize("data, res_expect_str",
|
1700
|
+
((data_same_size, spss_same_size),
|
1701
|
+
(data_diff_size, spss_diff_size)),
|
1702
|
+
ids=["equal size sample",
|
1703
|
+
"unequal sample size"])
|
1704
|
+
def test_compare_spss(self, data, res_expect_str):
|
1705
|
+
"""
|
1706
|
+
DATA LIST LIST /Group (F1.0) Value (F8.2).
|
1707
|
+
BEGIN DATA
|
1708
|
+
0 24
|
1709
|
+
0 23
|
1710
|
+
0 31
|
1711
|
+
0 51
|
1712
|
+
1 34
|
1713
|
+
1 18
|
1714
|
+
1 18
|
1715
|
+
1 26
|
1716
|
+
2 17
|
1717
|
+
2 68
|
1718
|
+
2 59
|
1719
|
+
2 7
|
1720
|
+
END DATA.
|
1721
|
+
|
1722
|
+
ONEWAY Value BY Group
|
1723
|
+
/MISSING ANALYSIS
|
1724
|
+
/POSTHOC=GH ALPHA(0.05).
|
1725
|
+
"""
|
1726
|
+
res_expect = np.asarray(
|
1727
|
+
res_expect_str.replace(" - ", " ").split()[7:],
|
1728
|
+
dtype=float).reshape(-1, 6)
|
1729
|
+
res_games = stats.tukey_hsd(*data, equal_var=False)
|
1730
|
+
conf = res_games.confidence_interval()
|
1731
|
+
# loop over the comparisons
|
1732
|
+
for i, j, s, l, h, p in res_expect:
|
1733
|
+
i, j = int(i), int(j)
|
1734
|
+
assert_allclose(res_games.statistic[i, j], s, atol=1e-8)
|
1735
|
+
assert_allclose(res_games.pvalue[i, j], p, atol=1e-8)
|
1736
|
+
assert_allclose(conf.low[i, j], l, atol=1e-6)
|
1737
|
+
assert_allclose(conf.high[i, j], h, atol=1e-5)
|
1738
|
+
|
1739
|
+
r_same_size = """
|
1740
|
+
q value Pr(>|q|)
|
1741
|
+
1 - 0 == 0 -1.5467805948856344 0.55873362851759
|
1742
|
+
2 - 0 == 0 0.4726721776628535 0.94114775035993
|
1743
|
+
2 - 1 == 0 1.246837541297872 0.68298393799782
|
1744
|
+
"""
|
1745
|
+
|
1746
|
+
r_diff_size = """
|
1747
|
+
q value Pr(>|q|)
|
1748
|
+
1 - 0 == 0 -1.0589317485313876 0.87275427357438
|
1749
|
+
2 - 0 == 0 -0.5716222106144833 0.97526284087419
|
1750
|
+
3 - 0 == 0 -2.6209678382077000 0.42625067714691
|
1751
|
+
2 - 1 == 0 0.8971899898179028 0.91489506061850
|
1752
|
+
3 - 1 == 0 0.4579447210555352 0.98614322544695
|
1753
|
+
3 - 2 == 0 -2.198800177874794 0.47553444364614
|
1754
|
+
"""
|
1755
|
+
|
1756
|
+
@pytest.mark.parametrize("data, res_expect_str",
|
1757
|
+
((data_same_size, r_same_size),
|
1758
|
+
(data_diff_size, r_diff_size)),
|
1759
|
+
ids=["equal size sample",
|
1760
|
+
"unequal sample size"])
|
1761
|
+
def test_compare_r(self, data, res_expect_str):
|
1762
|
+
"""
|
1763
|
+
games-howell is provided by PMCMRplus package
|
1764
|
+
https://search.r-project.org/CRAN/refmans/PMCMRplus/html/gamesHowellTest.html
|
1765
|
+
> library("PMCMRplus")
|
1766
|
+
> options(digits=16)
|
1767
|
+
> table = data.frame(
|
1768
|
+
values = c(24., 23., 31., 51., 34., 18., 18., 26., 17., 68., 59., 7.),
|
1769
|
+
groups = c("0", "0", "0", "0", "1", "1", "1", "1", "2", "2", "2", "2")
|
1770
|
+
)
|
1771
|
+
> table$groups = as.factor(table$groups)
|
1772
|
+
> fit <-aov(values ~ groups, table)
|
1773
|
+
> res = gamesHowellTest(fit)
|
1774
|
+
> summary(res)
|
1775
|
+
"""
|
1776
|
+
res_expect = np.asarray(
|
1777
|
+
res_expect_str.replace(" - ", " ")
|
1778
|
+
.replace(" == ", " ").split()[3:],
|
1779
|
+
dtype=float).reshape(-1, 5)
|
1780
|
+
res_games = stats.tukey_hsd(*data, equal_var=False)
|
1781
|
+
# loop over the comparisons
|
1782
|
+
# note confidence intervals are not provided by PMCMRplus
|
1783
|
+
for j, i, _, _, p in res_expect:
|
1784
|
+
i, j = int(i), int(j)
|
1785
|
+
assert_allclose(res_games.pvalue[i, j], p, atol=1e-7)
|
1786
|
+
|
1787
|
+
# Data validation test has been covered by TestTukeyHSD
|
1788
|
+
# like empty, 1d, inf, and lack of tretments
|
1789
|
+
# because games_howell leverage _tukey_hsd_iv()
|
1790
|
+
|
1791
|
+
class TestPoissonMeansTest:
|
1792
|
+
@pytest.mark.parametrize("c1, n1, c2, n2, p_expect", (
|
1793
|
+
# example from [1], 6. Illustrative examples: Example 1
|
1794
|
+
[0, 100, 3, 100, 0.0884],
|
1795
|
+
[2, 100, 6, 100, 0.1749]
|
1796
|
+
))
|
1797
|
+
def test_paper_examples(self, c1, n1, c2, n2, p_expect):
|
1798
|
+
res = stats.poisson_means_test(c1, n1, c2, n2)
|
1799
|
+
assert_allclose(res.pvalue, p_expect, atol=1e-4)
|
1800
|
+
|
1801
|
+
@pytest.mark.parametrize("c1, n1, c2, n2, p_expect, alt, d", (
|
1802
|
+
# These test cases are produced by the wrapped fortran code from the
|
1803
|
+
# original authors. Using a slightly modified version of this fortran,
|
1804
|
+
# found here, https://github.com/nolanbconaway/poisson-etest,
|
1805
|
+
# additional tests were created.
|
1806
|
+
[20, 10, 20, 10, 0.9999997568929630, 'two-sided', 0],
|
1807
|
+
[10, 10, 10, 10, 0.9999998403241203, 'two-sided', 0],
|
1808
|
+
[50, 15, 1, 1, 0.09920321053409643, 'two-sided', .05],
|
1809
|
+
[3, 100, 20, 300, 0.12202725450896404, 'two-sided', 0],
|
1810
|
+
[3, 12, 4, 20, 0.40416087318539173, 'greater', 0],
|
1811
|
+
[4, 20, 3, 100, 0.008053640402974236, 'greater', 0],
|
1812
|
+
# publishing paper does not include a `less` alternative,
|
1813
|
+
# so it was calculated with switched argument order and
|
1814
|
+
# alternative="greater"
|
1815
|
+
[4, 20, 3, 10, 0.3083216325432898, 'less', 0],
|
1816
|
+
[1, 1, 50, 15, 0.09322998607245102, 'less', 0]
|
1817
|
+
))
|
1818
|
+
def test_fortran_authors(self, c1, n1, c2, n2, p_expect, alt, d):
|
1819
|
+
res = stats.poisson_means_test(c1, n1, c2, n2, alternative=alt, diff=d)
|
1820
|
+
assert_allclose(res.pvalue, p_expect, atol=2e-6, rtol=1e-16)
|
1821
|
+
|
1822
|
+
def test_different_results(self):
|
1823
|
+
# The implementation in Fortran is known to break down at higher
|
1824
|
+
# counts and observations, so we expect different results. By
|
1825
|
+
# inspection we can infer the p-value to be near one.
|
1826
|
+
count1, count2 = 10000, 10000
|
1827
|
+
nobs1, nobs2 = 10000, 10000
|
1828
|
+
res = stats.poisson_means_test(count1, nobs1, count2, nobs2)
|
1829
|
+
assert_allclose(res.pvalue, 1)
|
1830
|
+
|
1831
|
+
def test_less_than_zero_lambda_hat2(self):
|
1832
|
+
# demonstrates behavior that fixes a known fault from original Fortran.
|
1833
|
+
# p-value should clearly be near one.
|
1834
|
+
count1, count2 = 0, 0
|
1835
|
+
nobs1, nobs2 = 1, 1
|
1836
|
+
res = stats.poisson_means_test(count1, nobs1, count2, nobs2)
|
1837
|
+
assert_allclose(res.pvalue, 1)
|
1838
|
+
|
1839
|
+
def test_input_validation(self):
|
1840
|
+
count1, count2 = 0, 0
|
1841
|
+
nobs1, nobs2 = 1, 1
|
1842
|
+
|
1843
|
+
# test non-integral events
|
1844
|
+
message = '`k1` and `k2` must be integers.'
|
1845
|
+
with assert_raises(TypeError, match=message):
|
1846
|
+
stats.poisson_means_test(.7, nobs1, count2, nobs2)
|
1847
|
+
with assert_raises(TypeError, match=message):
|
1848
|
+
stats.poisson_means_test(count1, nobs1, .7, nobs2)
|
1849
|
+
|
1850
|
+
# test negative events
|
1851
|
+
message = '`k1` and `k2` must be greater than or equal to 0.'
|
1852
|
+
with assert_raises(ValueError, match=message):
|
1853
|
+
stats.poisson_means_test(-1, nobs1, count2, nobs2)
|
1854
|
+
with assert_raises(ValueError, match=message):
|
1855
|
+
stats.poisson_means_test(count1, nobs1, -1, nobs2)
|
1856
|
+
|
1857
|
+
# test negative sample size
|
1858
|
+
message = '`n1` and `n2` must be greater than 0.'
|
1859
|
+
with assert_raises(ValueError, match=message):
|
1860
|
+
stats.poisson_means_test(count1, -1, count2, nobs2)
|
1861
|
+
with assert_raises(ValueError, match=message):
|
1862
|
+
stats.poisson_means_test(count1, nobs1, count2, -1)
|
1863
|
+
|
1864
|
+
# test negative difference
|
1865
|
+
message = 'diff must be greater than or equal to 0.'
|
1866
|
+
with assert_raises(ValueError, match=message):
|
1867
|
+
stats.poisson_means_test(count1, nobs1, count2, nobs2, diff=-1)
|
1868
|
+
|
1869
|
+
# test invalid alternative
|
1870
|
+
message = 'Alternative must be one of ...'
|
1871
|
+
with assert_raises(ValueError, match=message):
|
1872
|
+
stats.poisson_means_test(1, 2, 1, 2, alternative='error')
|
1873
|
+
|
1874
|
+
|
1875
|
+
class TestBWSTest:
|
1876
|
+
|
1877
|
+
def test_bws_input_validation(self):
|
1878
|
+
rng = np.random.default_rng(4571775098104213308)
|
1879
|
+
|
1880
|
+
x, y = rng.random(size=(2, 7))
|
1881
|
+
|
1882
|
+
message = '`x` and `y` must be exactly one-dimensional.'
|
1883
|
+
with pytest.raises(ValueError, match=message):
|
1884
|
+
stats.bws_test([x, x], [y, y])
|
1885
|
+
|
1886
|
+
message = '`x` and `y` must not contain NaNs.'
|
1887
|
+
with pytest.raises(ValueError, match=message):
|
1888
|
+
stats.bws_test([np.nan], y)
|
1889
|
+
|
1890
|
+
message = '`x` and `y` must be of nonzero size.'
|
1891
|
+
with pytest.raises(ValueError, match=message):
|
1892
|
+
stats.bws_test(x, [])
|
1893
|
+
|
1894
|
+
message = 'alternative` must be one of...'
|
1895
|
+
with pytest.raises(ValueError, match=message):
|
1896
|
+
stats.bws_test(x, y, alternative='ekki-ekki')
|
1897
|
+
|
1898
|
+
message = 'method` must be an instance of...'
|
1899
|
+
with pytest.raises(ValueError, match=message):
|
1900
|
+
stats.bws_test(x, y, method=42)
|
1901
|
+
|
1902
|
+
|
1903
|
+
def test_against_published_reference(self):
|
1904
|
+
# Test against Example 2 in bws_test Reference [1], pg 9
|
1905
|
+
# https://link.springer.com/content/pdf/10.1007/BF02762032.pdf
|
1906
|
+
x = [1, 2, 3, 4, 6, 7, 8]
|
1907
|
+
y = [5, 9, 10, 11, 12, 13, 14]
|
1908
|
+
res = stats.bws_test(x, y, alternative='two-sided')
|
1909
|
+
assert_allclose(res.statistic, 5.132, atol=1e-3)
|
1910
|
+
assert_equal(res.pvalue, 10/3432)
|
1911
|
+
|
1912
|
+
|
1913
|
+
@pytest.mark.parametrize(('alternative', 'statistic', 'pvalue'),
|
1914
|
+
[('two-sided', 1.7510204081633, 0.1264422777777),
|
1915
|
+
('less', -1.7510204081633, 0.05754662004662),
|
1916
|
+
('greater', -1.7510204081633, 0.9424533799534)])
|
1917
|
+
def test_against_R(self, alternative, statistic, pvalue):
|
1918
|
+
# Test against R library BWStest function bws_test
|
1919
|
+
# library(BWStest)
|
1920
|
+
# options(digits=16)
|
1921
|
+
# x = c(...)
|
1922
|
+
# y = c(...)
|
1923
|
+
# bws_test(x, y, alternative='two.sided')
|
1924
|
+
rng = np.random.default_rng(4571775098104213308)
|
1925
|
+
x, y = rng.random(size=(2, 7))
|
1926
|
+
res = stats.bws_test(x, y, alternative=alternative)
|
1927
|
+
assert_allclose(res.statistic, statistic, rtol=1e-13)
|
1928
|
+
assert_allclose(res.pvalue, pvalue, atol=1e-2, rtol=1e-1)
|
1929
|
+
|
1930
|
+
@pytest.mark.parametrize(('alternative', 'statistic', 'pvalue'),
|
1931
|
+
[('two-sided', 1.142629265891, 0.2903950180801),
|
1932
|
+
('less', 0.99629665877411, 0.8545660222131),
|
1933
|
+
('greater', 0.99629665877411, 0.1454339777869)])
|
1934
|
+
def test_against_R_imbalanced(self, alternative, statistic, pvalue):
|
1935
|
+
# Test against R library BWStest function bws_test
|
1936
|
+
# library(BWStest)
|
1937
|
+
# options(digits=16)
|
1938
|
+
# x = c(...)
|
1939
|
+
# y = c(...)
|
1940
|
+
# bws_test(x, y, alternative='two.sided')
|
1941
|
+
rng = np.random.default_rng(5429015622386364034)
|
1942
|
+
x = rng.random(size=9)
|
1943
|
+
y = rng.random(size=8)
|
1944
|
+
res = stats.bws_test(x, y, alternative=alternative)
|
1945
|
+
assert_allclose(res.statistic, statistic, rtol=1e-13)
|
1946
|
+
assert_allclose(res.pvalue, pvalue, atol=1e-2, rtol=1e-1)
|
1947
|
+
|
1948
|
+
def test_method(self):
|
1949
|
+
# Test that `method` parameter has the desired effect
|
1950
|
+
rng = np.random.default_rng(1520514347193347862)
|
1951
|
+
x, y = rng.random(size=(2, 10))
|
1952
|
+
|
1953
|
+
rng = np.random.default_rng(1520514347193347862)
|
1954
|
+
method = stats.PermutationMethod(n_resamples=10, rng=rng)
|
1955
|
+
res1 = stats.bws_test(x, y, method=method)
|
1956
|
+
|
1957
|
+
assert len(res1.null_distribution) == 10
|
1958
|
+
|
1959
|
+
rng = np.random.default_rng(1520514347193347862)
|
1960
|
+
method = stats.PermutationMethod(n_resamples=10, rng=rng)
|
1961
|
+
res2 = stats.bws_test(x, y, method=method)
|
1962
|
+
|
1963
|
+
assert_allclose(res1.null_distribution, res2.null_distribution)
|
1964
|
+
|
1965
|
+
rng = np.random.default_rng(5205143471933478621)
|
1966
|
+
method = stats.PermutationMethod(n_resamples=10, rng=rng)
|
1967
|
+
res3 = stats.bws_test(x, y, method=method)
|
1968
|
+
|
1969
|
+
assert not np.allclose(res3.null_distribution, res1.null_distribution)
|
1970
|
+
|
1971
|
+
def test_directions(self):
|
1972
|
+
# Sanity check of the sign of the one-sided statistic
|
1973
|
+
rng = np.random.default_rng(1520514347193347862)
|
1974
|
+
x = rng.random(size=5)
|
1975
|
+
y = x - 1
|
1976
|
+
|
1977
|
+
res = stats.bws_test(x, y, alternative='greater')
|
1978
|
+
assert res.statistic > 0
|
1979
|
+
assert_equal(res.pvalue, 1 / len(res.null_distribution))
|
1980
|
+
|
1981
|
+
res = stats.bws_test(x, y, alternative='less')
|
1982
|
+
assert res.statistic > 0
|
1983
|
+
assert_equal(res.pvalue, 1)
|
1984
|
+
|
1985
|
+
res = stats.bws_test(y, x, alternative='less')
|
1986
|
+
assert res.statistic < 0
|
1987
|
+
assert_equal(res.pvalue, 1 / len(res.null_distribution))
|
1988
|
+
|
1989
|
+
res = stats.bws_test(y, x, alternative='greater')
|
1990
|
+
assert res.statistic < 0
|
1991
|
+
assert_equal(res.pvalue, 1)
|