scipy 1.16.2__cp311-cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_cyutility.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_lib/_ccallback_c.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_lib/_fpumode.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_lib/_test_ccallback.cp311-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp311-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_call.cp311-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp311-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_def.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_lib/_uarray/_uarray.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/_lib/messagestream.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/cluster/_hierarchy.cp311-win_arm64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.lib +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp311-win_arm64.pyd +0 -0
- scipy/cluster/_vq.cp311-win_arm64.lib +0 -0
- scipy/cluster/_vq.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/fftpack/convolve.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/integrate/_dop.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/integrate/_lsoda.cp311-win_arm64.pyd +0 -0
- scipy/integrate/_ode.py +1395 -0
- scipy/integrate/_odepack.cp311-win_arm64.lib +0 -0
- scipy/integrate/_odepack.cp311-win_arm64.pyd +0 -0
- scipy/integrate/_odepack_py.py +273 -0
- scipy/integrate/_quad_vec.py +674 -0
- scipy/integrate/_quadpack.cp311-win_arm64.lib +0 -0
- scipy/integrate/_quadpack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/integrate/_test_multivariate.cp311-win_arm64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp311-win_arm64.lib +0 -0
- scipy/integrate/_test_odeint_banded.cp311-win_arm64.pyd +0 -0
- scipy/integrate/_vode.cp311-win_arm64.lib +0 -0
- scipy/integrate/_vode.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_dfitpack.cp311-win_arm64.pyd +0 -0
- scipy/interpolate/_dierckx.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_dierckx.cp311-win_arm64.pyd +0 -0
- scipy/interpolate/_fitpack.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_fitpack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_interpnd.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_ppoly.cp311-win_arm64.pyd +0 -0
- scipy/interpolate/_rbf.py +290 -0
- scipy/interpolate/_rbfinterp.py +550 -0
- scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp311-win_arm64.pyd +0 -0
- scipy/interpolate/_rgi.py +764 -0
- scipy/interpolate/_rgi_cython.cp311-win_arm64.lib +0 -0
- scipy/interpolate/_rgi_cython.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/io/_test_fortran.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/io/matlab/_mio5_utils.cp311-win_arm64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp311-win_arm64.lib +0 -0
- scipy/io/matlab/_mio_utils.cp311-win_arm64.pyd +0 -0
- scipy/io/matlab/_miobase.py +435 -0
- scipy/io/matlab/_streams.cp311-win_arm64.lib +0 -0
- scipy/io/matlab/_streams.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/_cythonized_array_utils.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/_decomp_interpolative.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +356 -0
- scipy/linalg/_decomp_lu.py +401 -0
- scipy/linalg/_decomp_lu_cython.cp311-win_arm64.lib +0 -0
- scipy/linalg/_decomp_lu_cython.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/_decomp_update.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +417 -0
- scipy/linalg/_fblas.cp311-win_arm64.lib +0 -0
- scipy/linalg/_fblas.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_flapack.cp311-win_arm64.lib +0 -0
- scipy/linalg/_flapack.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_lapack_subroutines.h +1521 -0
- scipy/linalg/_linalg_pythran.cp311-win_arm64.lib +0 -0
- scipy/linalg/_linalg_pythran.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs.py +1050 -0
- scipy/linalg/_matfuncs_expm.cp311-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_expm.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +107 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/_solve_toeplitz.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/linalg/cython_blas.cp311-win_arm64.pyd +0 -0
- scipy/linalg/cython_blas.pxd +169 -0
- scipy/linalg/cython_blas.pyx +1432 -0
- scipy/linalg/cython_lapack.cp311-win_arm64.lib +0 -0
- scipy/linalg/cython_lapack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/ndimage/_ctest.cp311-win_arm64.pyd +0 -0
- scipy/ndimage/_cytest.cp311-win_arm64.lib +0 -0
- scipy/ndimage/_cytest.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/ndimage/_nd_image.cp311-win_arm64.pyd +0 -0
- scipy/ndimage/_ndimage_api.py +16 -0
- scipy/ndimage/_ni_docstrings.py +214 -0
- scipy/ndimage/_ni_label.cp311-win_arm64.lib +0 -0
- scipy/ndimage/_ni_label.cp311-win_arm64.pyd +0 -0
- scipy/ndimage/_ni_support.py +139 -0
- scipy/ndimage/_rank_filter_1d.cp311-win_arm64.lib +0 -0
- scipy/ndimage/_rank_filter_1d.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/odr/__odrpack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_bglu_dense.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_direct.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_group_columns.cp311-win_arm64.pyd +0 -0
- scipy/optimize/_hessian_update_strategy.py +479 -0
- scipy/optimize/_highspy/__init__.py +0 -0
- scipy/optimize/_highspy/_core.cp311-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_core.cp311-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp311-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_highs_options.cp311-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_wrapper.py +338 -0
- scipy/optimize/_isotonic.py +157 -0
- scipy/optimize/_lbfgsb.cp311-win_arm64.lib +0 -0
- scipy/optimize/_lbfgsb.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_lsap.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_lsq/givens_elimination.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_minpack.cp311-win_arm64.pyd +0 -0
- scipy/optimize/_minpack_py.py +1178 -0
- scipy/optimize/_moduleTNC.cp311-win_arm64.lib +0 -0
- scipy/optimize/_moduleTNC.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_pava_pybind.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_slsqplib.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_trlib/_trlib.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/_zeros.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/optimize/cython_optimize/_zeros.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/signal/_max_len_seq_inner.cp311-win_arm64.pyd +0 -0
- scipy/signal/_peak_finding.py +1310 -0
- scipy/signal/_peak_finding_utils.cp311-win_arm64.lib +0 -0
- scipy/signal/_peak_finding_utils.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/signal/_sigtools.cp311-win_arm64.pyd +0 -0
- scipy/signal/_sosfilt.cp311-win_arm64.lib +0 -0
- scipy/signal/_sosfilt.cp311-win_arm64.pyd +0 -0
- scipy/signal/_spectral_py.py +2471 -0
- scipy/signal/_spline.cp311-win_arm64.lib +0 -0
- scipy/signal/_spline.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/signal/_upfirdn_apply.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/_csparsetools.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/_sparsetools.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_flow.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_laplacian.py +563 -0
- scipy/sparse/csgraph/_matching.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_matching.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_reordering.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_shortest_path.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_tools.cp311-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp311-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_traversal.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp311-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp311-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp311-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp311-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/spatial/_ckdtree.cp311-win_arm64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp311-win_arm64.lib +0 -0
- scipy/spatial/_distance_pybind.cp311-win_arm64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp311-win_arm64.lib +0 -0
- scipy/spatial/_distance_wrap.cp311-win_arm64.pyd +0 -0
- scipy/spatial/_geometric_slerp.py +238 -0
- scipy/spatial/_hausdorff.cp311-win_arm64.lib +0 -0
- scipy/spatial/_hausdorff.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/spatial/_qhull.cp311-win_arm64.pyd +0 -0
- scipy/spatial/_qhull.pyi +213 -0
- scipy/spatial/_spherical_voronoi.py +341 -0
- scipy/spatial/_voronoi.cp311-win_arm64.lib +0 -0
- scipy/spatial/_voronoi.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/spatial/transform/_rigid_transform.cp311-win_arm64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp311-win_arm64.lib +0 -0
- scipy/spatial/transform/_rotation.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/special/_comb.cp311-win_arm64.pyd +0 -0
- scipy/special/_ellip_harm.py +214 -0
- scipy/special/_ellip_harm_2.cp311-win_arm64.lib +0 -0
- scipy/special/_ellip_harm_2.cp311-win_arm64.pyd +0 -0
- scipy/special/_gufuncs.cp311-win_arm64.lib +0 -0
- scipy/special/_gufuncs.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/special/_specfun.cp311-win_arm64.pyd +0 -0
- scipy/special/_special_ufuncs.cp311-win_arm64.lib +0 -0
- scipy/special/_special_ufuncs.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/special/_test_internal.cp311-win_arm64.pyd +0 -0
- scipy/special/_test_internal.pyi +9 -0
- scipy/special/_testutils.py +321 -0
- scipy/special/_ufuncs.cp311-win_arm64.lib +0 -0
- scipy/special/_ufuncs.cp311-win_arm64.pyd +0 -0
- scipy/special/_ufuncs.pyi +522 -0
- scipy/special/_ufuncs.pyx +13173 -0
- scipy/special/_ufuncs_cxx.cp311-win_arm64.lib +0 -0
- scipy/special/_ufuncs_cxx.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/special/cython_special.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_ansari_swilk_statistics.cp311-win_arm64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +692 -0
- scipy/stats/_biasedurn.cp311-win_arm64.lib +0 -0
- scipy/stats/_biasedurn.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_levy_stable/levyst.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_qmc_cy.cp311-win_arm64.pyd +0 -0
- scipy/stats/_qmc_cy.pyi +54 -0
- scipy/stats/_qmvnt.py +454 -0
- scipy/stats/_qmvnt_cy.cp311-win_arm64.lib +0 -0
- scipy/stats/_qmvnt_cy.cp311-win_arm64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/__init__.py +4 -0
- scipy/stats/_rcont/rcont.cp311-win_arm64.lib +0 -0
- scipy/stats/_rcont/rcont.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_sobol.cp311-win_arm64.pyd +0 -0
- scipy/stats/_sobol.pyi +54 -0
- scipy/stats/_sobol_direction_numbers.npz +0 -0
- scipy/stats/_stats.cp311-win_arm64.lib +0 -0
- scipy/stats/_stats.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_stats_pythran.cp311-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.cp311-win_arm64.lib +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp311-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,2198 @@
|
|
1
|
+
import itertools as it
|
2
|
+
import os
|
3
|
+
import pickle
|
4
|
+
from copy import deepcopy
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
from numpy import inf
|
8
|
+
import pytest
|
9
|
+
from numpy.testing import assert_allclose, assert_equal
|
10
|
+
from hypothesis import strategies, given, reproduce_failure, settings # noqa: F401
|
11
|
+
import hypothesis.extra.numpy as npst
|
12
|
+
|
13
|
+
from scipy import special
|
14
|
+
from scipy import stats
|
15
|
+
from scipy.stats._fit import _kolmogorov_smirnov
|
16
|
+
from scipy.stats._ksstats import kolmogn
|
17
|
+
from scipy.stats import qmc
|
18
|
+
from scipy.stats._distr_params import distcont, distdiscrete
|
19
|
+
from scipy.stats._distribution_infrastructure import (
|
20
|
+
_Domain, _RealInterval, _Parameter, _Parameterization, _RealParameter,
|
21
|
+
ContinuousDistribution, ShiftedScaledDistribution, _fiinfo,
|
22
|
+
_generate_domain_support, Mixture)
|
23
|
+
from scipy.stats._new_distributions import StandardNormal, _LogUniform, _Gamma
|
24
|
+
from scipy.stats._new_distributions import DiscreteDistribution
|
25
|
+
from scipy.stats import Normal, Uniform, Binomial
|
26
|
+
|
27
|
+
|
28
|
+
class Test_RealInterval:
|
29
|
+
rng = np.random.default_rng(349849812549824)
|
30
|
+
|
31
|
+
def test_iv(self):
|
32
|
+
domain = _RealInterval(endpoints=('a', 'b'))
|
33
|
+
message = "The endpoints of the distribution are defined..."
|
34
|
+
with pytest.raises(TypeError, match=message):
|
35
|
+
domain.get_numerical_endpoints(dict)
|
36
|
+
|
37
|
+
|
38
|
+
@pytest.mark.parametrize('x', [rng.uniform(10, 10, size=(2, 3, 4)),
|
39
|
+
-np.inf, np.pi])
|
40
|
+
def test_contains_simple(self, x):
|
41
|
+
# Test `contains` when endpoints are defined by constants
|
42
|
+
a, b = -np.inf, np.pi
|
43
|
+
domain = _RealInterval(endpoints=(a, b), inclusive=(False, True))
|
44
|
+
assert_equal(domain.contains(x), (a < x) & (x <= b))
|
45
|
+
|
46
|
+
@pytest.mark.slow
|
47
|
+
@given(shapes=npst.mutually_broadcastable_shapes(num_shapes=3, min_side=0),
|
48
|
+
inclusive_a=strategies.booleans(),
|
49
|
+
inclusive_b=strategies.booleans(),
|
50
|
+
data=strategies.data())
|
51
|
+
@pytest.mark.thread_unsafe
|
52
|
+
def test_contains(self, shapes, inclusive_a, inclusive_b, data):
|
53
|
+
# Test `contains` when endpoints are defined by parameters
|
54
|
+
input_shapes, result_shape = shapes
|
55
|
+
shape_a, shape_b, shape_x = input_shapes
|
56
|
+
|
57
|
+
# Without defining min and max values, I spent forever trying to set
|
58
|
+
# up a valid test without overflows or similar just drawing arrays.
|
59
|
+
a_elements = dict(allow_nan=False, allow_infinity=False,
|
60
|
+
min_value=-1e3, max_value=1)
|
61
|
+
b_elements = dict(allow_nan=False, allow_infinity=False,
|
62
|
+
min_value=2, max_value=1e3)
|
63
|
+
a = data.draw(npst.arrays(npst.floating_dtypes(),
|
64
|
+
shape_a, elements=a_elements))
|
65
|
+
b = data.draw(npst.arrays(npst.floating_dtypes(),
|
66
|
+
shape_b, elements=b_elements))
|
67
|
+
# ensure some points are to the left, some to the right, and some
|
68
|
+
# are exactly on the boundary
|
69
|
+
d = b - a
|
70
|
+
x = np.concatenate([np.linspace(a-d, a, 10),
|
71
|
+
np.linspace(a, b, 10),
|
72
|
+
np.linspace(b, b+d, 10)])
|
73
|
+
# Domain is defined by two parameters, 'a' and 'b'
|
74
|
+
domain = _RealInterval(endpoints=('a', 'b'),
|
75
|
+
inclusive=(inclusive_a, inclusive_b))
|
76
|
+
domain.define_parameters(_RealParameter('a', domain=_RealInterval()),
|
77
|
+
_RealParameter('b', domain=_RealInterval()))
|
78
|
+
# Check that domain and string evaluation give the same result
|
79
|
+
res = domain.contains(x, dict(a=a, b=b))
|
80
|
+
|
81
|
+
# Apparently, `np.float16([2]) < np.float32(2.0009766)` is False
|
82
|
+
# but `np.float16([2]) < np.float32([2.0009766])` is True
|
83
|
+
# dtype = np.result_type(a.dtype, b.dtype, x.dtype)
|
84
|
+
# a, b, x = a.astype(dtype), b.astype(dtype), x.astype(dtype)
|
85
|
+
# unclear whether we should be careful about this, since it will be
|
86
|
+
# fixed with NEP50. Just do what makes the test pass.
|
87
|
+
left_comparison = '<=' if inclusive_a else '<'
|
88
|
+
right_comparison = '<=' if inclusive_b else '<'
|
89
|
+
ref = eval(f'(a {left_comparison} x) & (x {right_comparison} b)')
|
90
|
+
assert_equal(res, ref)
|
91
|
+
|
92
|
+
@pytest.mark.parametrize("inclusive", list(it.product([True, False], repeat=2)))
|
93
|
+
@pytest.mark.parametrize("a,b", [(0, 1), (3, 1)])
|
94
|
+
def test_contains_function_endpoints(self, inclusive, a, b):
|
95
|
+
# Test `contains` when endpoints are defined by functions.
|
96
|
+
endpoints = (lambda a, b: (a - b) / 2, lambda a, b: (a + b) / 2)
|
97
|
+
domain = _RealInterval(endpoints=endpoints, inclusive=inclusive)
|
98
|
+
x = np.asarray([(a - 2*b)/2, (a - b)/2, a/2, (a + b)/2, (a + 2*b)/2])
|
99
|
+
res = domain.contains(x, dict(a=a, b=b))
|
100
|
+
|
101
|
+
numerical_endpoints = ((a - b) / 2, (a + b) / 2)
|
102
|
+
assert numerical_endpoints == domain.get_numerical_endpoints(dict(a=a, b=b))
|
103
|
+
alpha, beta = numerical_endpoints
|
104
|
+
|
105
|
+
above_left = alpha <= x if inclusive[0] else alpha < x
|
106
|
+
below_right = x <= beta if inclusive[1] else x < beta
|
107
|
+
ref = above_left & below_right
|
108
|
+
assert_equal(res, ref)
|
109
|
+
|
110
|
+
|
111
|
+
@pytest.mark.parametrize('case', [
|
112
|
+
(-np.inf, np.pi, False, True, r"(-\infty, \pi]"),
|
113
|
+
('a', 5, True, False, "[a, 5)")
|
114
|
+
])
|
115
|
+
def test_str(self, case):
|
116
|
+
domain = _RealInterval(endpoints=case[:2], inclusive=case[2:4])
|
117
|
+
assert str(domain) == case[4]
|
118
|
+
|
119
|
+
@pytest.mark.slow
|
120
|
+
@given(a=strategies.one_of(
|
121
|
+
strategies.decimals(allow_nan=False),
|
122
|
+
strategies.characters(whitelist_categories="L"), # type: ignore[arg-type]
|
123
|
+
strategies.sampled_from(list(_Domain.symbols))),
|
124
|
+
b=strategies.one_of(
|
125
|
+
strategies.decimals(allow_nan=False),
|
126
|
+
strategies.characters(whitelist_categories="L"), # type: ignore[arg-type]
|
127
|
+
strategies.sampled_from(list(_Domain.symbols))),
|
128
|
+
inclusive_a=strategies.booleans(),
|
129
|
+
inclusive_b=strategies.booleans(),
|
130
|
+
)
|
131
|
+
@pytest.mark.thread_unsafe
|
132
|
+
def test_str2(self, a, b, inclusive_a, inclusive_b):
|
133
|
+
# I wrote this independently from the implementation of __str__, but
|
134
|
+
# I imagine it looks pretty similar to __str__.
|
135
|
+
a = _Domain.symbols.get(a, a)
|
136
|
+
b = _Domain.symbols.get(b, b)
|
137
|
+
left_bracket = '[' if inclusive_a else '('
|
138
|
+
right_bracket = ']' if inclusive_b else ')'
|
139
|
+
domain = _RealInterval(endpoints=(a, b),
|
140
|
+
inclusive=(inclusive_a, inclusive_b))
|
141
|
+
ref = f"{left_bracket}{a}, {b}{right_bracket}"
|
142
|
+
assert str(domain) == ref
|
143
|
+
|
144
|
+
def test_symbols_gh22137(self):
|
145
|
+
# `symbols` was accidentally shared between instances originally
|
146
|
+
# Check that this is no longer the case
|
147
|
+
domain1 = _RealInterval(endpoints=(0, 1))
|
148
|
+
domain2 = _RealInterval(endpoints=(0, 1))
|
149
|
+
assert domain1.symbols is not domain2.symbols
|
150
|
+
|
151
|
+
|
152
|
+
def draw_distribution_from_family(family, data, rng, proportions, min_side=0):
|
153
|
+
# If the distribution has parameters, choose a parameterization and
|
154
|
+
# draw broadcastable shapes for the parameter arrays.
|
155
|
+
n_parameterizations = family._num_parameterizations()
|
156
|
+
if n_parameterizations > 0:
|
157
|
+
i = data.draw(strategies.integers(0, max_value=n_parameterizations-1))
|
158
|
+
n_parameters = family._num_parameters(i)
|
159
|
+
shapes, result_shape = data.draw(
|
160
|
+
npst.mutually_broadcastable_shapes(num_shapes=n_parameters,
|
161
|
+
min_side=min_side))
|
162
|
+
dist = family._draw(shapes, rng=rng, proportions=proportions,
|
163
|
+
i_parameterization=i)
|
164
|
+
else:
|
165
|
+
dist = family._draw(rng=rng)
|
166
|
+
result_shape = tuple()
|
167
|
+
|
168
|
+
# Draw a broadcastable shape for the arguments, and draw values for the
|
169
|
+
# arguments.
|
170
|
+
x_shape = data.draw(npst.broadcastable_shapes(result_shape,
|
171
|
+
min_side=min_side))
|
172
|
+
x = dist._variable.draw(x_shape, parameter_values=dist._parameters,
|
173
|
+
proportions=proportions, rng=rng, region='typical')
|
174
|
+
x_result_shape = np.broadcast_shapes(x_shape, result_shape)
|
175
|
+
y_shape = data.draw(npst.broadcastable_shapes(x_result_shape,
|
176
|
+
min_side=min_side))
|
177
|
+
y = dist._variable.draw(y_shape, parameter_values=dist._parameters,
|
178
|
+
proportions=proportions, rng=rng, region='typical')
|
179
|
+
xy_result_shape = np.broadcast_shapes(y_shape, x_result_shape)
|
180
|
+
p_domain = _RealInterval((0, 1), (True, True))
|
181
|
+
p_var = _RealParameter('p', domain=p_domain)
|
182
|
+
p = p_var.draw(x_shape, proportions=proportions, rng=rng)
|
183
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
184
|
+
logp = np.log(p)
|
185
|
+
|
186
|
+
return dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape
|
187
|
+
|
188
|
+
|
189
|
+
continuous_families = [
|
190
|
+
StandardNormal,
|
191
|
+
Normal,
|
192
|
+
Uniform,
|
193
|
+
_LogUniform
|
194
|
+
]
|
195
|
+
|
196
|
+
discrete_families = [
|
197
|
+
Binomial,
|
198
|
+
]
|
199
|
+
|
200
|
+
families = continuous_families + discrete_families
|
201
|
+
|
202
|
+
|
203
|
+
class TestDistributions:
|
204
|
+
@pytest.mark.fail_slow(60) # need to break up check_moment_funcs
|
205
|
+
@settings(max_examples=20)
|
206
|
+
@pytest.mark.parametrize('family', families)
|
207
|
+
@given(data=strategies.data(), seed=strategies.integers(min_value=0))
|
208
|
+
@pytest.mark.thread_unsafe
|
209
|
+
def test_support_moments_sample(self, family, data, seed):
|
210
|
+
rng = np.random.default_rng(seed)
|
211
|
+
|
212
|
+
# relative proportions of valid, endpoint, out of bounds, and NaN params
|
213
|
+
proportions = (0.7, 0.1, 0.1, 0.1)
|
214
|
+
tmp = draw_distribution_from_family(family, data, rng, proportions)
|
215
|
+
dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
|
216
|
+
sample_shape = data.draw(npst.array_shapes(min_dims=0, min_side=0,
|
217
|
+
max_side=20))
|
218
|
+
|
219
|
+
with np.errstate(invalid='ignore', divide='ignore'):
|
220
|
+
check_support(dist)
|
221
|
+
check_moment_funcs(dist, result_shape) # this needs to get split up
|
222
|
+
check_sample_shape_NaNs(dist, 'sample', sample_shape, result_shape, rng)
|
223
|
+
qrng = qmc.Halton(d=1, seed=rng)
|
224
|
+
check_sample_shape_NaNs(dist, 'sample', sample_shape, result_shape, qrng)
|
225
|
+
|
226
|
+
@pytest.mark.fail_slow(10)
|
227
|
+
@pytest.mark.parametrize('family', families)
|
228
|
+
@pytest.mark.parametrize('func, methods, arg',
|
229
|
+
[('entropy', {'log/exp', 'quadrature'}, None),
|
230
|
+
('logentropy', {'log/exp', 'quadrature'}, None),
|
231
|
+
('median', {'icdf'}, None),
|
232
|
+
('mode', {'optimization'}, None),
|
233
|
+
('mean', {'cache'}, None),
|
234
|
+
('variance', {'cache'}, None),
|
235
|
+
('skewness', {'cache'}, None),
|
236
|
+
('kurtosis', {'cache'}, None),
|
237
|
+
('pdf', {'log/exp'}, 'x'),
|
238
|
+
('logpdf', {'log/exp'}, 'x'),
|
239
|
+
('logcdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
|
240
|
+
('cdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
|
241
|
+
('logccdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
|
242
|
+
('ccdf', {'log/exp', 'complement', 'quadrature'}, 'x'),
|
243
|
+
('ilogccdf', {'complement', 'inversion'}, 'logp'),
|
244
|
+
('iccdf', {'complement', 'inversion'}, 'p'),
|
245
|
+
])
|
246
|
+
@settings(max_examples=20)
|
247
|
+
@given(data=strategies.data(), seed=strategies.integers(min_value=0))
|
248
|
+
@pytest.mark.thread_unsafe
|
249
|
+
def test_funcs(self, family, data, seed, func, methods, arg):
|
250
|
+
if family == Uniform and func == 'mode':
|
251
|
+
pytest.skip("Mode is not unique; `method`s disagree.")
|
252
|
+
|
253
|
+
rng = np.random.default_rng(seed)
|
254
|
+
|
255
|
+
# relative proportions of valid, endpoint, out of bounds, and NaN params
|
256
|
+
proportions = (0.7, 0.1, 0.1, 0.1)
|
257
|
+
tmp = draw_distribution_from_family(family, data, rng, proportions)
|
258
|
+
dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
|
259
|
+
|
260
|
+
args = {'x': x, 'p': p, 'logp': p}
|
261
|
+
with np.errstate(invalid='ignore', divide='ignore', over='ignore'):
|
262
|
+
if arg is None:
|
263
|
+
check_dist_func(dist, func, None, result_shape, methods)
|
264
|
+
elif arg in args:
|
265
|
+
check_dist_func(dist, func, args[arg], x_result_shape, methods)
|
266
|
+
|
267
|
+
if func == 'variance':
|
268
|
+
assert_allclose(dist.standard_deviation()**2, dist.variance())
|
269
|
+
|
270
|
+
# invalid and divide are to be expected; maybe look into over
|
271
|
+
with np.errstate(invalid='ignore', divide='ignore', over='ignore'):
|
272
|
+
if not isinstance(dist, ShiftedScaledDistribution):
|
273
|
+
if func == 'cdf':
|
274
|
+
methods = {'quadrature'}
|
275
|
+
check_cdf2(dist, False, x, y, xy_result_shape, methods)
|
276
|
+
check_cdf2(dist, True, x, y, xy_result_shape, methods)
|
277
|
+
elif func == 'ccdf':
|
278
|
+
methods = {'addition'}
|
279
|
+
check_ccdf2(dist, False, x, y, xy_result_shape, methods)
|
280
|
+
check_ccdf2(dist, True, x, y, xy_result_shape, methods)
|
281
|
+
|
282
|
+
@pytest.mark.thread_unsafe
|
283
|
+
def test_plot(self):
|
284
|
+
try:
|
285
|
+
import matplotlib.pyplot as plt
|
286
|
+
except ImportError:
|
287
|
+
return
|
288
|
+
|
289
|
+
X = Uniform(a=0., b=1.)
|
290
|
+
ax = X.plot()
|
291
|
+
assert ax == plt.gca()
|
292
|
+
|
293
|
+
@pytest.mark.parametrize('method_name', ['cdf', 'ccdf'])
|
294
|
+
def test_complement_safe(self, method_name):
|
295
|
+
X = stats.Normal()
|
296
|
+
X.tol = 1e-12
|
297
|
+
p = np.asarray([1e-4, 1e-3])
|
298
|
+
func = getattr(X, method_name)
|
299
|
+
ifunc = getattr(X, 'i'+method_name)
|
300
|
+
x = ifunc(p, method='formula')
|
301
|
+
p1 = func(x, method='complement_safe')
|
302
|
+
p2 = func(x, method='complement')
|
303
|
+
assert_equal(p1[1], p2[1])
|
304
|
+
assert p1[0] != p2[0]
|
305
|
+
assert_allclose(p1[0], p[0], rtol=X.tol)
|
306
|
+
|
307
|
+
@pytest.mark.parametrize('method_name', ['cdf', 'ccdf'])
|
308
|
+
def test_icomplement_safe(self, method_name):
|
309
|
+
X = stats.Normal()
|
310
|
+
X.tol = 1e-12
|
311
|
+
p = np.asarray([1e-4, 1e-3])
|
312
|
+
func = getattr(X, method_name)
|
313
|
+
ifunc = getattr(X, 'i'+method_name)
|
314
|
+
x1 = ifunc(p, method='complement_safe')
|
315
|
+
x2 = ifunc(p, method='complement')
|
316
|
+
assert_equal(x1[1], x2[1])
|
317
|
+
assert x1[0] != x2[0]
|
318
|
+
assert_allclose(func(x1[0]), p[0], rtol=X.tol)
|
319
|
+
|
320
|
+
def test_subtraction_safe(self):
|
321
|
+
X = stats.Normal()
|
322
|
+
X.tol = 1e-12
|
323
|
+
|
324
|
+
# Regular subtraction is fine in either tail (and of course, across tails)
|
325
|
+
x = [-11, -10, 10, 11]
|
326
|
+
y = [-10, -11, 11, 10]
|
327
|
+
p0 = X.cdf(x, y, method='quadrature')
|
328
|
+
p1 = X.cdf(x, y, method='subtraction_safe')
|
329
|
+
p2 = X.cdf(x, y, method='subtraction')
|
330
|
+
assert_equal(p2, p1)
|
331
|
+
assert_allclose(p1, p0, rtol=X.tol)
|
332
|
+
|
333
|
+
# Safe subtraction is needed in special cases
|
334
|
+
x = np.asarray([-1e-20, -1e-21, 1e-20, 1e-21, -1e-20])
|
335
|
+
y = np.asarray([-1e-21, -1e-20, 1e-21, 1e-20, 1e-20])
|
336
|
+
|
337
|
+
|
338
|
+
p0 = X.pdf(0)*(y-x)
|
339
|
+
p1 = X.cdf(x, y, method='subtraction_safe')
|
340
|
+
p2 = X.cdf(x, y, method='subtraction')
|
341
|
+
assert_equal(p2, 0)
|
342
|
+
assert_allclose(p1, p0, rtol=X.tol)
|
343
|
+
|
344
|
+
def test_logentropy_safe(self):
|
345
|
+
# simulate an `entropy` calculation over/underflowing with extreme parameters
|
346
|
+
class _Normal(stats.Normal):
|
347
|
+
def _entropy_formula(self, **params):
|
348
|
+
out = np.asarray(super()._entropy_formula(**params))
|
349
|
+
out[0] = 0
|
350
|
+
out[-1] = np.inf
|
351
|
+
return out
|
352
|
+
|
353
|
+
X = _Normal(sigma=[1, 2, 3])
|
354
|
+
with np.errstate(divide='ignore'):
|
355
|
+
res1 = X.logentropy(method='logexp_safe')
|
356
|
+
res2 = X.logentropy(method='logexp')
|
357
|
+
ref = X.logentropy(method='quadrature')
|
358
|
+
i_fl = [0, -1] # first and last
|
359
|
+
assert np.isinf(res2[i_fl]).all()
|
360
|
+
assert res1[1] == res2[1]
|
361
|
+
# quadrature happens to be perfectly accurate on some platforms
|
362
|
+
# assert res1[1] != ref[1]
|
363
|
+
assert_equal(res1[i_fl], ref[i_fl])
|
364
|
+
|
365
|
+
def test_logcdf2_safe(self):
|
366
|
+
# test what happens when 2-arg `cdf` underflows
|
367
|
+
X = stats.Normal(sigma=[1, 2, 3])
|
368
|
+
x = [-301, 1, 300]
|
369
|
+
y = [-300, 2, 301]
|
370
|
+
with np.errstate(divide='ignore'):
|
371
|
+
res1 = X.logcdf(x, y, method='logexp_safe')
|
372
|
+
res2 = X.logcdf(x, y, method='logexp')
|
373
|
+
ref = X.logcdf(x, y, method='quadrature')
|
374
|
+
i_fl = [0, -1] # first and last
|
375
|
+
assert np.isinf(res2[i_fl]).all()
|
376
|
+
assert res1[1] == res2[1]
|
377
|
+
# quadrature happens to be perfectly accurate on some platforms
|
378
|
+
# assert res1[1] != ref[1]
|
379
|
+
assert_equal(res1[i_fl], ref[i_fl])
|
380
|
+
|
381
|
+
@pytest.mark.parametrize('method_name', ['logcdf', 'logccdf'])
|
382
|
+
def test_logexp_safe(self, method_name):
|
383
|
+
# test what happens when `cdf`/`ccdf` underflows
|
384
|
+
X = stats.Normal(sigma=2)
|
385
|
+
x = [-301, 1] if method_name == 'logcdf' else [301, 1]
|
386
|
+
func = getattr(X, method_name)
|
387
|
+
with np.errstate(divide='ignore'):
|
388
|
+
res1 = func(x, method='logexp_safe')
|
389
|
+
res2 = func(x, method='logexp')
|
390
|
+
ref = func(x, method='quadrature')
|
391
|
+
assert res1[0] == ref[0]
|
392
|
+
assert res1[0] != res2[0]
|
393
|
+
assert res1[1] == res2[1]
|
394
|
+
assert res1[1] != ref[1]
|
395
|
+
|
396
|
+
def check_sample_shape_NaNs(dist, fname, sample_shape, result_shape, rng):
|
397
|
+
full_shape = sample_shape + result_shape
|
398
|
+
if fname == 'sample':
|
399
|
+
sample_method = dist.sample
|
400
|
+
|
401
|
+
methods = {'inverse_transform'}
|
402
|
+
if dist._overrides(f'_{fname}_formula') and not isinstance(rng, qmc.QMCEngine):
|
403
|
+
methods.add('formula')
|
404
|
+
|
405
|
+
for method in methods:
|
406
|
+
res = sample_method(sample_shape, method=method, rng=rng)
|
407
|
+
valid_parameters = np.broadcast_to(get_valid_parameters(dist),
|
408
|
+
res.shape)
|
409
|
+
assert_equal(res.shape, full_shape)
|
410
|
+
np.testing.assert_equal(res.dtype, dist._dtype)
|
411
|
+
|
412
|
+
if full_shape == ():
|
413
|
+
# NumPy random makes a distinction between a 0d array and a scalar.
|
414
|
+
# In stats, we consistently turn 0d arrays into scalars, so
|
415
|
+
# maintain that behavior here. (With Array API arrays, this will
|
416
|
+
# change.)
|
417
|
+
assert np.isscalar(res)
|
418
|
+
assert np.all(np.isfinite(res[valid_parameters]))
|
419
|
+
assert_equal(res[~valid_parameters], np.nan)
|
420
|
+
|
421
|
+
sample1 = sample_method(sample_shape, method=method, rng=42)
|
422
|
+
sample2 = sample_method(sample_shape, method=method, rng=42)
|
423
|
+
if not isinstance(dist, DiscreteDistribution):
|
424
|
+
# The idea is that it's very unlikely that the random sample
|
425
|
+
# for a randomly chosen seed will match that for seed 42,
|
426
|
+
# but it is not so unlikely if `dist` is a discrete distribution.
|
427
|
+
assert not np.any(np.equal(res, sample1))
|
428
|
+
assert_equal(sample1, sample2)
|
429
|
+
|
430
|
+
|
431
|
+
def check_support(dist):
|
432
|
+
a, b = dist.support()
|
433
|
+
check_nans_and_edges(dist, 'support', None, a)
|
434
|
+
check_nans_and_edges(dist, 'support', None, b)
|
435
|
+
assert a.shape == dist._shape
|
436
|
+
assert b.shape == dist._shape
|
437
|
+
assert a.dtype == dist._dtype
|
438
|
+
assert b.dtype == dist._dtype
|
439
|
+
|
440
|
+
|
441
|
+
def check_dist_func(dist, fname, arg, result_shape, methods):
|
442
|
+
# Check that all computation methods of all distribution functions agree
|
443
|
+
# with one another, effectively testing the correctness of the generic
|
444
|
+
# computation methods and confirming the consistency of specific
|
445
|
+
# distributions with their pdf/logpdf.
|
446
|
+
|
447
|
+
args = tuple() if arg is None else (arg,)
|
448
|
+
methods = methods.copy()
|
449
|
+
|
450
|
+
if "cache" in methods:
|
451
|
+
# If "cache" is specified before the value has been evaluated, it
|
452
|
+
# raises an error. After the value is evaluated, it will succeed.
|
453
|
+
with pytest.raises(NotImplementedError):
|
454
|
+
getattr(dist, fname)(*args, method="cache")
|
455
|
+
|
456
|
+
ref = getattr(dist, fname)(*args)
|
457
|
+
check_nans_and_edges(dist, fname, arg, ref)
|
458
|
+
|
459
|
+
# Remove this after fixing `draw`
|
460
|
+
tol_override = {'atol': 1e-15}
|
461
|
+
# Mean can be 0, which makes logmean -inf.
|
462
|
+
if fname in {'logmean', 'mean', 'logskewness', 'skewness'}:
|
463
|
+
tol_override = {'atol': 1e-15}
|
464
|
+
elif fname in {'mode'}:
|
465
|
+
# can only expect about half of machine precision for optimization
|
466
|
+
# because math
|
467
|
+
tol_override = {'atol': 1e-6}
|
468
|
+
elif fname in {'logcdf'}: # gh-22276
|
469
|
+
tol_override = {'rtol': 2e-7}
|
470
|
+
|
471
|
+
if dist._overrides(f'_{fname}_formula'):
|
472
|
+
methods.add('formula')
|
473
|
+
|
474
|
+
np.testing.assert_equal(ref.shape, result_shape)
|
475
|
+
# Until we convert to array API, let's do the familiar thing:
|
476
|
+
# 0d things are scalars, not arrays
|
477
|
+
if result_shape == tuple():
|
478
|
+
assert np.isscalar(ref)
|
479
|
+
|
480
|
+
for method in methods:
|
481
|
+
res = getattr(dist, fname)(*args, method=method)
|
482
|
+
if 'log' in fname:
|
483
|
+
np.testing.assert_allclose(np.exp(res), np.exp(ref),
|
484
|
+
**tol_override)
|
485
|
+
else:
|
486
|
+
np.testing.assert_allclose(res, ref, **tol_override)
|
487
|
+
|
488
|
+
# for now, make sure dtypes are consistent; later, we can check whether
|
489
|
+
# they are correct.
|
490
|
+
np.testing.assert_equal(res.dtype, ref.dtype)
|
491
|
+
np.testing.assert_equal(res.shape, result_shape)
|
492
|
+
if result_shape == tuple():
|
493
|
+
assert np.isscalar(res)
|
494
|
+
|
495
|
+
def check_cdf2(dist, log, x, y, result_shape, methods):
|
496
|
+
# Specialized test for 2-arg cdf since the interface is a bit different
|
497
|
+
# from the other methods. Here, we'll use 1-arg cdf as a reference, and
|
498
|
+
# since we have already checked 1-arg cdf in `check_nans_and_edges`, this
|
499
|
+
# checks the equivalent of both `check_dist_func` and
|
500
|
+
# `check_nans_and_edges`.
|
501
|
+
methods = methods.copy()
|
502
|
+
|
503
|
+
if log:
|
504
|
+
if dist._overrides('_logcdf2_formula'):
|
505
|
+
methods.add('formula')
|
506
|
+
if dist._overrides('_logcdf_formula') or dist._overrides('_logccdf_formula'):
|
507
|
+
methods.add('subtraction')
|
508
|
+
if (dist._overrides('_cdf_formula')
|
509
|
+
or dist._overrides('_ccdf_formula')):
|
510
|
+
methods.add('log/exp')
|
511
|
+
else:
|
512
|
+
if dist._overrides('_cdf2_formula'):
|
513
|
+
methods.add('formula')
|
514
|
+
if dist._overrides('_cdf_formula') or dist._overrides('_ccdf_formula'):
|
515
|
+
methods.add('subtraction')
|
516
|
+
if (dist._overrides('_logcdf_formula')
|
517
|
+
or dist._overrides('_logccdf_formula')):
|
518
|
+
methods.add('log/exp')
|
519
|
+
|
520
|
+
ref = dist.cdf(y) - dist.cdf(x)
|
521
|
+
np.testing.assert_equal(ref.shape, result_shape)
|
522
|
+
|
523
|
+
if result_shape == tuple():
|
524
|
+
assert np.isscalar(ref)
|
525
|
+
|
526
|
+
for method in methods:
|
527
|
+
if isinstance(dist, DiscreteDistribution):
|
528
|
+
message = ("Two argument cdf functions are currently only supported for "
|
529
|
+
"continuous distributions.")
|
530
|
+
with pytest.raises(NotImplementedError, match=message):
|
531
|
+
res = (np.exp(dist.logcdf(x, y, method=method)) if log
|
532
|
+
else dist.cdf(x, y, method=method))
|
533
|
+
continue
|
534
|
+
res = (np.exp(dist.logcdf(x, y, method=method)) if log
|
535
|
+
else dist.cdf(x, y, method=method))
|
536
|
+
np.testing.assert_allclose(res, ref, atol=1e-14)
|
537
|
+
if log:
|
538
|
+
np.testing.assert_equal(res.dtype, (ref + 0j).dtype)
|
539
|
+
else:
|
540
|
+
np.testing.assert_equal(res.dtype, ref.dtype)
|
541
|
+
np.testing.assert_equal(res.shape, result_shape)
|
542
|
+
if result_shape == tuple():
|
543
|
+
assert np.isscalar(res)
|
544
|
+
|
545
|
+
|
546
|
+
def check_ccdf2(dist, log, x, y, result_shape, methods):
|
547
|
+
# Specialized test for 2-arg ccdf since the interface is a bit different
|
548
|
+
# from the other methods. Could be combined with check_cdf2 above, but
|
549
|
+
# writing it separately is simpler.
|
550
|
+
methods = methods.copy()
|
551
|
+
|
552
|
+
if dist._overrides(f'_{"log" if log else ""}ccdf2_formula'):
|
553
|
+
methods.add('formula')
|
554
|
+
|
555
|
+
ref = dist.cdf(x) + dist.ccdf(y)
|
556
|
+
np.testing.assert_equal(ref.shape, result_shape)
|
557
|
+
|
558
|
+
if result_shape == tuple():
|
559
|
+
assert np.isscalar(ref)
|
560
|
+
|
561
|
+
for method in methods:
|
562
|
+
message = ("Two argument cdf functions are currently only supported for "
|
563
|
+
"continuous distributions.")
|
564
|
+
if isinstance(dist, DiscreteDistribution):
|
565
|
+
with pytest.raises(NotImplementedError, match=message):
|
566
|
+
res = (np.exp(dist.logccdf(x, y, method=method)) if log
|
567
|
+
else dist.ccdf(x, y, method=method))
|
568
|
+
continue
|
569
|
+
res = (np.exp(dist.logccdf(x, y, method=method)) if log
|
570
|
+
else dist.ccdf(x, y, method=method))
|
571
|
+
np.testing.assert_allclose(res, ref, atol=1e-14)
|
572
|
+
np.testing.assert_equal(res.dtype, ref.dtype)
|
573
|
+
np.testing.assert_equal(res.shape, result_shape)
|
574
|
+
if result_shape == tuple():
|
575
|
+
assert np.isscalar(res)
|
576
|
+
|
577
|
+
|
578
|
+
def check_nans_and_edges(dist, fname, arg, res):
|
579
|
+
|
580
|
+
valid_parameters = get_valid_parameters(dist)
|
581
|
+
if fname in {'icdf', 'iccdf'}:
|
582
|
+
arg_domain = _RealInterval(endpoints=(0, 1), inclusive=(True, True))
|
583
|
+
elif fname in {'ilogcdf', 'ilogccdf'}:
|
584
|
+
arg_domain = _RealInterval(endpoints=(-inf, 0), inclusive=(True, True))
|
585
|
+
else:
|
586
|
+
arg_domain = dist._variable.domain
|
587
|
+
|
588
|
+
classified_args = classify_arg(dist, arg, arg_domain)
|
589
|
+
valid_parameters, *classified_args = np.broadcast_arrays(valid_parameters,
|
590
|
+
*classified_args)
|
591
|
+
valid_arg, endpoint_arg, outside_arg, nan_arg = classified_args
|
592
|
+
all_valid = valid_arg & valid_parameters
|
593
|
+
|
594
|
+
# Check NaN pattern and edge cases
|
595
|
+
assert_equal(res[~valid_parameters], np.nan)
|
596
|
+
assert_equal(res[nan_arg], np.nan)
|
597
|
+
|
598
|
+
a, b = dist.support()
|
599
|
+
a = np.broadcast_to(a, res.shape)
|
600
|
+
b = np.broadcast_to(b, res.shape)
|
601
|
+
|
602
|
+
outside_arg_minus = (outside_arg == -1) & valid_parameters
|
603
|
+
outside_arg_plus = (outside_arg == 1) & valid_parameters
|
604
|
+
endpoint_arg_minus = (endpoint_arg == -1) & valid_parameters
|
605
|
+
endpoint_arg_plus = (endpoint_arg == 1) & valid_parameters
|
606
|
+
|
607
|
+
is_discrete = isinstance(dist, DiscreteDistribution)
|
608
|
+
# Writing this independently of how the are set in the distribution
|
609
|
+
# infrastructure. That is very compact; this is very verbose.
|
610
|
+
if fname in {'logpdf'}:
|
611
|
+
assert_equal(res[outside_arg_minus], -np.inf)
|
612
|
+
assert_equal(res[outside_arg_plus], -np.inf)
|
613
|
+
ref = -np.inf if not is_discrete else np.inf
|
614
|
+
assert_equal(res[endpoint_arg_minus & ~valid_arg], ref)
|
615
|
+
assert_equal(res[endpoint_arg_plus & ~valid_arg], ref)
|
616
|
+
elif fname in {'pdf'}:
|
617
|
+
assert_equal(res[outside_arg_minus], 0)
|
618
|
+
assert_equal(res[outside_arg_plus], 0)
|
619
|
+
ref = 0 if not is_discrete else np.inf
|
620
|
+
assert_equal(res[endpoint_arg_minus & ~valid_arg], ref)
|
621
|
+
assert_equal(res[endpoint_arg_plus & ~valid_arg], ref)
|
622
|
+
elif fname in {'logcdf'} and not is_discrete:
|
623
|
+
assert_equal(res[outside_arg_minus], -inf)
|
624
|
+
assert_equal(res[outside_arg_plus], 0)
|
625
|
+
assert_equal(res[endpoint_arg_minus], -inf)
|
626
|
+
assert_equal(res[endpoint_arg_plus], 0)
|
627
|
+
elif fname in {'cdf'} and not is_discrete:
|
628
|
+
assert_equal(res[outside_arg_minus], 0)
|
629
|
+
assert_equal(res[outside_arg_plus], 1)
|
630
|
+
assert_equal(res[endpoint_arg_minus], 0)
|
631
|
+
assert_equal(res[endpoint_arg_plus], 1)
|
632
|
+
elif fname in {'logccdf'} and not is_discrete:
|
633
|
+
assert_equal(res[outside_arg_minus], 0)
|
634
|
+
assert_equal(res[outside_arg_plus], -inf)
|
635
|
+
assert_equal(res[endpoint_arg_minus], 0)
|
636
|
+
assert_equal(res[endpoint_arg_plus], -inf)
|
637
|
+
elif fname in {'ccdf'} and not is_discrete:
|
638
|
+
assert_equal(res[outside_arg_minus], 1)
|
639
|
+
assert_equal(res[outside_arg_plus], 0)
|
640
|
+
assert_equal(res[endpoint_arg_minus], 1)
|
641
|
+
assert_equal(res[endpoint_arg_plus], 0)
|
642
|
+
elif fname in {'ilogcdf', 'icdf'} and not is_discrete:
|
643
|
+
assert_equal(res[outside_arg == -1], np.nan)
|
644
|
+
assert_equal(res[outside_arg == 1], np.nan)
|
645
|
+
assert_equal(res[endpoint_arg == -1], a[endpoint_arg == -1])
|
646
|
+
assert_equal(res[endpoint_arg == 1], b[endpoint_arg == 1])
|
647
|
+
elif fname in {'ilogccdf', 'iccdf'} and not is_discrete:
|
648
|
+
assert_equal(res[outside_arg == -1], np.nan)
|
649
|
+
assert_equal(res[outside_arg == 1], np.nan)
|
650
|
+
assert_equal(res[endpoint_arg == -1], b[endpoint_arg == -1])
|
651
|
+
assert_equal(res[endpoint_arg == 1], a[endpoint_arg == 1])
|
652
|
+
|
653
|
+
exclude = {'logmean', 'mean', 'logskewness', 'skewness', 'support'}
|
654
|
+
if isinstance(dist, DiscreteDistribution):
|
655
|
+
exclude.update({'pdf', 'logpdf'})
|
656
|
+
|
657
|
+
if (
|
658
|
+
fname not in exclude
|
659
|
+
and not (isinstance(dist, Binomial)
|
660
|
+
and np.any((dist.n == 0) | (dist.p == 0) | (dist.p == 1)))):
|
661
|
+
# This can fail in degenerate case where Binomial distribution is a point
|
662
|
+
# distribution. Further on, we could factor out an is_degenerate function
|
663
|
+
# for the tests, or think about storing info about degeneracy in the
|
664
|
+
# instances.
|
665
|
+
assert np.isfinite(res[all_valid & (endpoint_arg == 0)]).all()
|
666
|
+
|
667
|
+
|
668
|
+
def check_moment_funcs(dist, result_shape):
|
669
|
+
# Check that all computation methods of all distribution functions agree
|
670
|
+
# with one another, effectively testing the correctness of the generic
|
671
|
+
# computation methods and confirming the consistency of specific
|
672
|
+
# distributions with their pdf/logpdf.
|
673
|
+
|
674
|
+
atol = 1e-9 # make this tighter (e.g. 1e-13) after fixing `draw`
|
675
|
+
|
676
|
+
def check(order, kind, method=None, ref=None, success=True):
|
677
|
+
if success:
|
678
|
+
res = dist.moment(order, kind, method=method)
|
679
|
+
assert_allclose(res, ref, atol=atol*10**order)
|
680
|
+
assert res.shape == ref.shape
|
681
|
+
else:
|
682
|
+
with pytest.raises(NotImplementedError):
|
683
|
+
dist.moment(order, kind, method=method)
|
684
|
+
|
685
|
+
def has_formula(order, kind):
|
686
|
+
formula_name = f'_moment_{kind}_formula'
|
687
|
+
overrides = dist._overrides(formula_name)
|
688
|
+
if not overrides:
|
689
|
+
return False
|
690
|
+
formula = getattr(dist, formula_name)
|
691
|
+
orders = getattr(formula, 'orders', set(range(6)))
|
692
|
+
return order in orders
|
693
|
+
|
694
|
+
dist.reset_cache()
|
695
|
+
|
696
|
+
### Check Raw Moments ###
|
697
|
+
for i in range(6):
|
698
|
+
check(i, 'raw', 'cache', success=False) # not cached yet
|
699
|
+
ref = dist.moment(i, 'raw', method='quadrature')
|
700
|
+
check_nans_and_edges(dist, 'moment', None, ref)
|
701
|
+
assert ref.shape == result_shape
|
702
|
+
check(i, 'raw','cache', ref, success=True) # cached now
|
703
|
+
check(i, 'raw', 'formula', ref, success=has_formula(i, 'raw'))
|
704
|
+
check(i, 'raw', 'general', ref, success=(i == 0))
|
705
|
+
if dist.__class__ == stats.Normal:
|
706
|
+
check(i, 'raw', 'quadrature_icdf', ref, success=True)
|
707
|
+
|
708
|
+
|
709
|
+
# Clearing caches to better check their behavior
|
710
|
+
dist.reset_cache()
|
711
|
+
|
712
|
+
# If we have central or standard moment formulas, or if there are
|
713
|
+
# values in their cache, we can use method='transform'
|
714
|
+
dist.moment(0, 'central') # build up the cache
|
715
|
+
dist.moment(1, 'central')
|
716
|
+
for i in range(2, 6):
|
717
|
+
ref = dist.moment(i, 'raw', method='quadrature')
|
718
|
+
check(i, 'raw', 'transform', ref,
|
719
|
+
success=has_formula(i, 'central') or has_formula(i, 'standardized'))
|
720
|
+
dist.moment(i, 'central') # build up the cache
|
721
|
+
check(i, 'raw', 'transform', ref)
|
722
|
+
|
723
|
+
dist.reset_cache()
|
724
|
+
|
725
|
+
### Check Central Moments ###
|
726
|
+
|
727
|
+
for i in range(6):
|
728
|
+
check(i, 'central', 'cache', success=False)
|
729
|
+
ref = dist.moment(i, 'central', method='quadrature')
|
730
|
+
assert ref.shape == result_shape
|
731
|
+
check(i, 'central', 'cache', ref, success=True)
|
732
|
+
check(i, 'central', 'formula', ref, success=has_formula(i, 'central'))
|
733
|
+
check(i, 'central', 'general', ref, success=i <= 1)
|
734
|
+
if dist.__class__ == stats.Normal:
|
735
|
+
check(i, 'central', 'quadrature_icdf', ref, success=True)
|
736
|
+
if not (dist.__class__ == stats.Uniform and i == 5):
|
737
|
+
# Quadrature is not super accurate for 5th central moment when the
|
738
|
+
# support is really big. Skip this one failing test. We need to come
|
739
|
+
# up with a better system of skipping individual failures w/ hypothesis.
|
740
|
+
check(i, 'central', 'transform', ref,
|
741
|
+
success=has_formula(i, 'raw') or (i <= 1))
|
742
|
+
if not has_formula(i, 'raw'):
|
743
|
+
dist.moment(i, 'raw')
|
744
|
+
check(i, 'central', 'transform', ref)
|
745
|
+
|
746
|
+
variance = dist.variance()
|
747
|
+
dist.reset_cache()
|
748
|
+
|
749
|
+
# If we have standard moment formulas, or if there are
|
750
|
+
# values in their cache, we can use method='normalize'
|
751
|
+
dist.moment(0, 'standardized') # build up the cache
|
752
|
+
dist.moment(1, 'standardized')
|
753
|
+
dist.moment(2, 'standardized')
|
754
|
+
for i in range(3, 6):
|
755
|
+
ref = dist.moment(i, 'central', method='quadrature')
|
756
|
+
check(i, 'central', 'normalize', ref,
|
757
|
+
success=has_formula(i, 'standardized') and not np.any(variance == 0))
|
758
|
+
dist.moment(i, 'standardized') # build up the cache
|
759
|
+
check(i, 'central', 'normalize', ref, success=not np.any(variance == 0))
|
760
|
+
|
761
|
+
### Check Standardized Moments ###
|
762
|
+
|
763
|
+
var = dist.moment(2, 'central', method='quadrature')
|
764
|
+
dist.reset_cache()
|
765
|
+
|
766
|
+
for i in range(6):
|
767
|
+
check(i, 'standardized', 'cache', success=False)
|
768
|
+
ref = dist.moment(i, 'central', method='quadrature') / var ** (i / 2)
|
769
|
+
assert ref.shape == result_shape
|
770
|
+
check(i, 'standardized', 'formula', ref,
|
771
|
+
success=has_formula(i, 'standardized'))
|
772
|
+
if not (
|
773
|
+
isinstance(dist, Binomial)
|
774
|
+
and np.any((dist.n == 0) | (dist.p == 0) | (dist.p == 1))
|
775
|
+
):
|
776
|
+
# This test will fail for degenerate case where binomial distribution
|
777
|
+
# is a point distribution.
|
778
|
+
check(i, 'standardized', 'general', ref, success=i <= 2)
|
779
|
+
check(i, 'standardized', 'normalize', ref)
|
780
|
+
|
781
|
+
if isinstance(dist, ShiftedScaledDistribution):
|
782
|
+
# logmoment is not fully fleshed out; no need to test
|
783
|
+
# ShiftedScaledDistribution here
|
784
|
+
return
|
785
|
+
|
786
|
+
# logmoment is not very accuate, and it's not public, so skip for now
|
787
|
+
# ### Check Against _logmoment ###
|
788
|
+
# logmean = dist._logmoment(1, logcenter=-np.inf)
|
789
|
+
# for i in range(6):
|
790
|
+
# ref = np.exp(dist._logmoment(i, logcenter=-np.inf))
|
791
|
+
# assert_allclose(dist.moment(i, 'raw'), ref, atol=atol*10**i)
|
792
|
+
#
|
793
|
+
# ref = np.exp(dist._logmoment(i, logcenter=logmean))
|
794
|
+
# assert_allclose(dist.moment(i, 'central'), ref, atol=atol*10**i)
|
795
|
+
#
|
796
|
+
# ref = np.exp(dist._logmoment(i, logcenter=logmean, standardized=True))
|
797
|
+
# assert_allclose(dist.moment(i, 'standardized'), ref, atol=atol*10**i)
|
798
|
+
|
799
|
+
|
800
|
+
@pytest.mark.parametrize('family', (Normal,))
|
801
|
+
@pytest.mark.parametrize('x_shape', [tuple(), (2, 3)])
|
802
|
+
@pytest.mark.parametrize('dist_shape', [tuple(), (4, 1)])
|
803
|
+
@pytest.mark.parametrize('fname', ['sample'])
|
804
|
+
@pytest.mark.parametrize('rng_type', [np.random.Generator, qmc.Halton, qmc.Sobol])
|
805
|
+
def test_sample_against_cdf(family, dist_shape, x_shape, fname, rng_type):
|
806
|
+
rng = np.random.default_rng(842582438235635)
|
807
|
+
num_parameters = family._num_parameters()
|
808
|
+
|
809
|
+
if dist_shape and num_parameters == 0:
|
810
|
+
pytest.skip("Distribution can't have a shape without parameters.")
|
811
|
+
|
812
|
+
dist = family._draw(dist_shape, rng)
|
813
|
+
|
814
|
+
n = 1024
|
815
|
+
sample_size = (n,) + x_shape
|
816
|
+
sample_array_shape = sample_size + dist_shape
|
817
|
+
|
818
|
+
if fname == 'sample':
|
819
|
+
sample_method = dist.sample
|
820
|
+
|
821
|
+
if rng_type != np.random.Generator:
|
822
|
+
rng = rng_type(d=1, seed=rng)
|
823
|
+
x = sample_method(sample_size, rng=rng)
|
824
|
+
assert x.shape == sample_array_shape
|
825
|
+
|
826
|
+
# probably should give `axis` argument to ks_1samp, review that separately
|
827
|
+
statistic = _kolmogorov_smirnov(dist, x, axis=0)
|
828
|
+
pvalue = kolmogn(x.shape[0], statistic, cdf=False)
|
829
|
+
p_threshold = 0.01
|
830
|
+
num_pvalues = pvalue.size
|
831
|
+
num_small_pvalues = np.sum(pvalue < p_threshold)
|
832
|
+
assert num_small_pvalues < p_threshold * num_pvalues
|
833
|
+
|
834
|
+
|
835
|
+
def get_valid_parameters(dist):
|
836
|
+
# Given a distribution, return a logical array that is true where all
|
837
|
+
# distribution parameters are within their respective domains. The code
|
838
|
+
# here is probably quite similar to that used to form the `_invalid`
|
839
|
+
# attribute of the distribution, but this was written about a week later
|
840
|
+
# without referring to that code, so it is a somewhat independent check.
|
841
|
+
|
842
|
+
# Get all parameter values and `_Parameter` objects
|
843
|
+
parameter_values = dist._parameters
|
844
|
+
parameters = {}
|
845
|
+
for parameterization in dist._parameterizations:
|
846
|
+
parameters.update(parameterization.parameters)
|
847
|
+
|
848
|
+
all_valid = np.ones(dist._shape, dtype=bool)
|
849
|
+
for name, value in parameter_values.items():
|
850
|
+
if name not in parameters: # cached value not part of parameterization
|
851
|
+
continue
|
852
|
+
parameter = parameters[name]
|
853
|
+
|
854
|
+
# Check that the numerical endpoints and inclusivity attribute
|
855
|
+
# agree with the `contains` method about which parameter values are
|
856
|
+
# within the domain.
|
857
|
+
a, b = parameter.domain.get_numerical_endpoints(
|
858
|
+
parameter_values=parameter_values)
|
859
|
+
a_included, b_included = parameter.domain.inclusive
|
860
|
+
valid = (a <= value) if a_included else a < value
|
861
|
+
valid &= (value <= b) if b_included else value < b
|
862
|
+
assert_equal(valid, parameter.domain.contains(
|
863
|
+
value, parameter_values=parameter_values))
|
864
|
+
|
865
|
+
# Form `all_valid` mask that is True where *all* parameters are valid
|
866
|
+
all_valid &= valid
|
867
|
+
|
868
|
+
# Check that the `all_valid` mask formed here is the complement of the
|
869
|
+
# `dist._invalid` mask stored by the infrastructure
|
870
|
+
assert_equal(~all_valid, dist._invalid)
|
871
|
+
|
872
|
+
return all_valid
|
873
|
+
|
874
|
+
def classify_arg(dist, arg, arg_domain):
|
875
|
+
if arg is None:
|
876
|
+
valid_args = np.ones(dist._shape, dtype=bool)
|
877
|
+
endpoint_args = np.zeros(dist._shape, dtype=bool)
|
878
|
+
outside_args = np.zeros(dist._shape, dtype=bool)
|
879
|
+
nan_args = np.zeros(dist._shape, dtype=bool)
|
880
|
+
return valid_args, endpoint_args, outside_args, nan_args
|
881
|
+
|
882
|
+
a, b = arg_domain.get_numerical_endpoints(
|
883
|
+
parameter_values=dist._parameters)
|
884
|
+
|
885
|
+
a, b, arg = np.broadcast_arrays(a, b, arg)
|
886
|
+
a_included, b_included = arg_domain.inclusive
|
887
|
+
|
888
|
+
inside = (a <= arg) if a_included else a < arg
|
889
|
+
inside &= (arg <= b) if b_included else arg < b
|
890
|
+
# TODO: add `supported` method and check here
|
891
|
+
on = np.zeros(a.shape, dtype=int)
|
892
|
+
on[a == arg] = -1
|
893
|
+
on[b == arg] = 1
|
894
|
+
outside = np.zeros(a.shape, dtype=int)
|
895
|
+
outside[(arg < a) if a_included else arg <= a] = -1
|
896
|
+
outside[(b < arg) if b_included else b <= arg] = 1
|
897
|
+
nan = np.isnan(arg)
|
898
|
+
|
899
|
+
return inside, on, outside, nan
|
900
|
+
|
901
|
+
|
902
|
+
def test_input_validation():
|
903
|
+
class Test(ContinuousDistribution):
|
904
|
+
_variable = _RealParameter('x', domain=_RealInterval())
|
905
|
+
|
906
|
+
message = ("The `Test` distribution family does not accept parameters, "
|
907
|
+
"but parameters `{'a'}` were provided.")
|
908
|
+
with pytest.raises(ValueError, match=message):
|
909
|
+
Test(a=1, )
|
910
|
+
|
911
|
+
message = "Attribute `tol` of `Test` must be a positive float, if specified."
|
912
|
+
with pytest.raises(ValueError, match=message):
|
913
|
+
Test(tol=np.asarray([]))
|
914
|
+
with pytest.raises(ValueError, match=message):
|
915
|
+
Test(tol=[1, 2, 3])
|
916
|
+
with pytest.raises(ValueError, match=message):
|
917
|
+
Test(tol=np.nan)
|
918
|
+
with pytest.raises(ValueError, match=message):
|
919
|
+
Test(tol=-1)
|
920
|
+
|
921
|
+
message = ("Argument `order` of `Test.moment` must be a "
|
922
|
+
"finite, positive integer.")
|
923
|
+
with pytest.raises(ValueError, match=message):
|
924
|
+
Test().moment(-1)
|
925
|
+
with pytest.raises(ValueError, match=message):
|
926
|
+
Test().moment(np.inf)
|
927
|
+
|
928
|
+
message = "Argument `kind` of `Test.moment` must be one of..."
|
929
|
+
with pytest.raises(ValueError, match=message):
|
930
|
+
Test().moment(2, kind='coconut')
|
931
|
+
|
932
|
+
class Test2(ContinuousDistribution):
|
933
|
+
_p1 = _RealParameter('c', domain=_RealInterval())
|
934
|
+
_p2 = _RealParameter('d', domain=_RealInterval())
|
935
|
+
_parameterizations = [_Parameterization(_p1, _p2)]
|
936
|
+
_variable = _RealParameter('x', domain=_RealInterval())
|
937
|
+
|
938
|
+
message = ("The provided parameters `{a}` do not match a supported "
|
939
|
+
"parameterization of the `Test2` distribution family.")
|
940
|
+
with pytest.raises(ValueError, match=message):
|
941
|
+
Test2(a=1)
|
942
|
+
|
943
|
+
message = ("The `Test2` distribution family requires parameters, but none "
|
944
|
+
"were provided.")
|
945
|
+
with pytest.raises(ValueError, match=message):
|
946
|
+
Test2()
|
947
|
+
|
948
|
+
message = ("The parameters `{c, d}` provided to the `Test2` "
|
949
|
+
"distribution family cannot be broadcast to the same shape.")
|
950
|
+
with pytest.raises(ValueError, match=message):
|
951
|
+
Test2(c=[1, 2], d=[1, 2, 3])
|
952
|
+
|
953
|
+
message = ("The argument provided to `Test2.pdf` cannot be be broadcast to "
|
954
|
+
"the same shape as the distribution parameters.")
|
955
|
+
with pytest.raises(ValueError, match=message):
|
956
|
+
dist = Test2(c=[1, 2, 3], d=[1, 2, 3])
|
957
|
+
dist.pdf([1, 2])
|
958
|
+
|
959
|
+
message = "Parameter `c` must be of real dtype."
|
960
|
+
with pytest.raises(TypeError, match=message):
|
961
|
+
Test2(c=[1, object()], d=[1, 2])
|
962
|
+
|
963
|
+
message = "Parameter `convention` of `Test2.kurtosis` must be one of..."
|
964
|
+
with pytest.raises(ValueError, match=message):
|
965
|
+
dist = Test2(c=[1, 2, 3], d=[1, 2, 3])
|
966
|
+
dist.kurtosis(convention='coconut')
|
967
|
+
|
968
|
+
|
969
|
+
def test_rng_deepcopy_pickle():
|
970
|
+
# test behavior of `rng` attribute and copy behavior
|
971
|
+
kwargs = dict(a=[-1, 2], b=10)
|
972
|
+
dist1 = Uniform(**kwargs)
|
973
|
+
dist2 = deepcopy(dist1)
|
974
|
+
dist3 = pickle.loads(pickle.dumps(dist1))
|
975
|
+
|
976
|
+
res1, res2, res3 = dist1.sample(), dist2.sample(), dist3.sample()
|
977
|
+
assert np.all(res2 != res1)
|
978
|
+
assert np.all(res3 != res1)
|
979
|
+
|
980
|
+
res1, res2, res3 = dist1.sample(rng=42), dist2.sample(rng=42), dist3.sample(rng=42)
|
981
|
+
assert np.all(res2 == res1)
|
982
|
+
assert np.all(res3 == res1)
|
983
|
+
|
984
|
+
|
985
|
+
class TestAttributes:
|
986
|
+
def test_cache_policy(self):
|
987
|
+
dist = StandardNormal(cache_policy="no_cache")
|
988
|
+
# make error message more appropriate
|
989
|
+
message = "`StandardNormal` does not provide an accurate implementation of the "
|
990
|
+
with pytest.raises(NotImplementedError, match=message):
|
991
|
+
dist.mean(method='cache')
|
992
|
+
mean = dist.mean()
|
993
|
+
with pytest.raises(NotImplementedError, match=message):
|
994
|
+
dist.mean(method='cache')
|
995
|
+
|
996
|
+
# add to enum
|
997
|
+
dist.cache_policy = None
|
998
|
+
with pytest.raises(NotImplementedError, match=message):
|
999
|
+
dist.mean(method='cache')
|
1000
|
+
mean = dist.mean() # method is 'formula' by default
|
1001
|
+
cached_mean = dist.mean(method='cache')
|
1002
|
+
assert_equal(cached_mean, mean)
|
1003
|
+
|
1004
|
+
# cache is overridden by latest evaluation
|
1005
|
+
quadrature_mean = dist.mean(method='quadrature')
|
1006
|
+
cached_mean = dist.mean(method='cache')
|
1007
|
+
assert_equal(cached_mean, quadrature_mean)
|
1008
|
+
assert not np.all(mean == quadrature_mean)
|
1009
|
+
|
1010
|
+
# We can turn the cache off, and it won't change, but the old cache is
|
1011
|
+
# still available
|
1012
|
+
dist.cache_policy = "no_cache"
|
1013
|
+
mean = dist.mean(method='formula')
|
1014
|
+
cached_mean = dist.mean(method='cache')
|
1015
|
+
assert_equal(cached_mean, quadrature_mean)
|
1016
|
+
assert not np.all(mean == quadrature_mean)
|
1017
|
+
|
1018
|
+
dist.reset_cache()
|
1019
|
+
with pytest.raises(NotImplementedError, match=message):
|
1020
|
+
dist.mean(method='cache')
|
1021
|
+
|
1022
|
+
message = "Attribute `cache_policy` of `StandardNormal`..."
|
1023
|
+
with pytest.raises(ValueError, match=message):
|
1024
|
+
dist.cache_policy = "invalid"
|
1025
|
+
|
1026
|
+
def test_tol(self):
|
1027
|
+
x = 3.
|
1028
|
+
X = stats.Normal()
|
1029
|
+
|
1030
|
+
message = "Attribute `tol` of `StandardNormal` must..."
|
1031
|
+
with pytest.raises(ValueError, match=message):
|
1032
|
+
X.tol = -1.
|
1033
|
+
with pytest.raises(ValueError, match=message):
|
1034
|
+
X.tol = (0.1,)
|
1035
|
+
with pytest.raises(ValueError, match=message):
|
1036
|
+
X.tol = np.nan
|
1037
|
+
|
1038
|
+
X1 = stats.Normal(tol=1e-1)
|
1039
|
+
X2 = stats.Normal(tol=1e-12)
|
1040
|
+
ref = X.cdf(x)
|
1041
|
+
res1 = X1.cdf(x, method='quadrature')
|
1042
|
+
res2 = X2.cdf(x, method='quadrature')
|
1043
|
+
assert_allclose(res1, ref, rtol=X1.tol)
|
1044
|
+
assert_allclose(res2, ref, rtol=X2.tol)
|
1045
|
+
assert abs(res1 - ref) > abs(res2 - ref)
|
1046
|
+
|
1047
|
+
p = 0.99
|
1048
|
+
X1.tol, X2.tol = X2.tol, X1.tol
|
1049
|
+
ref = X.icdf(p)
|
1050
|
+
res1 = X1.icdf(p, method='inversion')
|
1051
|
+
res2 = X2.icdf(p, method='inversion')
|
1052
|
+
assert_allclose(res1, ref, rtol=X1.tol)
|
1053
|
+
assert_allclose(res2, ref, rtol=X2.tol)
|
1054
|
+
assert abs(res2 - ref) > abs(res1 - ref)
|
1055
|
+
|
1056
|
+
def test_iv_policy(self):
|
1057
|
+
X = Uniform(a=0, b=1)
|
1058
|
+
assert X.pdf(2) == 0
|
1059
|
+
|
1060
|
+
X.validation_policy = 'skip_all'
|
1061
|
+
assert X.pdf(np.asarray(2.)) == 1
|
1062
|
+
|
1063
|
+
# Tests _set_invalid_nan
|
1064
|
+
a, b = np.asarray(1.), np.asarray(0.) # invalid parameters
|
1065
|
+
X = Uniform(a=a, b=b, validation_policy='skip_all')
|
1066
|
+
assert X.pdf(np.asarray(2.)) == -1
|
1067
|
+
|
1068
|
+
# Tests _set_invalid_nan_property
|
1069
|
+
class MyUniform(Uniform):
|
1070
|
+
def _entropy_formula(self, *args, **kwargs):
|
1071
|
+
return 'incorrect'
|
1072
|
+
|
1073
|
+
def _moment_raw_formula(self, order, **params):
|
1074
|
+
return 'incorrect'
|
1075
|
+
|
1076
|
+
X = MyUniform(a=a, b=b, validation_policy='skip_all')
|
1077
|
+
assert X.entropy() == 'incorrect'
|
1078
|
+
|
1079
|
+
# Tests _validate_order_kind
|
1080
|
+
assert X.moment(kind='raw', order=-1) == 'incorrect'
|
1081
|
+
|
1082
|
+
# Test input validation
|
1083
|
+
message = "Attribute `validation_policy` of `MyUniform`..."
|
1084
|
+
with pytest.raises(ValueError, match=message):
|
1085
|
+
X.validation_policy = "invalid"
|
1086
|
+
|
1087
|
+
def test_shapes(self):
|
1088
|
+
X = stats.Normal(mu=1, sigma=2)
|
1089
|
+
Y = stats.Normal(mu=[2], sigma=3)
|
1090
|
+
|
1091
|
+
# Check that attributes are available as expected
|
1092
|
+
assert X.mu == 1
|
1093
|
+
assert X.sigma == 2
|
1094
|
+
assert Y.mu[0] == 2
|
1095
|
+
assert Y.sigma[0] == 3
|
1096
|
+
|
1097
|
+
# Trying to set an attribute raises
|
1098
|
+
# message depends on Python version
|
1099
|
+
with pytest.raises(AttributeError):
|
1100
|
+
X.mu = 2
|
1101
|
+
|
1102
|
+
# Trying to mutate an attribute really mutates a copy
|
1103
|
+
Y.mu[0] = 10
|
1104
|
+
assert Y.mu[0] == 2
|
1105
|
+
|
1106
|
+
|
1107
|
+
class TestMakeDistribution:
|
1108
|
+
@pytest.mark.parametrize('i, distdata', enumerate(distcont + distdiscrete))
|
1109
|
+
def test_rv_generic(self, i, distdata):
|
1110
|
+
distname = distdata[0]
|
1111
|
+
|
1112
|
+
slow = {'argus', 'exponpow', 'exponweib', 'genexpon', 'gompertz', 'halfgennorm',
|
1113
|
+
'johnsonsb', 'kappa4', 'ksone', 'kstwo', 'kstwobign', 'norminvgauss',
|
1114
|
+
'powerlognorm', 'powernorm', 'recipinvgauss', 'studentized_range',
|
1115
|
+
'vonmises_line', # continuous
|
1116
|
+
'betanbinom', 'logser', 'skellam', 'zipf'} # discrete
|
1117
|
+
if not int(os.environ.get('SCIPY_XSLOW', '0')) and distname in slow:
|
1118
|
+
pytest.skip('Skipping as XSLOW')
|
1119
|
+
|
1120
|
+
if distname in { # skip these distributions
|
1121
|
+
'levy_stable', # private methods seem to require >= 1d args
|
1122
|
+
'vonmises', # circular distribution; shouldn't work
|
1123
|
+
'poisson_binom', # vector shape parameter
|
1124
|
+
'hypergeom', # distribution functions need interpolation
|
1125
|
+
'nchypergeom_fisher', # distribution functions need interpolation
|
1126
|
+
'nchypergeom_wallenius', # distribution functions need interpolation
|
1127
|
+
}:
|
1128
|
+
return
|
1129
|
+
|
1130
|
+
# skip single test, mostly due to slight disagreement
|
1131
|
+
custom_tolerances = {'ksone': 1e-5, 'kstwo': 1e-5} # discontinuous PDF
|
1132
|
+
skip_entropy = {'kstwobign', 'pearson3'} # tolerance issue
|
1133
|
+
skip_skewness = {'exponpow', 'ksone', 'nchypergeom_wallenius'} # tolerance
|
1134
|
+
skip_kurtosis = {'chi', 'exponpow', 'invgamma', # tolerance
|
1135
|
+
'johnsonsb', 'ksone', 'kstwo', # tolerance
|
1136
|
+
'nchypergeom_wallenius'} # tolerance
|
1137
|
+
skip_logccdf = {'arcsine', 'skewcauchy', 'trapezoid', 'triang'} # tolerance
|
1138
|
+
skip_raw = {2: {'alpha', 'foldcauchy', 'halfcauchy', 'levy', 'levy_l'},
|
1139
|
+
3: {'pareto'}, # stats.pareto is just wrong
|
1140
|
+
4: {'invgamma'}} # tolerance issue
|
1141
|
+
skip_standardized = {'exponpow', 'ksone'} # tolerances
|
1142
|
+
|
1143
|
+
dist = getattr(stats, distname)
|
1144
|
+
params = dict(zip(dist.shapes.split(', '), distdata[1])) if dist.shapes else {}
|
1145
|
+
rng = np.random.default_rng(7548723590230982)
|
1146
|
+
CustomDistribution = stats.make_distribution(dist)
|
1147
|
+
X = CustomDistribution(**params)
|
1148
|
+
Y = dist(**params)
|
1149
|
+
x = X.sample(shape=10, rng=rng)
|
1150
|
+
p = X.cdf(x)
|
1151
|
+
rtol = custom_tolerances.get(distname, 1e-7)
|
1152
|
+
atol = 1e-12
|
1153
|
+
|
1154
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
1155
|
+
m, v, s, k = Y.stats('mvsk')
|
1156
|
+
assert_allclose(X.support(), Y.support())
|
1157
|
+
if distname not in skip_entropy:
|
1158
|
+
assert_allclose(X.entropy(), Y.entropy(), rtol=rtol)
|
1159
|
+
if isinstance(Y, stats.rv_discrete):
|
1160
|
+
# some continuous distributions have trouble with `logentropy` because
|
1161
|
+
# it uses complex numbers
|
1162
|
+
assert_allclose(np.exp(X.logentropy()), Y.entropy(), rtol=rtol)
|
1163
|
+
assert_allclose(X.median(), Y.median(), rtol=rtol)
|
1164
|
+
assert_allclose(X.mean(), m, rtol=rtol, atol=atol)
|
1165
|
+
assert_allclose(X.variance(), v, rtol=rtol, atol=atol)
|
1166
|
+
if distname not in skip_skewness:
|
1167
|
+
assert_allclose(X.skewness(), s, rtol=rtol, atol=atol)
|
1168
|
+
if distname not in skip_kurtosis:
|
1169
|
+
assert_allclose(X.kurtosis(convention='excess'), k,
|
1170
|
+
rtol=rtol, atol=atol)
|
1171
|
+
if isinstance(dist, stats.rv_continuous):
|
1172
|
+
assert_allclose(X.logpdf(x), Y.logpdf(x), rtol=rtol)
|
1173
|
+
assert_allclose(X.pdf(x), Y.pdf(x), rtol=rtol)
|
1174
|
+
else:
|
1175
|
+
assert_allclose(X.logpmf(x), Y.logpmf(x), rtol=rtol)
|
1176
|
+
assert_allclose(X.pmf(x), Y.pmf(x), rtol=rtol)
|
1177
|
+
assert_allclose(X.logcdf(x), Y.logcdf(x), rtol=rtol)
|
1178
|
+
assert_allclose(X.cdf(x), Y.cdf(x), rtol=rtol)
|
1179
|
+
if distname not in skip_logccdf:
|
1180
|
+
assert_allclose(X.logccdf(x), Y.logsf(x), rtol=rtol)
|
1181
|
+
assert_allclose(X.ccdf(x), Y.sf(x), rtol=rtol)
|
1182
|
+
|
1183
|
+
# old infrastructure convention for ppf(p=0) and isf(p=1) is different than
|
1184
|
+
# new infrastructure. Adjust reference values accordingly.
|
1185
|
+
a, _ = Y.support()
|
1186
|
+
ref_ppf = Y.ppf(p)
|
1187
|
+
ref_ppf[p == 0] = a
|
1188
|
+
ref_isf = Y.isf(p)
|
1189
|
+
ref_isf[p == 1] = a
|
1190
|
+
|
1191
|
+
assert_allclose(X.icdf(p), ref_ppf, rtol=rtol)
|
1192
|
+
assert_allclose(X.iccdf(p), ref_isf, rtol=rtol)
|
1193
|
+
|
1194
|
+
for order in range(5):
|
1195
|
+
if distname not in skip_raw.get(order, {}):
|
1196
|
+
assert_allclose(X.moment(order, kind='raw'),
|
1197
|
+
Y.moment(order), rtol=rtol, atol=atol)
|
1198
|
+
for order in range(3, 4):
|
1199
|
+
if distname not in skip_standardized:
|
1200
|
+
assert_allclose(X.moment(order, kind='standardized'),
|
1201
|
+
Y.stats('mvsk'[order-1]), rtol=rtol, atol=atol)
|
1202
|
+
if isinstance(dist, stats.rv_continuous):
|
1203
|
+
# For discrete distributions, these won't agree at the far left end
|
1204
|
+
# of the support, and the new infrastructure is slow there (for now).
|
1205
|
+
seed = 845298245687345
|
1206
|
+
assert_allclose(X.sample(shape=10, rng=seed),
|
1207
|
+
Y.rvs(size=10,
|
1208
|
+
random_state=np.random.default_rng(seed)),
|
1209
|
+
rtol=rtol)
|
1210
|
+
|
1211
|
+
def test_custom(self):
|
1212
|
+
rng = np.random.default_rng(7548723590230982)
|
1213
|
+
|
1214
|
+
class MyLogUniform:
|
1215
|
+
@property
|
1216
|
+
def __make_distribution_version__(self):
|
1217
|
+
return "1.16.0"
|
1218
|
+
|
1219
|
+
@property
|
1220
|
+
def parameters(self):
|
1221
|
+
return {'a': {'endpoints': (0, np.inf), 'inclusive': (False, False)},
|
1222
|
+
'b': {'endpoints': ('a', np.inf), 'inclusive': (False, False)}}
|
1223
|
+
|
1224
|
+
@property
|
1225
|
+
def support(self):
|
1226
|
+
return {'endpoints': ('a', 'b')}
|
1227
|
+
|
1228
|
+
def pdf(self, x, a, b):
|
1229
|
+
return 1 / (x * (np.log(b) - np.log(a)))
|
1230
|
+
|
1231
|
+
def sample(self, shape, *, a, b, rng=None):
|
1232
|
+
p = rng.uniform(size=shape)
|
1233
|
+
return np.exp(np.log(a) + p * (np.log(b) - np.log(a)))
|
1234
|
+
|
1235
|
+
def moment(self, order, kind='raw', *, a, b):
|
1236
|
+
if order == 1 and kind == 'raw':
|
1237
|
+
# quadrature is perfectly accurate here; add 1e-10 error so we
|
1238
|
+
# can tell the difference between the two
|
1239
|
+
return (b - a) / np.log(b/a) + 1e-10
|
1240
|
+
|
1241
|
+
LogUniform = stats.make_distribution(MyLogUniform())
|
1242
|
+
|
1243
|
+
X = LogUniform(a=np.exp(1), b=np.exp(3))
|
1244
|
+
Y = stats.exp(Uniform(a=1., b=3.))
|
1245
|
+
x = X.sample(shape=10, rng=rng)
|
1246
|
+
p = X.cdf(x)
|
1247
|
+
|
1248
|
+
assert_allclose(X.support(), Y.support())
|
1249
|
+
assert_allclose(X.entropy(), Y.entropy())
|
1250
|
+
assert_allclose(X.median(), Y.median())
|
1251
|
+
assert_allclose(X.logpdf(x), Y.logpdf(x))
|
1252
|
+
assert_allclose(X.pdf(x), Y.pdf(x))
|
1253
|
+
assert_allclose(X.logcdf(x), Y.logcdf(x))
|
1254
|
+
assert_allclose(X.cdf(x), Y.cdf(x))
|
1255
|
+
assert_allclose(X.logccdf(x), Y.logccdf(x))
|
1256
|
+
assert_allclose(X.ccdf(x), Y.ccdf(x))
|
1257
|
+
assert_allclose(X.icdf(p), Y.icdf(p))
|
1258
|
+
assert_allclose(X.iccdf(p), Y.iccdf(p))
|
1259
|
+
for kind in ['raw', 'central', 'standardized']:
|
1260
|
+
for order in range(5):
|
1261
|
+
assert_allclose(X.moment(order, kind=kind),
|
1262
|
+
Y.moment(order, kind=kind))
|
1263
|
+
|
1264
|
+
# Confirm that the `sample` and `moment` methods are overriden as expected
|
1265
|
+
sample_formula = X.sample(shape=10, rng=0, method='formula')
|
1266
|
+
sample_inverse = X.sample(shape=10, rng=0, method='inverse_transform')
|
1267
|
+
assert_allclose(sample_formula, sample_inverse)
|
1268
|
+
assert not np.all(sample_formula == sample_inverse)
|
1269
|
+
|
1270
|
+
assert_allclose(X.mean(method='formula'), X.mean(method='quadrature'))
|
1271
|
+
assert not X.mean(method='formula') == X.mean(method='quadrature')
|
1272
|
+
|
1273
|
+
# pdf and cdf formulas below can warn on boundary of support in some cases.
|
1274
|
+
# See https://github.com/scipy/scipy/pull/22560#discussion_r1962763840.
|
1275
|
+
@pytest.mark.slow
|
1276
|
+
@pytest.mark.filterwarnings("ignore::RuntimeWarning")
|
1277
|
+
@pytest.mark.parametrize("c", [-1, 0, 1, np.asarray([-2.1, -1., 0., 1., 2.1])])
|
1278
|
+
def test_custom_variable_support(self, c):
|
1279
|
+
rng = np.random.default_rng(7548723590230982)
|
1280
|
+
|
1281
|
+
class MyGenExtreme:
|
1282
|
+
@property
|
1283
|
+
def __make_distribution_version__(self):
|
1284
|
+
return "1.16.0"
|
1285
|
+
|
1286
|
+
@property
|
1287
|
+
def parameters(self):
|
1288
|
+
return {
|
1289
|
+
'c': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
|
1290
|
+
'mu': {'endpoints': (-np.inf, np.inf), 'inclusive': (False, False)},
|
1291
|
+
'sigma': {'endpoints': (0, np.inf), 'inclusive': (False, False)}
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
@property
|
1295
|
+
def support(self):
|
1296
|
+
def left(*, c, mu, sigma):
|
1297
|
+
c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
|
1298
|
+
result = np.empty_like(c)
|
1299
|
+
result[c >= 0] = -np.inf
|
1300
|
+
result[c < 0] = mu[c < 0] + sigma[c < 0] / c[c < 0]
|
1301
|
+
return result[()]
|
1302
|
+
|
1303
|
+
def right(*, c, mu, sigma):
|
1304
|
+
c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
|
1305
|
+
result = np.empty_like(c)
|
1306
|
+
result[c <= 0] = np.inf
|
1307
|
+
result[c > 0] = mu[c > 0] + sigma[c > 0] / c[c > 0]
|
1308
|
+
return result[()]
|
1309
|
+
|
1310
|
+
return {"endpoints": (left, right), "inclusive": (False, False)}
|
1311
|
+
|
1312
|
+
def pdf(self, x, *, c, mu, sigma):
|
1313
|
+
x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
|
1314
|
+
t = np.empty_like(x)
|
1315
|
+
mask = (c == 0)
|
1316
|
+
t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
|
1317
|
+
t[~mask] = (
|
1318
|
+
1 - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
|
1319
|
+
)**(1/c[~mask])
|
1320
|
+
result = 1/sigma * t**(1 - c)*np.exp(-t)
|
1321
|
+
return result[()]
|
1322
|
+
|
1323
|
+
def cdf(self, x, *, c, mu, sigma):
|
1324
|
+
x, c, mu, sigma = np.broadcast_arrays(x, c, mu, sigma)
|
1325
|
+
t = np.empty_like(x)
|
1326
|
+
mask = (c == 0)
|
1327
|
+
t[mask] = np.exp(-(x[mask] - mu[mask])/sigma[mask])
|
1328
|
+
t[~mask] = (
|
1329
|
+
1 - c[~mask]*(x[~mask] - mu[~mask])/sigma[~mask]
|
1330
|
+
)**(1/c[~mask])
|
1331
|
+
return np.exp(-t)[()]
|
1332
|
+
|
1333
|
+
GenExtreme1 = stats.make_distribution(MyGenExtreme())
|
1334
|
+
GenExtreme2 = stats.make_distribution(stats.genextreme)
|
1335
|
+
|
1336
|
+
X1 = GenExtreme1(c=c, mu=0, sigma=1)
|
1337
|
+
X2 = GenExtreme2(c=c)
|
1338
|
+
|
1339
|
+
x = X1.sample(shape=10, rng=rng)
|
1340
|
+
p = X1.cdf(x)
|
1341
|
+
|
1342
|
+
assert_allclose(X1.support(), X2.support())
|
1343
|
+
assert_allclose(X1.entropy(), X2.entropy(), rtol=5e-6)
|
1344
|
+
assert_allclose(X1.median(), X2.median())
|
1345
|
+
assert_allclose(X1.logpdf(x), X2.logpdf(x))
|
1346
|
+
assert_allclose(X1.pdf(x), X2.pdf(x))
|
1347
|
+
assert_allclose(X1.logcdf(x), X2.logcdf(x))
|
1348
|
+
assert_allclose(X1.cdf(x), X2.cdf(x))
|
1349
|
+
assert_allclose(X1.logccdf(x), X2.logccdf(x))
|
1350
|
+
assert_allclose(X1.ccdf(x), X2.ccdf(x))
|
1351
|
+
assert_allclose(X1.icdf(p), X2.icdf(p))
|
1352
|
+
assert_allclose(X1.iccdf(p), X2.iccdf(p))
|
1353
|
+
|
1354
|
+
@pytest.mark.slow
|
1355
|
+
@pytest.mark.parametrize("a", [0.5, np.asarray([0.5, 1.0, 2.0, 4.0, 8.0])])
|
1356
|
+
@pytest.mark.parametrize("b", [0.5, np.asarray([0.5, 1.0, 2.0, 4.0, 8.0])])
|
1357
|
+
def test_custom_multiple_parameterizations(self, a, b):
|
1358
|
+
rng = np.random.default_rng(7548723590230982)
|
1359
|
+
class MyBeta:
|
1360
|
+
@property
|
1361
|
+
def __make_distribution_version__(self):
|
1362
|
+
return "1.16.0"
|
1363
|
+
|
1364
|
+
@property
|
1365
|
+
def parameters(self):
|
1366
|
+
return (
|
1367
|
+
{"a": (0, np.inf), "b": (0, np.inf)},
|
1368
|
+
{"mu": (0, 1), "nu": (0, np.inf)},
|
1369
|
+
)
|
1370
|
+
|
1371
|
+
def process_parameters(self, a=None, b=None, mu=None, nu=None):
|
1372
|
+
if a is not None and b is not None and mu is None and nu is None:
|
1373
|
+
nu = a + b
|
1374
|
+
mu = a / nu
|
1375
|
+
else:
|
1376
|
+
a = mu * nu
|
1377
|
+
b = nu - a
|
1378
|
+
return {"a": a, "b": b, "mu": mu, "nu": nu}
|
1379
|
+
|
1380
|
+
@property
|
1381
|
+
def support(self):
|
1382
|
+
return {'endpoints': (0, 1)}
|
1383
|
+
|
1384
|
+
def pdf(self, x, a, b, mu, nu):
|
1385
|
+
return special._ufuncs._beta_pdf(x, a, b)
|
1386
|
+
|
1387
|
+
def cdf(self, x, a, b, mu, nu):
|
1388
|
+
return special.betainc(a, b, x)
|
1389
|
+
|
1390
|
+
Beta = stats.make_distribution(stats.beta)
|
1391
|
+
MyBeta = stats.make_distribution(MyBeta())
|
1392
|
+
|
1393
|
+
mu = a / (a + b)
|
1394
|
+
nu = a + b
|
1395
|
+
|
1396
|
+
X = MyBeta(a=a, b=b)
|
1397
|
+
Y = MyBeta(mu=mu, nu=nu)
|
1398
|
+
Z = Beta(a=a, b=b)
|
1399
|
+
|
1400
|
+
x = Z.sample(shape=10, rng=rng)
|
1401
|
+
p = Z.cdf(x)
|
1402
|
+
|
1403
|
+
assert_allclose(X.support(), Z.support())
|
1404
|
+
assert_allclose(X.median(), Z.median())
|
1405
|
+
assert_allclose(X.pdf(x), Z.pdf(x))
|
1406
|
+
assert_allclose(X.cdf(x), Z.cdf(x))
|
1407
|
+
assert_allclose(X.ccdf(x), Z.ccdf(x))
|
1408
|
+
assert_allclose(X.icdf(p), Z.icdf(p))
|
1409
|
+
assert_allclose(X.iccdf(p), Z.iccdf(p))
|
1410
|
+
|
1411
|
+
assert_allclose(Y.support(), Z.support())
|
1412
|
+
assert_allclose(Y.median(), Z.median())
|
1413
|
+
assert_allclose(Y.pdf(x), Z.pdf(x))
|
1414
|
+
assert_allclose(Y.cdf(x), Z.cdf(x))
|
1415
|
+
assert_allclose(Y.ccdf(x), Z.ccdf(x))
|
1416
|
+
assert_allclose(Y.icdf(p), Z.icdf(p))
|
1417
|
+
assert_allclose(Y.iccdf(p), Z.iccdf(p))
|
1418
|
+
|
1419
|
+
def test_input_validation(self):
|
1420
|
+
message = '`levy_stable` is not supported.'
|
1421
|
+
with pytest.raises(NotImplementedError, match=message):
|
1422
|
+
stats.make_distribution(stats.levy_stable)
|
1423
|
+
|
1424
|
+
message = '`vonmises` is not supported.'
|
1425
|
+
with pytest.raises(NotImplementedError, match=message):
|
1426
|
+
stats.make_distribution(stats.vonmises)
|
1427
|
+
|
1428
|
+
message = "The argument must be an instance of..."
|
1429
|
+
with pytest.raises(ValueError, match=message):
|
1430
|
+
stats.make_distribution(object())
|
1431
|
+
|
1432
|
+
def test_repr_str_docs(self):
|
1433
|
+
from scipy.stats._distribution_infrastructure import _distribution_names
|
1434
|
+
for dist in _distribution_names.keys():
|
1435
|
+
assert hasattr(stats, dist)
|
1436
|
+
|
1437
|
+
dist = stats.make_distribution(stats.gamma)
|
1438
|
+
assert str(dist(a=2)) == "Gamma(a=2.0)"
|
1439
|
+
if np.__version__ >= "2":
|
1440
|
+
assert repr(dist(a=2)) == "Gamma(a=np.float64(2.0))"
|
1441
|
+
assert 'Gamma' in dist.__doc__
|
1442
|
+
|
1443
|
+
dist = stats.make_distribution(stats.halfgennorm)
|
1444
|
+
assert str(dist(beta=2)) == "HalfGeneralizedNormal(beta=2.0)"
|
1445
|
+
if np.__version__ >= "2":
|
1446
|
+
assert repr(dist(beta=2)) == "HalfGeneralizedNormal(beta=np.float64(2.0))"
|
1447
|
+
assert 'HalfGeneralizedNormal' in dist.__doc__
|
1448
|
+
|
1449
|
+
|
1450
|
+
class TestTransforms:
|
1451
|
+
|
1452
|
+
def test_ContinuousDistribution_only(self):
|
1453
|
+
X = stats.Binomial(n=10, p=0.5)
|
1454
|
+
# This is applied at the top level TransformedDistribution,
|
1455
|
+
# so testing one subclass is enough
|
1456
|
+
message = "Transformations are currently only supported for continuous RVs."
|
1457
|
+
with pytest.raises(NotImplementedError, match=message):
|
1458
|
+
stats.exp(X)
|
1459
|
+
|
1460
|
+
def test_truncate(self):
|
1461
|
+
rng = np.random.default_rng(81345982345826)
|
1462
|
+
lb = rng.random((3, 1))
|
1463
|
+
ub = rng.random((3, 1))
|
1464
|
+
lb, ub = np.minimum(lb, ub), np.maximum(lb, ub)
|
1465
|
+
|
1466
|
+
Y = stats.truncate(Normal(), lb=lb, ub=ub)
|
1467
|
+
Y0 = stats.truncnorm(lb, ub)
|
1468
|
+
|
1469
|
+
y = Y0.rvs((3, 10), random_state=rng)
|
1470
|
+
p = Y0.cdf(y)
|
1471
|
+
|
1472
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j))
|
1473
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1474
|
+
assert_allclose(Y.median(), Y0.ppf(0.5))
|
1475
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1476
|
+
assert_allclose(Y.variance(), Y0.var())
|
1477
|
+
assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
|
1478
|
+
assert_allclose(Y.skewness(), Y0.stats('s'))
|
1479
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
|
1480
|
+
assert_allclose(Y.support(), Y0.support())
|
1481
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1482
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1483
|
+
assert_allclose(Y.ccdf(y), Y0.sf(y))
|
1484
|
+
assert_allclose(Y.icdf(p), Y0.ppf(p))
|
1485
|
+
assert_allclose(Y.iccdf(p), Y0.isf(p))
|
1486
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1487
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1488
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1489
|
+
assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
|
1490
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1491
|
+
sample = Y.sample(10)
|
1492
|
+
assert np.all((sample > lb) & (sample < ub))
|
1493
|
+
|
1494
|
+
@pytest.mark.fail_slow(10)
|
1495
|
+
@given(data=strategies.data(), seed=strategies.integers(min_value=0))
|
1496
|
+
@pytest.mark.thread_unsafe
|
1497
|
+
def test_loc_scale(self, data, seed):
|
1498
|
+
# Need tests with negative scale
|
1499
|
+
rng = np.random.default_rng(seed)
|
1500
|
+
|
1501
|
+
class TransformedNormal(ShiftedScaledDistribution):
|
1502
|
+
def __init__(self, *args, **kwargs):
|
1503
|
+
super().__init__(StandardNormal(), *args, **kwargs)
|
1504
|
+
|
1505
|
+
tmp = draw_distribution_from_family(
|
1506
|
+
TransformedNormal, data, rng, proportions=(1, 0, 0, 0), min_side=1)
|
1507
|
+
dist, x, y, p, logp, result_shape, x_result_shape, xy_result_shape = tmp
|
1508
|
+
|
1509
|
+
loc = dist.loc
|
1510
|
+
scale = dist.scale
|
1511
|
+
dist0 = StandardNormal()
|
1512
|
+
dist_ref = stats.norm(loc=loc, scale=scale)
|
1513
|
+
|
1514
|
+
x0 = (x - loc) / scale
|
1515
|
+
y0 = (y - loc) / scale
|
1516
|
+
|
1517
|
+
a, b = dist.support()
|
1518
|
+
a0, b0 = dist0.support()
|
1519
|
+
assert_allclose(a, a0 + loc)
|
1520
|
+
assert_allclose(b, b0 + loc)
|
1521
|
+
|
1522
|
+
with np.errstate(invalid='ignore', divide='ignore'):
|
1523
|
+
assert_allclose(np.exp(dist.logentropy()), dist.entropy())
|
1524
|
+
assert_allclose(dist.entropy(), dist_ref.entropy())
|
1525
|
+
assert_allclose(dist.median(), dist0.median() + loc)
|
1526
|
+
assert_allclose(dist.mode(), dist0.mode() + loc)
|
1527
|
+
assert_allclose(dist.mean(), dist0.mean() + loc)
|
1528
|
+
assert_allclose(dist.variance(), dist0.variance() * scale**2)
|
1529
|
+
assert_allclose(dist.standard_deviation(), dist.variance()**0.5)
|
1530
|
+
assert_allclose(dist.skewness(), dist0.skewness() * np.sign(scale))
|
1531
|
+
assert_allclose(dist.kurtosis(), dist0.kurtosis())
|
1532
|
+
assert_allclose(dist.logpdf(x), dist0.logpdf(x0) - np.log(scale))
|
1533
|
+
assert_allclose(dist.pdf(x), dist0.pdf(x0) / scale)
|
1534
|
+
assert_allclose(dist.logcdf(x), dist0.logcdf(x0))
|
1535
|
+
assert_allclose(dist.cdf(x), dist0.cdf(x0))
|
1536
|
+
assert_allclose(dist.logccdf(x), dist0.logccdf(x0))
|
1537
|
+
assert_allclose(dist.ccdf(x), dist0.ccdf(x0))
|
1538
|
+
assert_allclose(dist.logcdf(x, y), dist0.logcdf(x0, y0))
|
1539
|
+
assert_allclose(dist.cdf(x, y), dist0.cdf(x0, y0))
|
1540
|
+
assert_allclose(dist.logccdf(x, y), dist0.logccdf(x0, y0))
|
1541
|
+
assert_allclose(dist.ccdf(x, y), dist0.ccdf(x0, y0))
|
1542
|
+
assert_allclose(dist.ilogcdf(logp), dist0.ilogcdf(logp)*scale + loc)
|
1543
|
+
assert_allclose(dist.icdf(p), dist0.icdf(p)*scale + loc)
|
1544
|
+
assert_allclose(dist.ilogccdf(logp), dist0.ilogccdf(logp)*scale + loc)
|
1545
|
+
assert_allclose(dist.iccdf(p), dist0.iccdf(p)*scale + loc)
|
1546
|
+
for i in range(1, 5):
|
1547
|
+
assert_allclose(dist.moment(i, 'raw'), dist_ref.moment(i))
|
1548
|
+
assert_allclose(dist.moment(i, 'central'),
|
1549
|
+
dist0.moment(i, 'central') * scale**i)
|
1550
|
+
assert_allclose(dist.moment(i, 'standardized'),
|
1551
|
+
dist0.moment(i, 'standardized') * np.sign(scale)**i)
|
1552
|
+
|
1553
|
+
# Transform back to the original distribution using all arithmetic
|
1554
|
+
# operations; check that it behaves as expected.
|
1555
|
+
dist = (dist - 2*loc) + loc
|
1556
|
+
dist = dist/scale**2 * scale
|
1557
|
+
z = np.zeros(dist._shape) # compact broadcasting
|
1558
|
+
|
1559
|
+
a, b = dist.support()
|
1560
|
+
a0, b0 = dist0.support()
|
1561
|
+
assert_allclose(a, a0 + z)
|
1562
|
+
assert_allclose(b, b0 + z)
|
1563
|
+
|
1564
|
+
with np.errstate(invalid='ignore', divide='ignore'):
|
1565
|
+
assert_allclose(dist.logentropy(), dist0.logentropy() + z)
|
1566
|
+
assert_allclose(dist.entropy(), dist0.entropy() + z)
|
1567
|
+
assert_allclose(dist.median(), dist0.median() + z)
|
1568
|
+
assert_allclose(dist.mode(), dist0.mode() + z)
|
1569
|
+
assert_allclose(dist.mean(), dist0.mean() + z)
|
1570
|
+
assert_allclose(dist.variance(), dist0.variance() + z)
|
1571
|
+
assert_allclose(dist.standard_deviation(), dist0.standard_deviation() + z)
|
1572
|
+
assert_allclose(dist.skewness(), dist0.skewness() + z)
|
1573
|
+
assert_allclose(dist.kurtosis(), dist0.kurtosis() + z)
|
1574
|
+
assert_allclose(dist.logpdf(x), dist0.logpdf(x)+z)
|
1575
|
+
assert_allclose(dist.pdf(x), dist0.pdf(x) + z)
|
1576
|
+
assert_allclose(dist.logcdf(x), dist0.logcdf(x) + z)
|
1577
|
+
assert_allclose(dist.cdf(x), dist0.cdf(x) + z)
|
1578
|
+
assert_allclose(dist.logccdf(x), dist0.logccdf(x) + z)
|
1579
|
+
assert_allclose(dist.ccdf(x), dist0.ccdf(x) + z)
|
1580
|
+
assert_allclose(dist.ilogcdf(logp), dist0.ilogcdf(logp) + z)
|
1581
|
+
assert_allclose(dist.icdf(p), dist0.icdf(p) + z)
|
1582
|
+
assert_allclose(dist.ilogccdf(logp), dist0.ilogccdf(logp) + z)
|
1583
|
+
assert_allclose(dist.iccdf(p), dist0.iccdf(p) + z)
|
1584
|
+
for i in range(1, 5):
|
1585
|
+
assert_allclose(dist.moment(i, 'raw'), dist0.moment(i, 'raw'))
|
1586
|
+
assert_allclose(dist.moment(i, 'central'), dist0.moment(i, 'central'))
|
1587
|
+
assert_allclose(dist.moment(i, 'standardized'),
|
1588
|
+
dist0.moment(i, 'standardized'))
|
1589
|
+
|
1590
|
+
# These are tough to compare because of the way the shape works
|
1591
|
+
# rng = np.random.default_rng(seed)
|
1592
|
+
# rng0 = np.random.default_rng(seed)
|
1593
|
+
# assert_allclose(dist.sample(x_result_shape, rng=rng),
|
1594
|
+
# dist0.sample(x_result_shape, rng=rng0) * scale + loc)
|
1595
|
+
# Should also try to test fit, plot?
|
1596
|
+
|
1597
|
+
@pytest.mark.fail_slow(5)
|
1598
|
+
@pytest.mark.parametrize('exp_pow', ['exp', 'pow'])
|
1599
|
+
def test_exp_pow(self, exp_pow):
|
1600
|
+
rng = np.random.default_rng(81345982345826)
|
1601
|
+
mu = rng.random((3, 1))
|
1602
|
+
sigma = rng.random((3, 1))
|
1603
|
+
|
1604
|
+
X = Normal()*sigma + mu
|
1605
|
+
if exp_pow == 'exp':
|
1606
|
+
Y = stats.exp(X)
|
1607
|
+
else:
|
1608
|
+
Y = np.e ** X
|
1609
|
+
Y0 = stats.lognorm(sigma, scale=np.exp(mu))
|
1610
|
+
|
1611
|
+
y = Y0.rvs((3, 10), random_state=rng)
|
1612
|
+
p = Y0.cdf(y)
|
1613
|
+
|
1614
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
|
1615
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1616
|
+
assert_allclose(Y.median(), Y0.ppf(0.5))
|
1617
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1618
|
+
assert_allclose(Y.variance(), Y0.var())
|
1619
|
+
assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
|
1620
|
+
assert_allclose(Y.skewness(), Y0.stats('s'))
|
1621
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
|
1622
|
+
assert_allclose(Y.support(), Y0.support())
|
1623
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1624
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1625
|
+
assert_allclose(Y.ccdf(y), Y0.sf(y))
|
1626
|
+
assert_allclose(Y.icdf(p), Y0.ppf(p))
|
1627
|
+
assert_allclose(Y.iccdf(p), Y0.isf(p))
|
1628
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1629
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1630
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1631
|
+
assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
|
1632
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1633
|
+
seed = 3984593485
|
1634
|
+
assert_allclose(Y.sample(rng=seed), np.exp(X.sample(rng=seed)))
|
1635
|
+
|
1636
|
+
|
1637
|
+
@pytest.mark.fail_slow(10)
|
1638
|
+
@pytest.mark.parametrize('scale', [1, 2, -1])
|
1639
|
+
@pytest.mark.xfail_on_32bit("`scale=-1` fails on 32-bit; needs investigation")
|
1640
|
+
def test_reciprocal(self, scale):
|
1641
|
+
rng = np.random.default_rng(81345982345826)
|
1642
|
+
a = rng.random((3, 1))
|
1643
|
+
|
1644
|
+
# Separate sign from scale. It's easy to scale the resulting
|
1645
|
+
# RV with negative scale; we want to test the ability to divide
|
1646
|
+
# by a RV with negative support
|
1647
|
+
sign, scale = np.sign(scale), abs(scale)
|
1648
|
+
|
1649
|
+
# Reference distribution
|
1650
|
+
InvGamma = stats.make_distribution(stats.invgamma)
|
1651
|
+
Y0 = sign * scale * InvGamma(a=a)
|
1652
|
+
|
1653
|
+
# Test distribution
|
1654
|
+
X = _Gamma(a=a) if sign > 0 else -_Gamma(a=a)
|
1655
|
+
Y = scale / X
|
1656
|
+
|
1657
|
+
y = Y0.sample(shape=(3, 10), rng=rng)
|
1658
|
+
p = Y0.cdf(y)
|
1659
|
+
logp = np.log(p)
|
1660
|
+
|
1661
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
|
1662
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1663
|
+
assert_allclose(Y.median(), Y0.median())
|
1664
|
+
# moments are not finite
|
1665
|
+
assert_allclose(Y.support(), Y0.support())
|
1666
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1667
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1668
|
+
assert_allclose(Y.ccdf(y), Y0.ccdf(y))
|
1669
|
+
assert_allclose(Y.icdf(p), Y0.icdf(p))
|
1670
|
+
assert_allclose(Y.iccdf(p), Y0.iccdf(p))
|
1671
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1672
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1673
|
+
assert_allclose(Y.logccdf(y), Y0.logccdf(y))
|
1674
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
1675
|
+
assert_allclose(Y.ilogcdf(logp), Y0.ilogcdf(logp))
|
1676
|
+
assert_allclose(Y.ilogccdf(logp), Y0.ilogccdf(logp))
|
1677
|
+
seed = 3984593485
|
1678
|
+
assert_allclose(Y.sample(rng=seed), scale/(X.sample(rng=seed)))
|
1679
|
+
|
1680
|
+
@pytest.mark.fail_slow(5)
|
1681
|
+
def test_log(self):
|
1682
|
+
rng = np.random.default_rng(81345982345826)
|
1683
|
+
a = rng.random((3, 1))
|
1684
|
+
|
1685
|
+
X = _Gamma(a=a)
|
1686
|
+
Y0 = stats.loggamma(a)
|
1687
|
+
Y = stats.log(X)
|
1688
|
+
y = Y0.rvs((3, 10), random_state=rng)
|
1689
|
+
p = Y0.cdf(y)
|
1690
|
+
|
1691
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy()))
|
1692
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1693
|
+
assert_allclose(Y.median(), Y0.ppf(0.5))
|
1694
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1695
|
+
assert_allclose(Y.variance(), Y0.var())
|
1696
|
+
assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
|
1697
|
+
assert_allclose(Y.skewness(), Y0.stats('s'))
|
1698
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
|
1699
|
+
assert_allclose(Y.support(), Y0.support())
|
1700
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1701
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1702
|
+
assert_allclose(Y.ccdf(y), Y0.sf(y))
|
1703
|
+
assert_allclose(Y.icdf(p), Y0.ppf(p))
|
1704
|
+
assert_allclose(Y.iccdf(p), Y0.isf(p))
|
1705
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1706
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1707
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1708
|
+
with np.errstate(invalid='ignore'):
|
1709
|
+
assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
|
1710
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1711
|
+
seed = 3984593485
|
1712
|
+
assert_allclose(Y.sample(rng=seed), np.log(X.sample(rng=seed)))
|
1713
|
+
|
1714
|
+
def test_monotonic_transforms(self):
|
1715
|
+
# Some tests of monotonic transforms that are better to be grouped or
|
1716
|
+
# don't fit well above
|
1717
|
+
|
1718
|
+
X = Uniform(a=1, b=2)
|
1719
|
+
X_str = "Uniform(a=1.0, b=2.0)"
|
1720
|
+
|
1721
|
+
assert str(stats.log(X)) == f"log({X_str})"
|
1722
|
+
assert str(1 / X) == f"1/({X_str})"
|
1723
|
+
assert str(stats.exp(X)) == f"exp({X_str})"
|
1724
|
+
|
1725
|
+
X = Uniform(a=-1, b=2)
|
1726
|
+
message = "Division by a random variable is only implemented when the..."
|
1727
|
+
with pytest.raises(NotImplementedError, match=message):
|
1728
|
+
1 / X
|
1729
|
+
message = "The logarithm of a random variable is only implemented when the..."
|
1730
|
+
with pytest.raises(NotImplementedError, match=message):
|
1731
|
+
stats.log(X)
|
1732
|
+
message = "Raising an argument to the power of a random variable is only..."
|
1733
|
+
with pytest.raises(NotImplementedError, match=message):
|
1734
|
+
(-2) ** X
|
1735
|
+
with pytest.raises(NotImplementedError, match=message):
|
1736
|
+
1 ** X
|
1737
|
+
with pytest.raises(NotImplementedError, match=message):
|
1738
|
+
[0.5, 1.5] ** X
|
1739
|
+
|
1740
|
+
message = "Raising a random variable to the power of an argument is only"
|
1741
|
+
with pytest.raises(NotImplementedError, match=message):
|
1742
|
+
X ** (-2)
|
1743
|
+
with pytest.raises(NotImplementedError, match=message):
|
1744
|
+
X ** 0
|
1745
|
+
with pytest.raises(NotImplementedError, match=message):
|
1746
|
+
X ** [0.5, 1.5]
|
1747
|
+
|
1748
|
+
def test_arithmetic_operators(self):
|
1749
|
+
rng = np.random.default_rng(2348923495832349834)
|
1750
|
+
|
1751
|
+
a, b, loc, scale = 0.294, 1.34, 0.57, 1.16
|
1752
|
+
|
1753
|
+
x = rng.uniform(-3, 3, 100)
|
1754
|
+
Y = _LogUniform(a=a, b=b)
|
1755
|
+
|
1756
|
+
X = scale*Y + loc
|
1757
|
+
assert_allclose(X.cdf(x), Y.cdf((x - loc) / scale))
|
1758
|
+
X = loc + Y*scale
|
1759
|
+
assert_allclose(X.cdf(x), Y.cdf((x - loc) / scale))
|
1760
|
+
|
1761
|
+
X = Y/scale - loc
|
1762
|
+
assert_allclose(X.cdf(x), Y.cdf((x + loc) * scale))
|
1763
|
+
X = loc -_LogUniform(a=a, b=b)/scale
|
1764
|
+
assert_allclose(X.cdf(x), Y.ccdf((-x + loc)*scale))
|
1765
|
+
|
1766
|
+
def test_abs(self):
|
1767
|
+
rng = np.random.default_rng(81345982345826)
|
1768
|
+
loc = rng.random((3, 1))
|
1769
|
+
|
1770
|
+
Y = stats.abs(Normal() + loc)
|
1771
|
+
Y0 = stats.foldnorm(loc)
|
1772
|
+
|
1773
|
+
y = Y0.rvs((3, 10), random_state=rng)
|
1774
|
+
p = Y0.cdf(y)
|
1775
|
+
|
1776
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j))
|
1777
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1778
|
+
assert_allclose(Y.median(), Y0.ppf(0.5))
|
1779
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1780
|
+
assert_allclose(Y.variance(), Y0.var())
|
1781
|
+
assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
|
1782
|
+
assert_allclose(Y.skewness(), Y0.stats('s'))
|
1783
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
|
1784
|
+
assert_allclose(Y.support(), Y0.support())
|
1785
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1786
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1787
|
+
assert_allclose(Y.ccdf(y), Y0.sf(y))
|
1788
|
+
assert_allclose(Y.icdf(p), Y0.ppf(p))
|
1789
|
+
assert_allclose(Y.iccdf(p), Y0.isf(p))
|
1790
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1791
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1792
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1793
|
+
assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
|
1794
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1795
|
+
sample = Y.sample(10)
|
1796
|
+
assert np.all(sample > 0)
|
1797
|
+
|
1798
|
+
def test_abs_finite_support(self):
|
1799
|
+
# The original implementation of `FoldedDistribution` might evaluate
|
1800
|
+
# the private distribution methods outside the support. Check that this
|
1801
|
+
# is resolved.
|
1802
|
+
Weibull = stats.make_distribution(stats.weibull_min)
|
1803
|
+
X = Weibull(c=2)
|
1804
|
+
Y = abs(-X)
|
1805
|
+
assert_equal(X.logpdf(1), Y.logpdf(1))
|
1806
|
+
assert_equal(X.pdf(1), Y.pdf(1))
|
1807
|
+
assert_equal(X.logcdf(1), Y.logcdf(1))
|
1808
|
+
assert_equal(X.cdf(1), Y.cdf(1))
|
1809
|
+
assert_equal(X.logccdf(1), Y.logccdf(1))
|
1810
|
+
assert_equal(X.ccdf(1), Y.ccdf(1))
|
1811
|
+
|
1812
|
+
def test_pow(self):
|
1813
|
+
rng = np.random.default_rng(81345982345826)
|
1814
|
+
|
1815
|
+
Y = Normal()**2
|
1816
|
+
Y0 = stats.chi2(df=1)
|
1817
|
+
|
1818
|
+
y = Y0.rvs(10, random_state=rng)
|
1819
|
+
p = Y0.cdf(y)
|
1820
|
+
|
1821
|
+
assert_allclose(Y.logentropy(), np.log(Y0.entropy() + 0j), rtol=1e-6)
|
1822
|
+
assert_allclose(Y.entropy(), Y0.entropy(), rtol=1e-6)
|
1823
|
+
assert_allclose(Y.median(), Y0.median())
|
1824
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1825
|
+
assert_allclose(Y.variance(), Y0.var())
|
1826
|
+
assert_allclose(Y.standard_deviation(), np.sqrt(Y0.var()))
|
1827
|
+
assert_allclose(Y.skewness(), Y0.stats('s'))
|
1828
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3)
|
1829
|
+
assert_allclose(Y.support(), Y0.support())
|
1830
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1831
|
+
assert_allclose(Y.cdf(y), Y0.cdf(y))
|
1832
|
+
assert_allclose(Y.ccdf(y), Y0.sf(y))
|
1833
|
+
assert_allclose(Y.icdf(p), Y0.ppf(p))
|
1834
|
+
assert_allclose(Y.iccdf(p), Y0.isf(p))
|
1835
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1836
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1837
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1838
|
+
assert_allclose(Y.ilogcdf(np.log(p)), Y0.ppf(p))
|
1839
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1840
|
+
sample = Y.sample(10)
|
1841
|
+
assert np.all(sample > 0)
|
1842
|
+
|
1843
|
+
class TestOrderStatistic:
|
1844
|
+
@pytest.mark.fail_slow(20) # Moments require integration
|
1845
|
+
def test_order_statistic(self):
|
1846
|
+
rng = np.random.default_rng(7546349802439582)
|
1847
|
+
X = Uniform(a=0, b=1)
|
1848
|
+
n = 5
|
1849
|
+
r = np.asarray([[1], [3], [5]])
|
1850
|
+
Y = stats.order_statistic(X, n=n, r=r)
|
1851
|
+
Y0 = stats.beta(r, n + 1 - r)
|
1852
|
+
|
1853
|
+
y = Y0.rvs((3, 10), random_state=rng)
|
1854
|
+
p = Y0.cdf(y)
|
1855
|
+
|
1856
|
+
# log methods need some attention before merge
|
1857
|
+
assert_allclose(np.exp(Y.logentropy()), Y0.entropy())
|
1858
|
+
assert_allclose(Y.entropy(), Y0.entropy())
|
1859
|
+
assert_allclose(Y.mean(), Y0.mean())
|
1860
|
+
assert_allclose(Y.variance(), Y0.var())
|
1861
|
+
assert_allclose(Y.skewness(), Y0.stats('s'), atol=1e-15)
|
1862
|
+
assert_allclose(Y.kurtosis(), Y0.stats('k') + 3, atol=1e-15)
|
1863
|
+
assert_allclose(Y.median(), Y0.ppf(0.5))
|
1864
|
+
assert_allclose(Y.support(), Y0.support())
|
1865
|
+
assert_allclose(Y.pdf(y), Y0.pdf(y))
|
1866
|
+
assert_allclose(Y.cdf(y, method='formula'), Y.cdf(y, method='quadrature'))
|
1867
|
+
assert_allclose(Y.ccdf(y, method='formula'), Y.ccdf(y, method='quadrature'))
|
1868
|
+
assert_allclose(Y.icdf(p, method='formula'), Y.icdf(p, method='inversion'))
|
1869
|
+
assert_allclose(Y.iccdf(p, method='formula'), Y.iccdf(p, method='inversion'))
|
1870
|
+
assert_allclose(Y.logpdf(y), Y0.logpdf(y))
|
1871
|
+
assert_allclose(Y.logcdf(y), Y0.logcdf(y))
|
1872
|
+
assert_allclose(Y.logccdf(y), Y0.logsf(y))
|
1873
|
+
with np.errstate(invalid='ignore', divide='ignore'):
|
1874
|
+
assert_allclose(Y.ilogcdf(np.log(p),), Y0.ppf(p))
|
1875
|
+
assert_allclose(Y.ilogccdf(np.log(p)), Y0.isf(p))
|
1876
|
+
|
1877
|
+
message = "`r` and `n` must contain only positive integers."
|
1878
|
+
with pytest.raises(ValueError, match=message):
|
1879
|
+
stats.order_statistic(X, n=n, r=-1)
|
1880
|
+
with pytest.raises(ValueError, match=message):
|
1881
|
+
stats.order_statistic(X, n=-1, r=r)
|
1882
|
+
with pytest.raises(ValueError, match=message):
|
1883
|
+
stats.order_statistic(X, n=n, r=1.5)
|
1884
|
+
with pytest.raises(ValueError, match=message):
|
1885
|
+
stats.order_statistic(X, n=1.5, r=r)
|
1886
|
+
|
1887
|
+
def test_support_gh22037(self):
|
1888
|
+
# During review of gh-22037, it was noted that the `support` of
|
1889
|
+
# an `OrderStatisticDistribution` returned incorrect results;
|
1890
|
+
# this was resolved by overriding `_support`.
|
1891
|
+
Uniform = stats.make_distribution(stats.uniform)
|
1892
|
+
X = Uniform()
|
1893
|
+
Y = X*5 + 2
|
1894
|
+
Z = stats.order_statistic(Y, r=3, n=5)
|
1895
|
+
assert_allclose(Z.support(), Y.support())
|
1896
|
+
|
1897
|
+
def test_composition_gh22037(self):
|
1898
|
+
# During review of gh-22037, it was noted that an error was
|
1899
|
+
# raised when creating an `OrderStatisticDistribution` from
|
1900
|
+
# a `TruncatedDistribution`. This was resolved by overriding
|
1901
|
+
# `_update_parameters`.
|
1902
|
+
Normal = stats.make_distribution(stats.norm)
|
1903
|
+
TruncatedNormal = stats.make_distribution(stats.truncnorm)
|
1904
|
+
a, b = [-2, -1], 1
|
1905
|
+
r, n = 3, [[4], [5]]
|
1906
|
+
x = [[[-0.3]], [[0.1]]]
|
1907
|
+
X1 = Normal()
|
1908
|
+
Y1 = stats.truncate(X1, a, b)
|
1909
|
+
Z1 = stats.order_statistic(Y1, r=r, n=n)
|
1910
|
+
X2 = TruncatedNormal(a=a, b=b)
|
1911
|
+
Z2 = stats.order_statistic(X2, r=r, n=n)
|
1912
|
+
np.testing.assert_allclose(Z1.cdf(x), Z2.cdf(x))
|
1913
|
+
|
1914
|
+
|
1915
|
+
class TestFullCoverage:
|
1916
|
+
# Adds tests just to get to 100% test coverage; this way it's more obvious
|
1917
|
+
# if new lines are untested.
|
1918
|
+
def test_Domain(self):
|
1919
|
+
with pytest.raises(NotImplementedError):
|
1920
|
+
_Domain.contains(None, 1.)
|
1921
|
+
with pytest.raises(NotImplementedError):
|
1922
|
+
_Domain.get_numerical_endpoints(None, 1.)
|
1923
|
+
with pytest.raises(NotImplementedError):
|
1924
|
+
_Domain.__str__(None)
|
1925
|
+
|
1926
|
+
def test_Parameter(self):
|
1927
|
+
with pytest.raises(NotImplementedError):
|
1928
|
+
_Parameter.validate(None, 1.)
|
1929
|
+
|
1930
|
+
@pytest.mark.parametrize(("dtype_in", "dtype_out"),
|
1931
|
+
[(np.float16, np.float16),
|
1932
|
+
(np.int16, np.float64)])
|
1933
|
+
def test_RealParameter_uncommon_dtypes(self, dtype_in, dtype_out):
|
1934
|
+
domain = _RealInterval((-1, 1))
|
1935
|
+
parameter = _RealParameter('x', domain=domain)
|
1936
|
+
|
1937
|
+
x = np.asarray([0.5, 2.5], dtype=dtype_in)
|
1938
|
+
arr, dtype, valid = parameter.validate(x, parameter_values={})
|
1939
|
+
assert_equal(arr, x)
|
1940
|
+
assert dtype == dtype_out
|
1941
|
+
assert_equal(valid, [True, False])
|
1942
|
+
|
1943
|
+
def test_ContinuousDistribution_set_invalid_nan(self):
|
1944
|
+
# Exercise code paths when formula returns wrong shape and dtype
|
1945
|
+
# We could consider making this raise an error to force authors
|
1946
|
+
# to return the right shape and dytpe, but this would need to be
|
1947
|
+
# configurable.
|
1948
|
+
class TestDist(ContinuousDistribution):
|
1949
|
+
_variable = _RealParameter('x', domain=_RealInterval(endpoints=(0., 1.)))
|
1950
|
+
def _logpdf_formula(self, x, *args, **kwargs):
|
1951
|
+
return 0
|
1952
|
+
|
1953
|
+
X = TestDist()
|
1954
|
+
dtype = np.float32
|
1955
|
+
X._dtype = dtype
|
1956
|
+
x = np.asarray([0.5], dtype=dtype)
|
1957
|
+
assert X.logpdf(x).dtype == dtype
|
1958
|
+
|
1959
|
+
def test_fiinfo(self):
|
1960
|
+
assert _fiinfo(np.float64(1.)).max == np.finfo(np.float64).max
|
1961
|
+
assert _fiinfo(np.int64(1)).max == np.iinfo(np.int64).max
|
1962
|
+
|
1963
|
+
def test_generate_domain_support(self):
|
1964
|
+
msg = _generate_domain_support(StandardNormal)
|
1965
|
+
assert "accepts no distribution parameters" in msg
|
1966
|
+
|
1967
|
+
msg = _generate_domain_support(Normal)
|
1968
|
+
assert "accepts one parameterization" in msg
|
1969
|
+
|
1970
|
+
msg = _generate_domain_support(_LogUniform)
|
1971
|
+
assert "accepts two parameterizations" in msg
|
1972
|
+
|
1973
|
+
def test_ContinuousDistribution__repr__(self):
|
1974
|
+
X = Uniform(a=0, b=1)
|
1975
|
+
if np.__version__ < "2":
|
1976
|
+
assert repr(X) == "Uniform(a=0.0, b=1.0)"
|
1977
|
+
else:
|
1978
|
+
assert repr(X) == "Uniform(a=np.float64(0.0), b=np.float64(1.0))"
|
1979
|
+
if np.__version__ < "2":
|
1980
|
+
assert repr(X*3 + 2) == "3.0*Uniform(a=0.0, b=1.0) + 2.0"
|
1981
|
+
else:
|
1982
|
+
assert repr(X*3 + 2) == (
|
1983
|
+
"np.float64(3.0)*Uniform(a=np.float64(0.0), b=np.float64(1.0))"
|
1984
|
+
" + np.float64(2.0)"
|
1985
|
+
)
|
1986
|
+
|
1987
|
+
X = Uniform(a=np.zeros(4), b=1)
|
1988
|
+
assert repr(X) == "Uniform(a=array([0., 0., 0., 0.]), b=1)"
|
1989
|
+
|
1990
|
+
X = Uniform(a=np.zeros(4, dtype=np.float32), b=np.ones(4, dtype=np.float32))
|
1991
|
+
assert repr(X) == (
|
1992
|
+
"Uniform(a=array([0., 0., 0., 0.], dtype=float32),"
|
1993
|
+
" b=array([1., 1., 1., 1.], dtype=float32))"
|
1994
|
+
)
|
1995
|
+
|
1996
|
+
|
1997
|
+
class TestReprs:
|
1998
|
+
U = Uniform(a=0, b=1)
|
1999
|
+
V = Uniform(a=np.float32(0.0), b=np.float32(1.0))
|
2000
|
+
X = Normal(mu=-1, sigma=1)
|
2001
|
+
Y = Normal(mu=1, sigma=1)
|
2002
|
+
Z = Normal(mu=np.zeros(1000), sigma=1)
|
2003
|
+
|
2004
|
+
@pytest.mark.parametrize(
|
2005
|
+
"dist",
|
2006
|
+
[
|
2007
|
+
U,
|
2008
|
+
U - np.array([1.0, 2.0]),
|
2009
|
+
pytest.param(
|
2010
|
+
V,
|
2011
|
+
marks=pytest.mark.skipif(
|
2012
|
+
np.__version__ < "2",
|
2013
|
+
reason="numpy 1.x didn't have dtype in repr",
|
2014
|
+
)
|
2015
|
+
),
|
2016
|
+
pytest.param(
|
2017
|
+
np.ones(2, dtype=np.float32)*V + np.zeros(2, dtype=np.float64),
|
2018
|
+
marks=pytest.mark.skipif(
|
2019
|
+
np.__version__ < "2",
|
2020
|
+
reason="numpy 1.x didn't have dtype in repr",
|
2021
|
+
)
|
2022
|
+
),
|
2023
|
+
3*U + 2,
|
2024
|
+
U**4,
|
2025
|
+
(3*U + 2)**4,
|
2026
|
+
(3*U + 2)**3,
|
2027
|
+
2**U,
|
2028
|
+
2**(3*U + 1),
|
2029
|
+
1 / (1 + U),
|
2030
|
+
stats.order_statistic(U, r=3, n=5),
|
2031
|
+
stats.truncate(U, 0.2, 0.8),
|
2032
|
+
stats.Mixture([X, Y], weights=[0.3, 0.7]),
|
2033
|
+
abs(U),
|
2034
|
+
stats.exp(U),
|
2035
|
+
stats.log(1 + U),
|
2036
|
+
np.array([1.0, 2.0])*U + np.array([2.0, 3.0]),
|
2037
|
+
]
|
2038
|
+
)
|
2039
|
+
def test_executable(self, dist):
|
2040
|
+
# Test that reprs actually evaluate to proper distribution
|
2041
|
+
# provided relevant imports are made.
|
2042
|
+
from numpy import array # noqa: F401
|
2043
|
+
from numpy import float32 # noqa: F401
|
2044
|
+
from scipy.stats import abs, exp, log, order_statistic, truncate # noqa: F401
|
2045
|
+
from scipy.stats import Mixture, Normal # noqa: F401
|
2046
|
+
from scipy.stats._new_distributions import Uniform # noqa: F401
|
2047
|
+
new_dist = eval(repr(dist))
|
2048
|
+
# A basic check that the distributions are the same
|
2049
|
+
sample1 = dist.sample(shape=10, rng=1234)
|
2050
|
+
sample2 = new_dist.sample(shape=10, rng=1234)
|
2051
|
+
assert_equal(sample1, sample2)
|
2052
|
+
assert sample1.dtype is sample2.dtype
|
2053
|
+
|
2054
|
+
@pytest.mark.parametrize(
|
2055
|
+
"dist",
|
2056
|
+
[
|
2057
|
+
Z,
|
2058
|
+
np.full(1000, 2.0) * X + 1.0,
|
2059
|
+
2.0 * X + np.full(1000, 1.0),
|
2060
|
+
np.full(1000, 2.0) * X + 1.0,
|
2061
|
+
stats.truncate(Z, -1, 1),
|
2062
|
+
stats.truncate(Z, -np.ones(1000), np.ones(1000)),
|
2063
|
+
stats.order_statistic(X, r=np.arange(1, 1000), n=1000),
|
2064
|
+
Z**2,
|
2065
|
+
1.0 / (1 + stats.exp(Z)),
|
2066
|
+
2**Z,
|
2067
|
+
]
|
2068
|
+
)
|
2069
|
+
def test_not_too_long(self, dist):
|
2070
|
+
# Tests that array summarization is working to ensure reprs aren't too long.
|
2071
|
+
# None of the reprs above will be executable.
|
2072
|
+
assert len(repr(dist)) < 250
|
2073
|
+
|
2074
|
+
|
2075
|
+
class MixedDist(ContinuousDistribution):
|
2076
|
+
_variable = _RealParameter('x', domain=_RealInterval(endpoints=(-np.inf, np.inf)))
|
2077
|
+
def _pdf_formula(self, x, *args, **kwargs):
|
2078
|
+
return (0.4 * 1/(1.1 * np.sqrt(2*np.pi)) * np.exp(-0.5*((x+0.25)/1.1)**2)
|
2079
|
+
+ 0.6 * 1/(0.9 * np.sqrt(2*np.pi)) * np.exp(-0.5*((x-0.5)/0.9)**2))
|
2080
|
+
|
2081
|
+
|
2082
|
+
class TestMixture:
|
2083
|
+
def test_input_validation(self):
|
2084
|
+
message = "`components` must contain at least one random variable."
|
2085
|
+
with pytest.raises(ValueError, match=message):
|
2086
|
+
Mixture([])
|
2087
|
+
|
2088
|
+
message = "Each element of `components` must be an instance..."
|
2089
|
+
with pytest.raises(ValueError, match=message):
|
2090
|
+
Mixture((1, 2, 3))
|
2091
|
+
|
2092
|
+
message = "All elements of `components` must have scalar shapes."
|
2093
|
+
with pytest.raises(ValueError, match=message):
|
2094
|
+
Mixture([Normal(mu=[1, 2]), Normal()])
|
2095
|
+
|
2096
|
+
message = "`components` and `weights` must have the same length."
|
2097
|
+
with pytest.raises(ValueError, match=message):
|
2098
|
+
Mixture([Normal()], weights=[0.5, 0.5])
|
2099
|
+
|
2100
|
+
message = "`weights` must have floating point dtype."
|
2101
|
+
with pytest.raises(ValueError, match=message):
|
2102
|
+
Mixture([Normal()], weights=[1])
|
2103
|
+
|
2104
|
+
message = "`weights` must have floating point dtype."
|
2105
|
+
with pytest.raises(ValueError, match=message):
|
2106
|
+
Mixture([Normal()], weights=[1])
|
2107
|
+
|
2108
|
+
message = "`weights` must sum to 1.0."
|
2109
|
+
with pytest.raises(ValueError, match=message):
|
2110
|
+
Mixture([Normal(), Normal()], weights=[0.5, 1.0])
|
2111
|
+
|
2112
|
+
message = "All `weights` must be non-negative."
|
2113
|
+
with pytest.raises(ValueError, match=message):
|
2114
|
+
Mixture([Normal(), Normal()], weights=[1.5, -0.5])
|
2115
|
+
|
2116
|
+
@pytest.mark.parametrize('shape', [(), (10,)])
|
2117
|
+
def test_basic(self, shape):
|
2118
|
+
rng = np.random.default_rng(582348972387243524)
|
2119
|
+
X = Mixture((Normal(mu=-0.25, sigma=1.1), Normal(mu=0.5, sigma=0.9)),
|
2120
|
+
weights=(0.4, 0.6))
|
2121
|
+
Y = MixedDist()
|
2122
|
+
x = rng.random(shape)
|
2123
|
+
|
2124
|
+
def assert_allclose(res, ref, **kwargs):
|
2125
|
+
if shape == ():
|
2126
|
+
assert np.isscalar(res)
|
2127
|
+
np.testing.assert_allclose(res, ref, **kwargs)
|
2128
|
+
|
2129
|
+
assert_allclose(X.logentropy(), Y.logentropy())
|
2130
|
+
assert_allclose(X.entropy(), Y.entropy())
|
2131
|
+
assert_allclose(X.mode(), Y.mode())
|
2132
|
+
assert_allclose(X.median(), Y.median())
|
2133
|
+
assert_allclose(X.mean(), Y.mean())
|
2134
|
+
assert_allclose(X.variance(), Y.variance())
|
2135
|
+
assert_allclose(X.standard_deviation(), Y.standard_deviation())
|
2136
|
+
assert_allclose(X.skewness(), Y.skewness())
|
2137
|
+
assert_allclose(X.kurtosis(), Y.kurtosis())
|
2138
|
+
assert_allclose(X.logpdf(x), Y.logpdf(x))
|
2139
|
+
assert_allclose(X.pdf(x), Y.pdf(x))
|
2140
|
+
assert_allclose(X.logcdf(x), Y.logcdf(x))
|
2141
|
+
assert_allclose(X.cdf(x), Y.cdf(x))
|
2142
|
+
assert_allclose(X.logccdf(x), Y.logccdf(x))
|
2143
|
+
assert_allclose(X.ccdf(x), Y.ccdf(x))
|
2144
|
+
assert_allclose(X.ilogcdf(x), Y.ilogcdf(x))
|
2145
|
+
assert_allclose(X.icdf(x), Y.icdf(x))
|
2146
|
+
assert_allclose(X.ilogccdf(x), Y.ilogccdf(x))
|
2147
|
+
assert_allclose(X.iccdf(x), Y.iccdf(x))
|
2148
|
+
for kind in ['raw', 'central', 'standardized']:
|
2149
|
+
for order in range(5):
|
2150
|
+
assert_allclose(X.moment(order, kind=kind),
|
2151
|
+
Y.moment(order, kind=kind),
|
2152
|
+
atol=1e-15)
|
2153
|
+
|
2154
|
+
# weak test of `sample`
|
2155
|
+
shape = (10, 20, 5)
|
2156
|
+
y = X.sample(shape, rng=rng)
|
2157
|
+
assert y.shape == shape
|
2158
|
+
assert stats.ks_1samp(y.ravel(), X.cdf).pvalue > 0.05
|
2159
|
+
|
2160
|
+
def test_default_weights(self):
|
2161
|
+
a = 1.1
|
2162
|
+
Gamma = stats.make_distribution(stats.gamma)
|
2163
|
+
X = Gamma(a=a)
|
2164
|
+
Y = stats.Mixture((X, -X))
|
2165
|
+
x = np.linspace(-4, 4, 300)
|
2166
|
+
assert_allclose(Y.pdf(x), stats.dgamma(a=a).pdf(x))
|
2167
|
+
|
2168
|
+
def test_properties(self):
|
2169
|
+
components = [Normal(mu=-0.25, sigma=1.1), Normal(mu=0.5, sigma=0.9)]
|
2170
|
+
weights = (0.4, 0.6)
|
2171
|
+
X = Mixture(components, weights=weights)
|
2172
|
+
|
2173
|
+
# Replacing properties doesn't work
|
2174
|
+
# Different version of Python have different messages
|
2175
|
+
with pytest.raises(AttributeError):
|
2176
|
+
X.components = 10
|
2177
|
+
with pytest.raises(AttributeError):
|
2178
|
+
X.weights = 10
|
2179
|
+
|
2180
|
+
# Mutation doesn't work
|
2181
|
+
X.components[0] = components[1]
|
2182
|
+
assert X.components[0] == components[0]
|
2183
|
+
X.weights[0] = weights[1]
|
2184
|
+
assert X.weights[0] == weights[0]
|
2185
|
+
|
2186
|
+
def test_inverse(self):
|
2187
|
+
# Originally, inverse relied on the mean to start the bracket search.
|
2188
|
+
# This didn't work for distributions with non-finite mean. Check that
|
2189
|
+
# this is resolved.
|
2190
|
+
rng = np.random.default_rng(24358934657854237863456)
|
2191
|
+
Cauchy = stats.make_distribution(stats.cauchy)
|
2192
|
+
X0 = Cauchy()
|
2193
|
+
X = stats.Mixture([X0, X0])
|
2194
|
+
p = rng.random(size=10)
|
2195
|
+
np.testing.assert_allclose(X.icdf(p), X0.icdf(p))
|
2196
|
+
np.testing.assert_allclose(X.iccdf(p), X0.iccdf(p))
|
2197
|
+
np.testing.assert_allclose(X.ilogcdf(p), X0.ilogcdf(p))
|
2198
|
+
np.testing.assert_allclose(X.ilogccdf(p), X0.ilogccdf(p))
|