scipy 1.16.2__cp313-cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_cyutility.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_ccallback_c.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_fpumode.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_test_ccallback.cp313t-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_call.cp313t-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_def.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_lib/_uarray/_uarray.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/_lib/messagestream.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/cluster/_hierarchy.cp313t-win_arm64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp313t-win_arm64.lib +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp313t-win_arm64.pyd +0 -0
- scipy/cluster/_vq.cp313t-win_arm64.lib +0 -0
- scipy/cluster/_vq.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/fftpack/convolve.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_dop.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_lsoda.cp313t-win_arm64.pyd +0 -0
- scipy/integrate/_ode.py +1395 -0
- scipy/integrate/_odepack.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_odepack.cp313t-win_arm64.pyd +0 -0
- scipy/integrate/_odepack_py.py +273 -0
- scipy/integrate/_quad_vec.py +674 -0
- scipy/integrate/_quadpack.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_quadpack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_test_multivariate.cp313t-win_arm64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_test_odeint_banded.cp313t-win_arm64.pyd +0 -0
- scipy/integrate/_vode.cp313t-win_arm64.lib +0 -0
- scipy/integrate/_vode.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_dfitpack.cp313t-win_arm64.pyd +0 -0
- scipy/interpolate/_dierckx.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_dierckx.cp313t-win_arm64.pyd +0 -0
- scipy/interpolate/_fitpack.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_fitpack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_interpnd.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_ppoly.cp313t-win_arm64.pyd +0 -0
- scipy/interpolate/_rbf.py +290 -0
- scipy/interpolate/_rbfinterp.py +550 -0
- scipy/interpolate/_rbfinterp_pythran.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp313t-win_arm64.pyd +0 -0
- scipy/interpolate/_rgi.py +764 -0
- scipy/interpolate/_rgi_cython.cp313t-win_arm64.lib +0 -0
- scipy/interpolate/_rgi_cython.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/io/_test_fortran.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/io/matlab/_mio5_utils.cp313t-win_arm64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp313t-win_arm64.lib +0 -0
- scipy/io/matlab/_mio_utils.cp313t-win_arm64.pyd +0 -0
- scipy/io/matlab/_miobase.py +435 -0
- scipy/io/matlab/_streams.cp313t-win_arm64.lib +0 -0
- scipy/io/matlab/_streams.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_cythonized_array_utils.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_interpolative.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +356 -0
- scipy/linalg/_decomp_lu.py +401 -0
- scipy/linalg/_decomp_lu_cython.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_lu_cython.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_update.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +417 -0
- scipy/linalg/_fblas.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_fblas.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_flapack.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_flapack.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_lapack_subroutines.h +1521 -0
- scipy/linalg/_linalg_pythran.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_linalg_pythran.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs.py +1050 -0
- scipy/linalg/_matfuncs_expm.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_expm.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +107 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/_solve_toeplitz.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/linalg/cython_blas.cp313t-win_arm64.pyd +0 -0
- scipy/linalg/cython_blas.pxd +169 -0
- scipy/linalg/cython_blas.pyx +1432 -0
- scipy/linalg/cython_lapack.cp313t-win_arm64.lib +0 -0
- scipy/linalg/cython_lapack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/ndimage/_ctest.cp313t-win_arm64.pyd +0 -0
- scipy/ndimage/_cytest.cp313t-win_arm64.lib +0 -0
- scipy/ndimage/_cytest.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/ndimage/_nd_image.cp313t-win_arm64.pyd +0 -0
- scipy/ndimage/_ndimage_api.py +16 -0
- scipy/ndimage/_ni_docstrings.py +214 -0
- scipy/ndimage/_ni_label.cp313t-win_arm64.lib +0 -0
- scipy/ndimage/_ni_label.cp313t-win_arm64.pyd +0 -0
- scipy/ndimage/_ni_support.py +139 -0
- scipy/ndimage/_rank_filter_1d.cp313t-win_arm64.lib +0 -0
- scipy/ndimage/_rank_filter_1d.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/odr/__odrpack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_bglu_dense.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_direct.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_group_columns.cp313t-win_arm64.pyd +0 -0
- scipy/optimize/_hessian_update_strategy.py +479 -0
- scipy/optimize/_highspy/__init__.py +0 -0
- scipy/optimize/_highspy/_core.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_core.cp313t-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_highs_options.cp313t-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_wrapper.py +338 -0
- scipy/optimize/_isotonic.py +157 -0
- scipy/optimize/_lbfgsb.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_lbfgsb.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_lsap.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_lsq/givens_elimination.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_minpack.cp313t-win_arm64.pyd +0 -0
- scipy/optimize/_minpack_py.py +1178 -0
- scipy/optimize/_moduleTNC.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_moduleTNC.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_pava_pybind.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_slsqplib.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_trlib/_trlib.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/_zeros.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/optimize/cython_optimize/_zeros.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/signal/_max_len_seq_inner.cp313t-win_arm64.pyd +0 -0
- scipy/signal/_peak_finding.py +1310 -0
- scipy/signal/_peak_finding_utils.cp313t-win_arm64.lib +0 -0
- scipy/signal/_peak_finding_utils.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/signal/_sigtools.cp313t-win_arm64.pyd +0 -0
- scipy/signal/_sosfilt.cp313t-win_arm64.lib +0 -0
- scipy/signal/_sosfilt.cp313t-win_arm64.pyd +0 -0
- scipy/signal/_spectral_py.py +2471 -0
- scipy/signal/_spline.cp313t-win_arm64.lib +0 -0
- scipy/signal/_spline.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/signal/_upfirdn_apply.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/_csparsetools.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/_sparsetools.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_flow.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_laplacian.py +563 -0
- scipy/sparse/csgraph/_matching.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_matching.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_reordering.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_shortest_path.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_tools.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp313t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_traversal.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp313t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp313t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_ckdtree.cp313t-win_arm64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_distance_pybind.cp313t-win_arm64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_distance_wrap.cp313t-win_arm64.pyd +0 -0
- scipy/spatial/_geometric_slerp.py +238 -0
- scipy/spatial/_hausdorff.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_hausdorff.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_qhull.cp313t-win_arm64.pyd +0 -0
- scipy/spatial/_qhull.pyi +213 -0
- scipy/spatial/_spherical_voronoi.py +341 -0
- scipy/spatial/_voronoi.cp313t-win_arm64.lib +0 -0
- scipy/spatial/_voronoi.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/spatial/transform/_rigid_transform.cp313t-win_arm64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp313t-win_arm64.lib +0 -0
- scipy/spatial/transform/_rotation.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/special/_comb.cp313t-win_arm64.pyd +0 -0
- scipy/special/_ellip_harm.py +214 -0
- scipy/special/_ellip_harm_2.cp313t-win_arm64.lib +0 -0
- scipy/special/_ellip_harm_2.cp313t-win_arm64.pyd +0 -0
- scipy/special/_gufuncs.cp313t-win_arm64.lib +0 -0
- scipy/special/_gufuncs.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/special/_specfun.cp313t-win_arm64.pyd +0 -0
- scipy/special/_special_ufuncs.cp313t-win_arm64.lib +0 -0
- scipy/special/_special_ufuncs.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/special/_test_internal.cp313t-win_arm64.pyd +0 -0
- scipy/special/_test_internal.pyi +9 -0
- scipy/special/_testutils.py +321 -0
- scipy/special/_ufuncs.cp313t-win_arm64.lib +0 -0
- scipy/special/_ufuncs.cp313t-win_arm64.pyd +0 -0
- scipy/special/_ufuncs.pyi +522 -0
- scipy/special/_ufuncs.pyx +13173 -0
- scipy/special/_ufuncs_cxx.cp313t-win_arm64.lib +0 -0
- scipy/special/_ufuncs_cxx.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/special/cython_special.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_ansari_swilk_statistics.cp313t-win_arm64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +692 -0
- scipy/stats/_biasedurn.cp313t-win_arm64.lib +0 -0
- scipy/stats/_biasedurn.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_levy_stable/levyst.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_qmc_cy.cp313t-win_arm64.pyd +0 -0
- scipy/stats/_qmc_cy.pyi +54 -0
- scipy/stats/_qmvnt.py +454 -0
- scipy/stats/_qmvnt_cy.cp313t-win_arm64.lib +0 -0
- scipy/stats/_qmvnt_cy.cp313t-win_arm64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/__init__.py +4 -0
- scipy/stats/_rcont/rcont.cp313t-win_arm64.lib +0 -0
- scipy/stats/_rcont/rcont.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_sobol.cp313t-win_arm64.pyd +0 -0
- scipy/stats/_sobol.pyi +54 -0
- scipy/stats/_sobol_direction_numbers.npz +0 -0
- scipy/stats/_stats.cp313t-win_arm64.lib +0 -0
- scipy/stats/_stats.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_stats_pythran.cp313t-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.cp313t-win_arm64.lib +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp313t-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,4815 @@
|
|
1
|
+
# this program corresponds to special.py
|
2
|
+
|
3
|
+
### Means test is not done yet
|
4
|
+
# E Means test is giving error (E)
|
5
|
+
# F Means test is failing (F)
|
6
|
+
# EF Means test is giving error and Failing
|
7
|
+
#! Means test is segfaulting
|
8
|
+
# 8 Means test runs forever
|
9
|
+
|
10
|
+
### test_besselpoly
|
11
|
+
### test_mathieu_a
|
12
|
+
### test_mathieu_even_coef
|
13
|
+
### test_mathieu_odd_coef
|
14
|
+
### test_modfresnelp
|
15
|
+
### test_modfresnelm
|
16
|
+
# test_pbdv_seq
|
17
|
+
### test_pbvv_seq
|
18
|
+
### test_sph_harm
|
19
|
+
|
20
|
+
import functools
|
21
|
+
import itertools
|
22
|
+
import operator
|
23
|
+
import platform
|
24
|
+
import sys
|
25
|
+
|
26
|
+
import numpy as np
|
27
|
+
from numpy import (array, isnan, r_, arange, finfo, pi, sin, cos, tan, exp,
|
28
|
+
log, zeros, sqrt, asarray, inf, nan_to_num, real, arctan, double,
|
29
|
+
array_equal)
|
30
|
+
|
31
|
+
import pytest
|
32
|
+
from pytest import raises as assert_raises
|
33
|
+
from numpy.testing import (assert_equal, assert_almost_equal,
|
34
|
+
assert_array_equal, assert_array_almost_equal, assert_approx_equal,
|
35
|
+
assert_, assert_allclose, assert_array_almost_equal_nulp,
|
36
|
+
suppress_warnings)
|
37
|
+
|
38
|
+
from scipy import special
|
39
|
+
import scipy.special._ufuncs as cephes
|
40
|
+
from scipy.special import ellipe, ellipk, ellipkm1
|
41
|
+
from scipy.special import elliprc, elliprd, elliprf, elliprg, elliprj
|
42
|
+
from scipy.special import softplus
|
43
|
+
from scipy.special import mathieu_odd_coef, mathieu_even_coef, stirling2
|
44
|
+
from scipy.special import lpn, lpmn, clpmn
|
45
|
+
from scipy._lib._util import np_long, np_ulong
|
46
|
+
from scipy._lib._array_api import xp_assert_close, xp_assert_equal, SCIPY_ARRAY_API
|
47
|
+
|
48
|
+
from scipy.special._basic import (
|
49
|
+
_FACTORIALK_LIMITS_64BITS, _FACTORIALK_LIMITS_32BITS, _is_subdtype
|
50
|
+
)
|
51
|
+
from scipy.special._testutils import with_special_errors, \
|
52
|
+
assert_func_equal, FuncData
|
53
|
+
|
54
|
+
import math
|
55
|
+
|
56
|
+
|
57
|
+
native_int = np.int32 if (
|
58
|
+
sys.platform == 'win32'
|
59
|
+
or platform.architecture()[0] == "32bit"
|
60
|
+
) else np.int64
|
61
|
+
|
62
|
+
|
63
|
+
class TestCephes:
|
64
|
+
def test_airy(self):
|
65
|
+
cephes.airy(0)
|
66
|
+
|
67
|
+
def test_airye(self):
|
68
|
+
cephes.airye(0)
|
69
|
+
|
70
|
+
def test_binom(self):
|
71
|
+
n = np.array([0.264, 4, 5.2, 17])
|
72
|
+
k = np.array([2, 0.4, 7, 3.3])
|
73
|
+
nk = np.array(np.broadcast_arrays(n[:,None], k[None,:])
|
74
|
+
).reshape(2, -1).T
|
75
|
+
rknown = np.array([[-0.097152, 0.9263051596159367, 0.01858423645695389,
|
76
|
+
-0.007581020651518199],[6, 2.0214389119675666, 0, 2.9827344527963846],
|
77
|
+
[10.92, 2.22993515861399, -0.00585728, 10.468891352063146],
|
78
|
+
[136, 3.5252179590758828, 19448, 1024.5526916174495]])
|
79
|
+
assert_func_equal(cephes.binom, rknown.ravel(), nk, rtol=1e-13)
|
80
|
+
|
81
|
+
# Test branches in implementation
|
82
|
+
rng = np.random.RandomState(1234)
|
83
|
+
n = np.r_[np.arange(-7, 30), 1000*rng.rand(30) - 500]
|
84
|
+
k = np.arange(0, 102)
|
85
|
+
nk = np.array(np.broadcast_arrays(n[:,None], k[None,:])
|
86
|
+
).reshape(2, -1).T
|
87
|
+
|
88
|
+
assert_func_equal(cephes.binom,
|
89
|
+
cephes.binom(nk[:,0], nk[:,1] * (1 + 1e-15)),
|
90
|
+
nk,
|
91
|
+
atol=1e-10, rtol=1e-10)
|
92
|
+
|
93
|
+
def test_binom_2(self):
|
94
|
+
# Test branches in implementation
|
95
|
+
np.random.seed(1234)
|
96
|
+
n = np.r_[np.logspace(1, 300, 20)]
|
97
|
+
k = np.arange(0, 102)
|
98
|
+
nk = np.array(np.broadcast_arrays(n[:,None], k[None,:])
|
99
|
+
).reshape(2, -1).T
|
100
|
+
|
101
|
+
assert_func_equal(cephes.binom,
|
102
|
+
cephes.binom(nk[:,0], nk[:,1] * (1 + 1e-15)),
|
103
|
+
nk,
|
104
|
+
atol=1e-10, rtol=1e-10)
|
105
|
+
|
106
|
+
def test_binom_exact(self):
|
107
|
+
@np.vectorize
|
108
|
+
def binom_int(n, k):
|
109
|
+
n = int(n)
|
110
|
+
k = int(k)
|
111
|
+
num = 1
|
112
|
+
den = 1
|
113
|
+
for i in range(1, k+1):
|
114
|
+
num *= i + n - k
|
115
|
+
den *= i
|
116
|
+
return float(num/den)
|
117
|
+
|
118
|
+
np.random.seed(1234)
|
119
|
+
n = np.arange(1, 15)
|
120
|
+
k = np.arange(0, 15)
|
121
|
+
nk = np.array(np.broadcast_arrays(n[:,None], k[None,:])
|
122
|
+
).reshape(2, -1).T
|
123
|
+
nk = nk[nk[:,0] >= nk[:,1]]
|
124
|
+
assert_func_equal(cephes.binom,
|
125
|
+
binom_int(nk[:,0], nk[:,1]),
|
126
|
+
nk,
|
127
|
+
atol=0, rtol=0)
|
128
|
+
|
129
|
+
def test_binom_nooverflow_8346(self):
|
130
|
+
# Test (binom(n, k) doesn't overflow prematurely */
|
131
|
+
dataset = [
|
132
|
+
(1000, 500, 2.70288240945436551e+299),
|
133
|
+
(1002, 501, 1.08007396880791225e+300),
|
134
|
+
(1004, 502, 4.31599279169058121e+300),
|
135
|
+
(1006, 503, 1.72468101616263781e+301),
|
136
|
+
(1008, 504, 6.89188009236419153e+301),
|
137
|
+
(1010, 505, 2.75402257948335448e+302),
|
138
|
+
(1012, 506, 1.10052048531923757e+303),
|
139
|
+
(1014, 507, 4.39774063758732849e+303),
|
140
|
+
(1016, 508, 1.75736486108312519e+304),
|
141
|
+
(1018, 509, 7.02255427788423734e+304),
|
142
|
+
(1020, 510, 2.80626776829962255e+305),
|
143
|
+
(1022, 511, 1.12140876377061240e+306),
|
144
|
+
(1024, 512, 4.48125455209897109e+306),
|
145
|
+
(1026, 513, 1.79075474304149900e+307),
|
146
|
+
(1028, 514, 7.15605105487789676e+307)
|
147
|
+
]
|
148
|
+
dataset = np.asarray(dataset)
|
149
|
+
FuncData(cephes.binom, dataset, (0, 1), 2, rtol=1e-12).check()
|
150
|
+
|
151
|
+
def test_bdtr(self):
|
152
|
+
assert_equal(cephes.bdtr(1,1,0.5),1.0)
|
153
|
+
|
154
|
+
def test_bdtri(self):
|
155
|
+
assert_equal(cephes.bdtri(1,3,0.5),0.5)
|
156
|
+
|
157
|
+
def test_bdtrc(self):
|
158
|
+
assert_equal(cephes.bdtrc(1,3,0.5),0.5)
|
159
|
+
|
160
|
+
def test_bdtrin(self):
|
161
|
+
assert_equal(cephes.bdtrin(1,0,1),5.0)
|
162
|
+
|
163
|
+
def test_bdtrik(self):
|
164
|
+
cephes.bdtrik(1,3,0.5)
|
165
|
+
|
166
|
+
def test_bei(self):
|
167
|
+
assert_equal(cephes.bei(0),0.0)
|
168
|
+
|
169
|
+
def test_beip(self):
|
170
|
+
assert_equal(cephes.beip(0),0.0)
|
171
|
+
|
172
|
+
def test_ber(self):
|
173
|
+
assert_equal(cephes.ber(0),1.0)
|
174
|
+
|
175
|
+
def test_berp(self):
|
176
|
+
assert_equal(cephes.berp(0),0.0)
|
177
|
+
|
178
|
+
def test_besselpoly(self):
|
179
|
+
assert_equal(cephes.besselpoly(0,0,0),1.0)
|
180
|
+
|
181
|
+
def test_btdtria(self):
|
182
|
+
assert_equal(cephes.btdtria(1,1,1),5.0)
|
183
|
+
|
184
|
+
def test_btdtrib(self):
|
185
|
+
assert_equal(cephes.btdtrib(1,1,1),5.0)
|
186
|
+
|
187
|
+
def test_cbrt(self):
|
188
|
+
assert_approx_equal(cephes.cbrt(1),1.0)
|
189
|
+
|
190
|
+
def test_chdtr(self):
|
191
|
+
assert_equal(cephes.chdtr(1,0),0.0)
|
192
|
+
|
193
|
+
def test_chdtrc(self):
|
194
|
+
assert_equal(cephes.chdtrc(1,0),1.0)
|
195
|
+
|
196
|
+
def test_chdtri(self):
|
197
|
+
assert_equal(cephes.chdtri(1,1),0.0)
|
198
|
+
|
199
|
+
def test_chdtriv(self):
|
200
|
+
assert_equal(cephes.chdtriv(0,0),5.0)
|
201
|
+
|
202
|
+
def test_chndtr(self):
|
203
|
+
assert_equal(cephes.chndtr(0,1,0),0.0)
|
204
|
+
|
205
|
+
# Each row holds (x, nu, lam, expected_value)
|
206
|
+
# These values were computed using Wolfram Alpha with
|
207
|
+
# CDF[NoncentralChiSquareDistribution[nu, lam], x]
|
208
|
+
values = np.array([
|
209
|
+
[25.00, 20.0, 400, 4.1210655112396197139e-57],
|
210
|
+
[25.00, 8.00, 250, 2.3988026526832425878e-29],
|
211
|
+
[0.001, 8.00, 40., 5.3761806201366039084e-24],
|
212
|
+
[0.010, 8.00, 40., 5.45396231055999457039e-20],
|
213
|
+
[20.00, 2.00, 107, 1.39390743555819597802e-9],
|
214
|
+
[22.50, 2.00, 107, 7.11803307138105870671e-9],
|
215
|
+
[25.00, 2.00, 107, 3.11041244829864897313e-8],
|
216
|
+
[3.000, 2.00, 1.0, 0.62064365321954362734],
|
217
|
+
[350.0, 300., 10., 0.93880128006276407710],
|
218
|
+
[100.0, 13.5, 10., 0.99999999650104210949],
|
219
|
+
[700.0, 20.0, 400, 0.99999999925680650105],
|
220
|
+
[150.0, 13.5, 10., 0.99999999999999983046],
|
221
|
+
[160.0, 13.5, 10., 0.99999999999999999518], # 1.0
|
222
|
+
])
|
223
|
+
cdf = cephes.chndtr(values[:, 0], values[:, 1], values[:, 2])
|
224
|
+
assert_allclose(cdf, values[:, 3], rtol=1e-12)
|
225
|
+
|
226
|
+
assert_almost_equal(cephes.chndtr(np.inf, np.inf, 0), 2.0)
|
227
|
+
assert_almost_equal(cephes.chndtr(2, 1, np.inf), 0.0)
|
228
|
+
assert_(np.isnan(cephes.chndtr(np.nan, 1, 2)))
|
229
|
+
assert_(np.isnan(cephes.chndtr(5, np.nan, 2)))
|
230
|
+
assert_(np.isnan(cephes.chndtr(5, 1, np.nan)))
|
231
|
+
|
232
|
+
def test_chndtridf(self):
|
233
|
+
assert_equal(cephes.chndtridf(0,0,1),5.0)
|
234
|
+
|
235
|
+
def test_chndtrinc(self):
|
236
|
+
assert_equal(cephes.chndtrinc(0,1,0),5.0)
|
237
|
+
|
238
|
+
def test_chndtrix(self):
|
239
|
+
assert_equal(cephes.chndtrix(0,1,0),0.0)
|
240
|
+
|
241
|
+
def test_cosdg(self):
|
242
|
+
assert_equal(cephes.cosdg(0),1.0)
|
243
|
+
|
244
|
+
def test_cosm1(self):
|
245
|
+
assert_equal(cephes.cosm1(0),0.0)
|
246
|
+
|
247
|
+
def test_cotdg(self):
|
248
|
+
assert_almost_equal(cephes.cotdg(45),1.0)
|
249
|
+
|
250
|
+
def test_dawsn(self):
|
251
|
+
assert_equal(cephes.dawsn(0),0.0)
|
252
|
+
assert_allclose(cephes.dawsn(1.23), 0.50053727749081767)
|
253
|
+
|
254
|
+
def test_diric(self):
|
255
|
+
# Test behavior near multiples of 2pi. Regression test for issue
|
256
|
+
# described in gh-4001.
|
257
|
+
n_odd = [1, 5, 25]
|
258
|
+
x = np.array(2*np.pi + 5e-5).astype(np.float32)
|
259
|
+
assert_almost_equal(special.diric(x, n_odd), 1.0, decimal=7)
|
260
|
+
x = np.array(2*np.pi + 1e-9).astype(np.float64)
|
261
|
+
assert_almost_equal(special.diric(x, n_odd), 1.0, decimal=15)
|
262
|
+
x = np.array(2*np.pi + 1e-15).astype(np.float64)
|
263
|
+
assert_almost_equal(special.diric(x, n_odd), 1.0, decimal=15)
|
264
|
+
if hasattr(np, 'float128'):
|
265
|
+
# No float128 available in 32-bit numpy
|
266
|
+
x = np.array(2*np.pi + 1e-12).astype(np.float128)
|
267
|
+
assert_almost_equal(special.diric(x, n_odd), 1.0, decimal=19)
|
268
|
+
|
269
|
+
n_even = [2, 4, 24]
|
270
|
+
x = np.array(2*np.pi + 1e-9).astype(np.float64)
|
271
|
+
assert_almost_equal(special.diric(x, n_even), -1.0, decimal=15)
|
272
|
+
|
273
|
+
# Test at some values not near a multiple of pi
|
274
|
+
x = np.arange(0.2*np.pi, 1.0*np.pi, 0.2*np.pi)
|
275
|
+
octave_result = [0.872677996249965, 0.539344662916632,
|
276
|
+
0.127322003750035, -0.206011329583298]
|
277
|
+
assert_almost_equal(special.diric(x, 3), octave_result, decimal=15)
|
278
|
+
|
279
|
+
def test_diric_broadcasting(self):
|
280
|
+
x = np.arange(5)
|
281
|
+
n = np.array([1, 3, 7])
|
282
|
+
assert_(special.diric(x[:, np.newaxis], n).shape == (x.size, n.size))
|
283
|
+
|
284
|
+
def test_ellipe(self):
|
285
|
+
assert_equal(cephes.ellipe(1),1.0)
|
286
|
+
|
287
|
+
def test_ellipeinc(self):
|
288
|
+
assert_equal(cephes.ellipeinc(0,1),0.0)
|
289
|
+
|
290
|
+
def test_ellipj(self):
|
291
|
+
cephes.ellipj(0,1)
|
292
|
+
|
293
|
+
def test_ellipk(self):
|
294
|
+
assert_allclose(ellipk(0), pi/2)
|
295
|
+
|
296
|
+
def test_ellipkinc(self):
|
297
|
+
assert_equal(cephes.ellipkinc(0,0),0.0)
|
298
|
+
|
299
|
+
def test_erf(self):
|
300
|
+
assert_equal(cephes.erf(0), 0.0)
|
301
|
+
|
302
|
+
def test_erf_symmetry(self):
|
303
|
+
x = 5.905732037710919
|
304
|
+
assert_equal(cephes.erf(x) + cephes.erf(-x), 0.0)
|
305
|
+
|
306
|
+
def test_erfc(self):
|
307
|
+
assert_equal(cephes.erfc(0), 1.0)
|
308
|
+
|
309
|
+
def test_exp10(self):
|
310
|
+
assert_approx_equal(cephes.exp10(2),100.0)
|
311
|
+
|
312
|
+
def test_exp2(self):
|
313
|
+
assert_equal(cephes.exp2(2),4.0)
|
314
|
+
|
315
|
+
def test_expm1(self):
|
316
|
+
assert_equal(cephes.expm1(0),0.0)
|
317
|
+
assert_equal(cephes.expm1(np.inf), np.inf)
|
318
|
+
assert_equal(cephes.expm1(-np.inf), -1)
|
319
|
+
assert_equal(cephes.expm1(np.nan), np.nan)
|
320
|
+
|
321
|
+
def test_expm1_complex(self):
|
322
|
+
expm1 = cephes.expm1
|
323
|
+
assert_equal(expm1(0 + 0j), 0 + 0j)
|
324
|
+
assert_equal(expm1(complex(np.inf, 0)), complex(np.inf, 0))
|
325
|
+
assert_equal(expm1(complex(np.inf, 1)), complex(np.inf, np.inf))
|
326
|
+
assert_equal(expm1(complex(np.inf, 2)), complex(-np.inf, np.inf))
|
327
|
+
assert_equal(expm1(complex(np.inf, 4)), complex(-np.inf, -np.inf))
|
328
|
+
assert_equal(expm1(complex(np.inf, 5)), complex(np.inf, -np.inf))
|
329
|
+
assert_equal(expm1(complex(1, np.inf)), complex(np.nan, np.nan))
|
330
|
+
assert_equal(expm1(complex(0, np.inf)), complex(np.nan, np.nan))
|
331
|
+
assert_equal(expm1(complex(np.inf, np.inf)), complex(np.inf, np.nan))
|
332
|
+
assert_equal(expm1(complex(-np.inf, np.inf)), complex(-1, 0))
|
333
|
+
assert_equal(expm1(complex(-np.inf, np.nan)), complex(-1, 0))
|
334
|
+
assert_equal(expm1(complex(np.inf, np.nan)), complex(np.inf, np.nan))
|
335
|
+
assert_equal(expm1(complex(0, np.nan)), complex(np.nan, np.nan))
|
336
|
+
assert_equal(expm1(complex(1, np.nan)), complex(np.nan, np.nan))
|
337
|
+
assert_equal(expm1(complex(np.nan, 1)), complex(np.nan, np.nan))
|
338
|
+
assert_equal(expm1(complex(np.nan, np.nan)), complex(np.nan, np.nan))
|
339
|
+
|
340
|
+
@pytest.mark.xfail(reason='The real part of expm1(z) bad at these points')
|
341
|
+
def test_expm1_complex_hard(self):
|
342
|
+
# The real part of this function is difficult to evaluate when
|
343
|
+
# z.real = -log(cos(z.imag)).
|
344
|
+
y = np.array([0.1, 0.2, 0.3, 5, 11, 20])
|
345
|
+
x = -np.log(np.cos(y))
|
346
|
+
z = x + 1j*y
|
347
|
+
|
348
|
+
# evaluate using mpmath.expm1 with dps=1000
|
349
|
+
expected = np.array([-5.5507901846769623e-17+0.10033467208545054j,
|
350
|
+
2.4289354732893695e-18+0.20271003550867248j,
|
351
|
+
4.5235500262585768e-17+0.30933624960962319j,
|
352
|
+
7.8234305217489006e-17-3.3805150062465863j,
|
353
|
+
-1.3685191953697676e-16-225.95084645419513j,
|
354
|
+
8.7175620481291045e-17+2.2371609442247422j])
|
355
|
+
found = cephes.expm1(z)
|
356
|
+
# this passes.
|
357
|
+
assert_array_almost_equal_nulp(found.imag, expected.imag, 3)
|
358
|
+
# this fails.
|
359
|
+
assert_array_almost_equal_nulp(found.real, expected.real, 20)
|
360
|
+
|
361
|
+
def test_fdtr(self):
|
362
|
+
assert_equal(cephes.fdtr(1, 1, 0), 0.0)
|
363
|
+
# Computed using Wolfram Alpha: CDF[FRatioDistribution[1e-6, 5], 10]
|
364
|
+
assert_allclose(cephes.fdtr(1e-6, 5, 10), 0.9999940790193488,
|
365
|
+
rtol=1e-12)
|
366
|
+
|
367
|
+
def test_fdtrc(self):
|
368
|
+
assert_equal(cephes.fdtrc(1, 1, 0), 1.0)
|
369
|
+
# Computed using Wolfram Alpha:
|
370
|
+
# 1 - CDF[FRatioDistribution[2, 1/10], 1e10]
|
371
|
+
assert_allclose(cephes.fdtrc(2, 0.1, 1e10), 0.27223784621293512,
|
372
|
+
rtol=1e-12)
|
373
|
+
|
374
|
+
def test_fdtri(self):
|
375
|
+
assert_allclose(cephes.fdtri(1, 1, [0.499, 0.501]),
|
376
|
+
array([0.9937365, 1.00630298]), rtol=1e-6)
|
377
|
+
# From Wolfram Alpha:
|
378
|
+
# CDF[FRatioDistribution[1/10, 1], 3] = 0.8756751669632105666874...
|
379
|
+
p = 0.8756751669632105666874
|
380
|
+
assert_allclose(cephes.fdtri(0.1, 1, p), 3, rtol=1e-12)
|
381
|
+
|
382
|
+
@pytest.mark.xfail(reason='Returns nan on i686.')
|
383
|
+
def test_fdtri_mysterious_failure(self):
|
384
|
+
assert_allclose(cephes.fdtri(1, 1, 0.5), 1)
|
385
|
+
|
386
|
+
def test_fdtridfd(self):
|
387
|
+
assert_equal(cephes.fdtridfd(1,0,0),5.0)
|
388
|
+
|
389
|
+
def test_fresnel(self):
|
390
|
+
assert_equal(cephes.fresnel(0),(0.0,0.0))
|
391
|
+
|
392
|
+
def test_gamma(self):
|
393
|
+
assert_equal(cephes.gamma(5),24.0)
|
394
|
+
|
395
|
+
def test_gammainccinv(self):
|
396
|
+
assert_equal(cephes.gammainccinv(5,1),0.0)
|
397
|
+
|
398
|
+
def test_gammaln(self):
|
399
|
+
cephes.gammaln(10)
|
400
|
+
|
401
|
+
def test_gammasgn(self):
|
402
|
+
vals = np.array(
|
403
|
+
[-np.inf, -4, -3.5, -2.3, -0.0, 0.0, 1, 4.2, np.inf], np.float64
|
404
|
+
)
|
405
|
+
reference = np.array(
|
406
|
+
[np.nan, np.nan, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0], np.float64
|
407
|
+
)
|
408
|
+
assert_array_equal(cephes.gammasgn(vals), reference)
|
409
|
+
|
410
|
+
def test_gdtr(self):
|
411
|
+
assert_equal(cephes.gdtr(1,1,0),0.0)
|
412
|
+
|
413
|
+
def test_gdtr_inf(self):
|
414
|
+
assert_equal(cephes.gdtr(1,1,np.inf),1.0)
|
415
|
+
|
416
|
+
def test_gdtrc(self):
|
417
|
+
assert_equal(cephes.gdtrc(1,1,0),1.0)
|
418
|
+
|
419
|
+
def test_gdtria(self):
|
420
|
+
assert_equal(cephes.gdtria(0,1,1),0.0)
|
421
|
+
|
422
|
+
def test_gdtrib(self):
|
423
|
+
cephes.gdtrib(1,0,1)
|
424
|
+
# assert_equal(cephes.gdtrib(1,0,1),5.0)
|
425
|
+
|
426
|
+
def test_gdtrix(self):
|
427
|
+
cephes.gdtrix(1,1,.1)
|
428
|
+
|
429
|
+
def test_hankel1(self):
|
430
|
+
cephes.hankel1(1,1)
|
431
|
+
|
432
|
+
def test_hankel1e(self):
|
433
|
+
cephes.hankel1e(1,1)
|
434
|
+
|
435
|
+
def test_hankel2(self):
|
436
|
+
cephes.hankel2(1,1)
|
437
|
+
|
438
|
+
def test_hankel2e(self):
|
439
|
+
cephes.hankel2e(1,1)
|
440
|
+
|
441
|
+
def test_hyp1f1(self):
|
442
|
+
assert_approx_equal(cephes.hyp1f1(1,1,1), exp(1.0))
|
443
|
+
assert_approx_equal(cephes.hyp1f1(3,4,-6), 0.026056422099537251095)
|
444
|
+
cephes.hyp1f1(1,1,1)
|
445
|
+
|
446
|
+
def test_hyp2f1(self):
|
447
|
+
assert_equal(cephes.hyp2f1(1,1,1,0),1.0)
|
448
|
+
|
449
|
+
def test_i0(self):
|
450
|
+
assert_equal(cephes.i0(0),1.0)
|
451
|
+
|
452
|
+
def test_i0e(self):
|
453
|
+
assert_equal(cephes.i0e(0),1.0)
|
454
|
+
|
455
|
+
def test_i1(self):
|
456
|
+
assert_equal(cephes.i1(0),0.0)
|
457
|
+
|
458
|
+
def test_i1e(self):
|
459
|
+
assert_equal(cephes.i1e(0),0.0)
|
460
|
+
|
461
|
+
def test_it2i0k0(self):
|
462
|
+
cephes.it2i0k0(1)
|
463
|
+
|
464
|
+
def test_it2j0y0(self):
|
465
|
+
cephes.it2j0y0(1)
|
466
|
+
|
467
|
+
def test_it2struve0(self):
|
468
|
+
cephes.it2struve0(1)
|
469
|
+
|
470
|
+
def test_itairy(self):
|
471
|
+
cephes.itairy(1)
|
472
|
+
|
473
|
+
def test_iti0k0(self):
|
474
|
+
assert_equal(cephes.iti0k0(0),(0.0,0.0))
|
475
|
+
|
476
|
+
def test_itj0y0(self):
|
477
|
+
assert_equal(cephes.itj0y0(0),(0.0,0.0))
|
478
|
+
|
479
|
+
def test_itmodstruve0(self):
|
480
|
+
assert_equal(cephes.itmodstruve0(0),0.0)
|
481
|
+
|
482
|
+
def test_itstruve0(self):
|
483
|
+
assert_equal(cephes.itstruve0(0),0.0)
|
484
|
+
|
485
|
+
def test_iv(self):
|
486
|
+
assert_equal(cephes.iv(1,0),0.0)
|
487
|
+
|
488
|
+
def test_ive(self):
|
489
|
+
assert_equal(cephes.ive(1,0),0.0)
|
490
|
+
|
491
|
+
def test_j0(self):
|
492
|
+
assert_equal(cephes.j0(0),1.0)
|
493
|
+
|
494
|
+
def test_j1(self):
|
495
|
+
assert_equal(cephes.j1(0),0.0)
|
496
|
+
|
497
|
+
def test_jn(self):
|
498
|
+
assert_equal(cephes.jn(0,0),1.0)
|
499
|
+
|
500
|
+
def test_jv(self):
|
501
|
+
assert_equal(cephes.jv(0,0),1.0)
|
502
|
+
|
503
|
+
def test_jve(self):
|
504
|
+
assert_equal(cephes.jve(0,0),1.0)
|
505
|
+
|
506
|
+
def test_k0(self):
|
507
|
+
cephes.k0(2)
|
508
|
+
|
509
|
+
def test_k0e(self):
|
510
|
+
cephes.k0e(2)
|
511
|
+
|
512
|
+
def test_k1(self):
|
513
|
+
cephes.k1(2)
|
514
|
+
|
515
|
+
def test_k1e(self):
|
516
|
+
cephes.k1e(2)
|
517
|
+
|
518
|
+
def test_kei(self):
|
519
|
+
cephes.kei(2)
|
520
|
+
|
521
|
+
def test_keip(self):
|
522
|
+
assert_equal(cephes.keip(0),0.0)
|
523
|
+
|
524
|
+
def test_ker(self):
|
525
|
+
cephes.ker(2)
|
526
|
+
|
527
|
+
def test_kerp(self):
|
528
|
+
cephes.kerp(2)
|
529
|
+
|
530
|
+
def test_kelvin(self):
|
531
|
+
cephes.kelvin(2)
|
532
|
+
|
533
|
+
def test_kn(self):
|
534
|
+
cephes.kn(1,1)
|
535
|
+
|
536
|
+
def test_kolmogi(self):
|
537
|
+
assert_equal(cephes.kolmogi(1),0.0)
|
538
|
+
assert_(np.isnan(cephes.kolmogi(np.nan)))
|
539
|
+
|
540
|
+
def test_kolmogorov(self):
|
541
|
+
assert_equal(cephes.kolmogorov(0), 1.0)
|
542
|
+
|
543
|
+
def test_kolmogp(self):
|
544
|
+
assert_equal(cephes._kolmogp(0), -0.0)
|
545
|
+
|
546
|
+
def test_kolmogc(self):
|
547
|
+
assert_equal(cephes._kolmogc(0), 0.0)
|
548
|
+
|
549
|
+
def test_kolmogci(self):
|
550
|
+
assert_equal(cephes._kolmogci(0), 0.0)
|
551
|
+
assert_(np.isnan(cephes._kolmogci(np.nan)))
|
552
|
+
|
553
|
+
def test_kv(self):
|
554
|
+
cephes.kv(1,1)
|
555
|
+
|
556
|
+
def test_kve(self):
|
557
|
+
cephes.kve(1,1)
|
558
|
+
|
559
|
+
def test_log1p(self):
|
560
|
+
log1p = cephes.log1p
|
561
|
+
assert_equal(log1p(0), 0.0)
|
562
|
+
assert_equal(log1p(-1), -np.inf)
|
563
|
+
assert_equal(log1p(-2), np.nan)
|
564
|
+
assert_equal(log1p(np.inf), np.inf)
|
565
|
+
|
566
|
+
def test_log1p_complex(self):
|
567
|
+
log1p = cephes.log1p
|
568
|
+
c = complex
|
569
|
+
assert_equal(log1p(0 + 0j), 0 + 0j)
|
570
|
+
assert_equal(log1p(c(-1, 0)), c(-np.inf, 0))
|
571
|
+
with suppress_warnings() as sup:
|
572
|
+
sup.filter(RuntimeWarning, "invalid value encountered in multiply")
|
573
|
+
assert_allclose(log1p(c(1, np.inf)), c(np.inf, np.pi/2))
|
574
|
+
assert_equal(log1p(c(1, np.nan)), c(np.nan, np.nan))
|
575
|
+
assert_allclose(log1p(c(-np.inf, 1)), c(np.inf, np.pi))
|
576
|
+
assert_equal(log1p(c(np.inf, 1)), c(np.inf, 0))
|
577
|
+
assert_allclose(log1p(c(-np.inf, np.inf)), c(np.inf, 3*np.pi/4))
|
578
|
+
assert_allclose(log1p(c(np.inf, np.inf)), c(np.inf, np.pi/4))
|
579
|
+
assert_equal(log1p(c(np.inf, np.nan)), c(np.inf, np.nan))
|
580
|
+
assert_equal(log1p(c(-np.inf, np.nan)), c(np.inf, np.nan))
|
581
|
+
assert_equal(log1p(c(np.nan, np.inf)), c(np.inf, np.nan))
|
582
|
+
assert_equal(log1p(c(np.nan, 1)), c(np.nan, np.nan))
|
583
|
+
assert_equal(log1p(c(np.nan, np.nan)), c(np.nan, np.nan))
|
584
|
+
|
585
|
+
def test_lpmv(self):
|
586
|
+
assert_equal(cephes.lpmv(0,0,1),1.0)
|
587
|
+
|
588
|
+
def test_mathieu_a(self):
|
589
|
+
assert_equal(cephes.mathieu_a(1,0),1.0)
|
590
|
+
|
591
|
+
def test_mathieu_b(self):
|
592
|
+
assert_equal(cephes.mathieu_b(1,0),1.0)
|
593
|
+
|
594
|
+
def test_mathieu_cem(self):
|
595
|
+
assert_equal(cephes.mathieu_cem(1,0,0),(1.0,0.0))
|
596
|
+
|
597
|
+
# Test AMS 20.2.27
|
598
|
+
@np.vectorize
|
599
|
+
def ce_smallq(m, q, z):
|
600
|
+
z *= np.pi/180
|
601
|
+
if m == 0:
|
602
|
+
# + O(q^2)
|
603
|
+
return 2**(-0.5) * (1 - .5*q*cos(2*z))
|
604
|
+
elif m == 1:
|
605
|
+
# + O(q^2)
|
606
|
+
return cos(z) - q/8 * cos(3*z)
|
607
|
+
elif m == 2:
|
608
|
+
# + O(q^2)
|
609
|
+
return cos(2*z) - q*(cos(4*z)/12 - 1/4)
|
610
|
+
else:
|
611
|
+
# + O(q^2)
|
612
|
+
return cos(m*z) - q*(cos((m+2)*z)/(4*(m+1)) - cos((m-2)*z)/(4*(m-1)))
|
613
|
+
m = np.arange(0, 100)
|
614
|
+
q = np.r_[0, np.logspace(-30, -9, 10)]
|
615
|
+
assert_allclose(cephes.mathieu_cem(m[:,None], q[None,:], 0.123)[0],
|
616
|
+
ce_smallq(m[:,None], q[None,:], 0.123),
|
617
|
+
rtol=1e-14, atol=0)
|
618
|
+
|
619
|
+
def test_mathieu_sem(self):
|
620
|
+
assert_equal(cephes.mathieu_sem(1,0,0),(0.0,1.0))
|
621
|
+
|
622
|
+
# Test AMS 20.2.27
|
623
|
+
@np.vectorize
|
624
|
+
def se_smallq(m, q, z):
|
625
|
+
z *= np.pi/180
|
626
|
+
if m == 1:
|
627
|
+
# + O(q^2)
|
628
|
+
return sin(z) - q/8 * sin(3*z)
|
629
|
+
elif m == 2:
|
630
|
+
# + O(q^2)
|
631
|
+
return sin(2*z) - q*sin(4*z)/12
|
632
|
+
else:
|
633
|
+
# + O(q^2)
|
634
|
+
return sin(m*z) - q*(sin((m+2)*z)/(4*(m+1)) - sin((m-2)*z)/(4*(m-1)))
|
635
|
+
m = np.arange(1, 100)
|
636
|
+
q = np.r_[0, np.logspace(-30, -9, 10)]
|
637
|
+
assert_allclose(cephes.mathieu_sem(m[:,None], q[None,:], 0.123)[0],
|
638
|
+
se_smallq(m[:,None], q[None,:], 0.123),
|
639
|
+
rtol=1e-14, atol=0)
|
640
|
+
|
641
|
+
def test_mathieu_modcem1(self):
|
642
|
+
assert_equal(cephes.mathieu_modcem1(1,0,0),(0.0,0.0))
|
643
|
+
|
644
|
+
def test_mathieu_modcem2(self):
|
645
|
+
cephes.mathieu_modcem2(1,1,1)
|
646
|
+
|
647
|
+
# Test reflection relation AMS 20.6.19
|
648
|
+
m = np.arange(0, 4)[:,None,None]
|
649
|
+
q = np.r_[np.logspace(-2, 2, 10)][None,:,None]
|
650
|
+
z = np.linspace(0, 1, 7)[None,None,:]
|
651
|
+
|
652
|
+
y1 = cephes.mathieu_modcem2(m, q, -z)[0]
|
653
|
+
|
654
|
+
fr = -cephes.mathieu_modcem2(m, q, 0)[0] / cephes.mathieu_modcem1(m, q, 0)[0]
|
655
|
+
y2 = (-cephes.mathieu_modcem2(m, q, z)[0]
|
656
|
+
- 2*fr*cephes.mathieu_modcem1(m, q, z)[0])
|
657
|
+
|
658
|
+
assert_allclose(y1, y2, rtol=1e-10)
|
659
|
+
|
660
|
+
def test_mathieu_modsem1(self):
|
661
|
+
assert_equal(cephes.mathieu_modsem1(1,0,0),(0.0,0.0))
|
662
|
+
|
663
|
+
def test_mathieu_modsem2(self):
|
664
|
+
cephes.mathieu_modsem2(1,1,1)
|
665
|
+
|
666
|
+
# Test reflection relation AMS 20.6.20
|
667
|
+
m = np.arange(1, 4)[:,None,None]
|
668
|
+
q = np.r_[np.logspace(-2, 2, 10)][None,:,None]
|
669
|
+
z = np.linspace(0, 1, 7)[None,None,:]
|
670
|
+
|
671
|
+
y1 = cephes.mathieu_modsem2(m, q, -z)[0]
|
672
|
+
fr = cephes.mathieu_modsem2(m, q, 0)[1] / cephes.mathieu_modsem1(m, q, 0)[1]
|
673
|
+
y2 = (cephes.mathieu_modsem2(m, q, z)[0]
|
674
|
+
- 2*fr*cephes.mathieu_modsem1(m, q, z)[0])
|
675
|
+
assert_allclose(y1, y2, rtol=1e-10)
|
676
|
+
|
677
|
+
def test_mathieu_overflow(self):
|
678
|
+
# Check that these return NaNs instead of causing a SEGV
|
679
|
+
assert_equal(cephes.mathieu_cem(10000, 0, 1.3), (np.nan, np.nan))
|
680
|
+
assert_equal(cephes.mathieu_sem(10000, 0, 1.3), (np.nan, np.nan))
|
681
|
+
assert_equal(cephes.mathieu_cem(10000, 1.5, 1.3), (np.nan, np.nan))
|
682
|
+
assert_equal(cephes.mathieu_sem(10000, 1.5, 1.3), (np.nan, np.nan))
|
683
|
+
assert_equal(cephes.mathieu_modcem1(10000, 1.5, 1.3), (np.nan, np.nan))
|
684
|
+
assert_equal(cephes.mathieu_modsem1(10000, 1.5, 1.3), (np.nan, np.nan))
|
685
|
+
assert_equal(cephes.mathieu_modcem2(10000, 1.5, 1.3), (np.nan, np.nan))
|
686
|
+
assert_equal(cephes.mathieu_modsem2(10000, 1.5, 1.3), (np.nan, np.nan))
|
687
|
+
|
688
|
+
def test_mathieu_ticket_1847(self):
|
689
|
+
# Regression test --- this call had some out-of-bounds access
|
690
|
+
# and could return nan occasionally
|
691
|
+
for k in range(60):
|
692
|
+
v = cephes.mathieu_modsem2(2, 100, -1)
|
693
|
+
# Values from ACM TOMS 804 (derivate by numerical differentiation)
|
694
|
+
assert_allclose(v[0], 0.1431742913063671074347, rtol=1e-10)
|
695
|
+
assert_allclose(v[1], 0.9017807375832909144719, rtol=1e-4)
|
696
|
+
|
697
|
+
def test_modfresnelm(self):
|
698
|
+
cephes.modfresnelm(0)
|
699
|
+
|
700
|
+
def test_modfresnelp(self):
|
701
|
+
cephes.modfresnelp(0)
|
702
|
+
|
703
|
+
def test_modstruve(self):
|
704
|
+
assert_equal(cephes.modstruve(1,0),0.0)
|
705
|
+
|
706
|
+
def test_nbdtr(self):
|
707
|
+
assert_equal(cephes.nbdtr(1,1,1),1.0)
|
708
|
+
|
709
|
+
def test_nbdtrc(self):
|
710
|
+
assert_equal(cephes.nbdtrc(1,1,1),0.0)
|
711
|
+
|
712
|
+
def test_nbdtri(self):
|
713
|
+
assert_equal(cephes.nbdtri(1,1,1),1.0)
|
714
|
+
|
715
|
+
def test_nbdtrik(self):
|
716
|
+
cephes.nbdtrik(1,.4,.5)
|
717
|
+
|
718
|
+
def test_nbdtrin(self):
|
719
|
+
assert_equal(cephes.nbdtrin(1,0,0),5.0)
|
720
|
+
|
721
|
+
def test_ncfdtr(self):
|
722
|
+
assert_equal(cephes.ncfdtr(1,1,1,0),0.0)
|
723
|
+
|
724
|
+
def test_ncfdtri(self):
|
725
|
+
assert_equal(cephes.ncfdtri(1, 1, 1, 0), 0.0)
|
726
|
+
f = [0.5, 1, 1.5]
|
727
|
+
p = cephes.ncfdtr(2, 3, 1.5, f)
|
728
|
+
assert_allclose(cephes.ncfdtri(2, 3, 1.5, p), f)
|
729
|
+
|
730
|
+
@pytest.mark.xfail(
|
731
|
+
reason=(
|
732
|
+
"ncfdtr uses a Boost math implementation but ncfdtridfd"
|
733
|
+
"inverts the less accurate cdflib implementation of ncfdtr."
|
734
|
+
)
|
735
|
+
)
|
736
|
+
def test_ncfdtridfd(self):
|
737
|
+
dfd = [1, 2, 3]
|
738
|
+
p = cephes.ncfdtr(2, dfd, 0.25, 15)
|
739
|
+
assert_allclose(cephes.ncfdtridfd(2, p, 0.25, 15), dfd)
|
740
|
+
|
741
|
+
@pytest.mark.xfail(
|
742
|
+
reason=(
|
743
|
+
"ncfdtr uses a Boost math implementation but ncfdtridfn"
|
744
|
+
"inverts the less accurate cdflib implementation of ncfdtr."
|
745
|
+
)
|
746
|
+
)
|
747
|
+
def test_ncfdtridfn(self):
|
748
|
+
dfn = [0.1, 1, 2, 3, 1e4]
|
749
|
+
p = cephes.ncfdtr(dfn, 2, 0.25, 15)
|
750
|
+
assert_allclose(cephes.ncfdtridfn(p, 2, 0.25, 15), dfn, rtol=1e-5)
|
751
|
+
|
752
|
+
@pytest.mark.xfail(
|
753
|
+
reason=(
|
754
|
+
"ncfdtr uses a Boost math implementation but ncfdtrinc"
|
755
|
+
"inverts the less accurate cdflib implementation of ncfdtr."
|
756
|
+
)
|
757
|
+
)
|
758
|
+
def test_ncfdtrinc(self):
|
759
|
+
nc = [0.5, 1.5, 2.0]
|
760
|
+
p = cephes.ncfdtr(2, 3, nc, 15)
|
761
|
+
assert_allclose(cephes.ncfdtrinc(2, 3, p, 15), nc)
|
762
|
+
|
763
|
+
def test_nctdtr(self):
|
764
|
+
assert_equal(cephes.nctdtr(1,0,0),0.5)
|
765
|
+
assert_equal(cephes.nctdtr(9, 65536, 45), 0.0)
|
766
|
+
|
767
|
+
assert_approx_equal(cephes.nctdtr(np.inf, 1., 1.), 0.5, 5)
|
768
|
+
assert_(np.isnan(cephes.nctdtr(2., np.inf, 10.)))
|
769
|
+
assert_approx_equal(cephes.nctdtr(2., 1., np.inf), 1.)
|
770
|
+
|
771
|
+
assert_(np.isnan(cephes.nctdtr(np.nan, 1., 1.)))
|
772
|
+
assert_(np.isnan(cephes.nctdtr(2., np.nan, 1.)))
|
773
|
+
assert_(np.isnan(cephes.nctdtr(2., 1., np.nan)))
|
774
|
+
|
775
|
+
def test_nctdtridf(self):
|
776
|
+
cephes.nctdtridf(1,0.5,0)
|
777
|
+
|
778
|
+
def test_nctdtrinc(self):
|
779
|
+
cephes.nctdtrinc(1,0,0)
|
780
|
+
|
781
|
+
def test_nctdtrit(self):
|
782
|
+
cephes.nctdtrit(.1,0.2,.5)
|
783
|
+
|
784
|
+
def test_nrdtrimn(self):
|
785
|
+
assert_approx_equal(cephes.nrdtrimn(0.5,1,1),1.0)
|
786
|
+
|
787
|
+
def test_nrdtrisd(self):
|
788
|
+
assert_allclose(cephes.nrdtrisd(0.5,0.5,0.5), 0.0,
|
789
|
+
atol=0, rtol=0)
|
790
|
+
|
791
|
+
def test_obl_ang1(self):
|
792
|
+
cephes.obl_ang1(1,1,1,0)
|
793
|
+
|
794
|
+
def test_obl_ang1_cv(self):
|
795
|
+
result = cephes.obl_ang1_cv(1,1,1,1,0)
|
796
|
+
assert_almost_equal(result[0],1.0)
|
797
|
+
assert_almost_equal(result[1],0.0)
|
798
|
+
|
799
|
+
def test_obl_cv(self):
|
800
|
+
assert_equal(cephes.obl_cv(1,1,0),2.0)
|
801
|
+
|
802
|
+
def test_obl_rad1(self):
|
803
|
+
cephes.obl_rad1(1,1,1,0)
|
804
|
+
|
805
|
+
def test_obl_rad1_cv(self):
|
806
|
+
cephes.obl_rad1_cv(1,1,1,1,0)
|
807
|
+
|
808
|
+
def test_obl_rad2(self):
|
809
|
+
cephes.obl_rad2(1,1,1,0)
|
810
|
+
|
811
|
+
def test_obl_rad2_cv(self):
|
812
|
+
cephes.obl_rad2_cv(1,1,1,1,0)
|
813
|
+
|
814
|
+
def test_pbdv(self):
|
815
|
+
assert_equal(cephes.pbdv(1,0),(0.0,1.0))
|
816
|
+
|
817
|
+
def test_pbvv(self):
|
818
|
+
cephes.pbvv(1,0)
|
819
|
+
|
820
|
+
def test_pbwa(self):
|
821
|
+
cephes.pbwa(1,0)
|
822
|
+
|
823
|
+
def test_pdtr(self):
|
824
|
+
val = cephes.pdtr(0, 1)
|
825
|
+
assert_almost_equal(val, np.exp(-1))
|
826
|
+
# Edge case: m = 0.
|
827
|
+
val = cephes.pdtr([0, 1, 2], 0)
|
828
|
+
assert_array_equal(val, [1, 1, 1])
|
829
|
+
|
830
|
+
def test_pdtrc(self):
|
831
|
+
val = cephes.pdtrc(0, 1)
|
832
|
+
assert_almost_equal(val, 1 - np.exp(-1))
|
833
|
+
# Edge case: m = 0.
|
834
|
+
val = cephes.pdtrc([0, 1, 2], 0.0)
|
835
|
+
assert_array_equal(val, [0, 0, 0])
|
836
|
+
|
837
|
+
def test_pdtri(self):
|
838
|
+
with suppress_warnings() as sup:
|
839
|
+
sup.filter(RuntimeWarning, "floating point number truncated to an integer")
|
840
|
+
cephes.pdtri(0.5,0.5)
|
841
|
+
|
842
|
+
def test_pdtrik(self):
|
843
|
+
k = cephes.pdtrik(0.5, 1)
|
844
|
+
assert_almost_equal(cephes.gammaincc(k + 1, 1), 0.5)
|
845
|
+
# Edge case: m = 0 or very small.
|
846
|
+
k = cephes.pdtrik([[0], [0.25], [0.95]], [0, 1e-20, 1e-6])
|
847
|
+
assert_array_equal(k, np.zeros((3, 3)))
|
848
|
+
|
849
|
+
def test_pro_ang1(self):
|
850
|
+
cephes.pro_ang1(1,1,1,0)
|
851
|
+
|
852
|
+
def test_pro_ang1_cv(self):
|
853
|
+
assert_array_almost_equal(cephes.pro_ang1_cv(1,1,1,1,0),
|
854
|
+
array((1.0,0.0)))
|
855
|
+
|
856
|
+
def test_pro_cv(self):
|
857
|
+
assert_equal(cephes.pro_cv(1,1,0),2.0)
|
858
|
+
|
859
|
+
def test_pro_rad1(self):
|
860
|
+
cephes.pro_rad1(1,1,1,0.1)
|
861
|
+
|
862
|
+
def test_pro_rad1_cv(self):
|
863
|
+
cephes.pro_rad1_cv(1,1,1,1,0)
|
864
|
+
|
865
|
+
def test_pro_rad2(self):
|
866
|
+
cephes.pro_rad2(1,1,1,0)
|
867
|
+
|
868
|
+
def test_pro_rad2_cv(self):
|
869
|
+
cephes.pro_rad2_cv(1,1,1,1,0)
|
870
|
+
|
871
|
+
def test_psi(self):
|
872
|
+
cephes.psi(1)
|
873
|
+
|
874
|
+
def test_radian(self):
|
875
|
+
assert_equal(cephes.radian(0,0,0),0)
|
876
|
+
|
877
|
+
def test_rgamma(self):
|
878
|
+
assert_equal(cephes.rgamma(1),1.0)
|
879
|
+
|
880
|
+
def test_round(self):
|
881
|
+
assert_equal(cephes.round(3.4),3.0)
|
882
|
+
assert_equal(cephes.round(-3.4),-3.0)
|
883
|
+
assert_equal(cephes.round(3.6),4.0)
|
884
|
+
assert_equal(cephes.round(-3.6),-4.0)
|
885
|
+
assert_equal(cephes.round(3.5),4.0)
|
886
|
+
assert_equal(cephes.round(-3.5),-4.0)
|
887
|
+
|
888
|
+
def test_shichi(self):
|
889
|
+
cephes.shichi(1)
|
890
|
+
|
891
|
+
def test_sici(self):
|
892
|
+
cephes.sici(1)
|
893
|
+
|
894
|
+
s, c = cephes.sici(np.inf)
|
895
|
+
assert_almost_equal(s, np.pi * 0.5)
|
896
|
+
assert_almost_equal(c, 0)
|
897
|
+
|
898
|
+
s, c = cephes.sici(-np.inf)
|
899
|
+
assert_almost_equal(s, -np.pi * 0.5)
|
900
|
+
assert_(np.isnan(c), "cosine integral(-inf) is not nan")
|
901
|
+
|
902
|
+
def test_sindg(self):
|
903
|
+
assert_equal(cephes.sindg(90),1.0)
|
904
|
+
|
905
|
+
def test_smirnov(self):
|
906
|
+
assert_equal(cephes.smirnov(1,.1),0.9)
|
907
|
+
assert_(np.isnan(cephes.smirnov(1,np.nan)))
|
908
|
+
|
909
|
+
def test_smirnovp(self):
|
910
|
+
assert_equal(cephes._smirnovp(1, .1), -1)
|
911
|
+
assert_equal(cephes._smirnovp(2, 0.75), -2*(0.25)**(2-1))
|
912
|
+
assert_equal(cephes._smirnovp(3, 0.75), -3*(0.25)**(3-1))
|
913
|
+
assert_(np.isnan(cephes._smirnovp(1, np.nan)))
|
914
|
+
|
915
|
+
def test_smirnovc(self):
|
916
|
+
assert_equal(cephes._smirnovc(1,.1),0.1)
|
917
|
+
assert_(np.isnan(cephes._smirnovc(1,np.nan)))
|
918
|
+
x10 = np.linspace(0, 1, 11, endpoint=True)
|
919
|
+
assert_almost_equal(cephes._smirnovc(3, x10), 1-cephes.smirnov(3, x10))
|
920
|
+
x4 = np.linspace(0, 1, 5, endpoint=True)
|
921
|
+
assert_almost_equal(cephes._smirnovc(4, x4), 1-cephes.smirnov(4, x4))
|
922
|
+
|
923
|
+
def test_smirnovi(self):
|
924
|
+
assert_almost_equal(cephes.smirnov(1,cephes.smirnovi(1,0.4)),0.4)
|
925
|
+
assert_almost_equal(cephes.smirnov(1,cephes.smirnovi(1,0.6)),0.6)
|
926
|
+
assert_(np.isnan(cephes.smirnovi(1,np.nan)))
|
927
|
+
|
928
|
+
def test_smirnovci(self):
|
929
|
+
assert_almost_equal(cephes._smirnovc(1,cephes._smirnovci(1,0.4)),0.4)
|
930
|
+
assert_almost_equal(cephes._smirnovc(1,cephes._smirnovci(1,0.6)),0.6)
|
931
|
+
assert_(np.isnan(cephes._smirnovci(1,np.nan)))
|
932
|
+
|
933
|
+
def test_spence(self):
|
934
|
+
assert_equal(cephes.spence(1),0.0)
|
935
|
+
|
936
|
+
def test_stdtr(self):
|
937
|
+
assert_equal(cephes.stdtr(1,0),0.5)
|
938
|
+
assert_almost_equal(cephes.stdtr(1,1), 0.75)
|
939
|
+
assert_almost_equal(cephes.stdtr(1,2), 0.852416382349)
|
940
|
+
|
941
|
+
def test_stdtridf(self):
|
942
|
+
cephes.stdtridf(0.7,1)
|
943
|
+
|
944
|
+
def test_stdtrit(self):
|
945
|
+
cephes.stdtrit(1,0.7)
|
946
|
+
|
947
|
+
def test_struve(self):
|
948
|
+
assert_equal(cephes.struve(0,0),0.0)
|
949
|
+
|
950
|
+
def test_tandg(self):
|
951
|
+
assert_equal(cephes.tandg(45),1.0)
|
952
|
+
|
953
|
+
def test_tklmbda(self):
|
954
|
+
assert_almost_equal(cephes.tklmbda(1,1),1.0)
|
955
|
+
|
956
|
+
def test_y0(self):
|
957
|
+
cephes.y0(1)
|
958
|
+
|
959
|
+
def test_y1(self):
|
960
|
+
cephes.y1(1)
|
961
|
+
|
962
|
+
def test_yn(self):
|
963
|
+
cephes.yn(1,1)
|
964
|
+
|
965
|
+
def test_yv(self):
|
966
|
+
cephes.yv(1,1)
|
967
|
+
|
968
|
+
def test_yve(self):
|
969
|
+
cephes.yve(1,1)
|
970
|
+
|
971
|
+
def test_wofz(self):
|
972
|
+
z = [complex(624.2,-0.26123), complex(-0.4,3.), complex(0.6,2.),
|
973
|
+
complex(-1.,1.), complex(-1.,-9.), complex(-1.,9.),
|
974
|
+
complex(-0.0000000234545,1.1234), complex(-3.,5.1),
|
975
|
+
complex(-53,30.1), complex(0.0,0.12345),
|
976
|
+
complex(11,1), complex(-22,-2), complex(9,-28),
|
977
|
+
complex(21,-33), complex(1e5,1e5), complex(1e14,1e14)
|
978
|
+
]
|
979
|
+
w = [
|
980
|
+
complex(-3.78270245518980507452677445620103199303131110e-7,
|
981
|
+
0.000903861276433172057331093754199933411710053155),
|
982
|
+
complex(0.1764906227004816847297495349730234591778719532788,
|
983
|
+
-0.02146550539468457616788719893991501311573031095617),
|
984
|
+
complex(0.2410250715772692146133539023007113781272362309451,
|
985
|
+
0.06087579663428089745895459735240964093522265589350),
|
986
|
+
complex(0.30474420525691259245713884106959496013413834051768,
|
987
|
+
-0.20821893820283162728743734725471561394145872072738),
|
988
|
+
complex(7.317131068972378096865595229600561710140617977e34,
|
989
|
+
8.321873499714402777186848353320412813066170427e34),
|
990
|
+
complex(0.0615698507236323685519612934241429530190806818395,
|
991
|
+
-0.00676005783716575013073036218018565206070072304635),
|
992
|
+
complex(0.3960793007699874918961319170187598400134746631,
|
993
|
+
-5.593152259116644920546186222529802777409274656e-9),
|
994
|
+
complex(0.08217199226739447943295069917990417630675021771804,
|
995
|
+
-0.04701291087643609891018366143118110965272615832184),
|
996
|
+
complex(0.00457246000350281640952328010227885008541748668738,
|
997
|
+
-0.00804900791411691821818731763401840373998654987934),
|
998
|
+
complex(0.8746342859608052666092782112565360755791467973338452,
|
999
|
+
0.),
|
1000
|
+
complex(0.00468190164965444174367477874864366058339647648741,
|
1001
|
+
0.0510735563901306197993676329845149741675029197050),
|
1002
|
+
complex(-0.0023193175200187620902125853834909543869428763219,
|
1003
|
+
-0.025460054739731556004902057663500272721780776336),
|
1004
|
+
complex(9.11463368405637174660562096516414499772662584e304,
|
1005
|
+
3.97101807145263333769664875189354358563218932e305),
|
1006
|
+
complex(-4.4927207857715598976165541011143706155432296e281,
|
1007
|
+
-2.8019591213423077494444700357168707775769028e281),
|
1008
|
+
complex(2.820947917809305132678577516325951485807107151e-6,
|
1009
|
+
2.820947917668257736791638444590253942253354058e-6),
|
1010
|
+
complex(2.82094791773878143474039725787438662716372268e-15,
|
1011
|
+
2.82094791773878143474039725773333923127678361e-15)
|
1012
|
+
]
|
1013
|
+
assert_func_equal(cephes.wofz, w, z, rtol=1e-13)
|
1014
|
+
|
1015
|
+
|
1016
|
+
class TestAiry:
|
1017
|
+
def test_airy(self):
|
1018
|
+
# This tests the airy function to ensure 8 place accuracy in computation
|
1019
|
+
|
1020
|
+
x = special.airy(.99)
|
1021
|
+
assert_array_almost_equal(
|
1022
|
+
x,
|
1023
|
+
array([0.13689066,-0.16050153,1.19815925,0.92046818]),
|
1024
|
+
8,
|
1025
|
+
)
|
1026
|
+
x = special.airy(.41)
|
1027
|
+
assert_array_almost_equal(
|
1028
|
+
x,
|
1029
|
+
array([0.25238916,-.23480512,0.80686202,0.51053919]),
|
1030
|
+
8,
|
1031
|
+
)
|
1032
|
+
x = special.airy(-.36)
|
1033
|
+
assert_array_almost_equal(
|
1034
|
+
x,
|
1035
|
+
array([0.44508477,-0.23186773,0.44939534,0.48105354]),
|
1036
|
+
8,
|
1037
|
+
)
|
1038
|
+
|
1039
|
+
def test_airye(self):
|
1040
|
+
a = special.airye(0.01)
|
1041
|
+
b = special.airy(0.01)
|
1042
|
+
b1 = [None]*4
|
1043
|
+
for n in range(2):
|
1044
|
+
b1[n] = b[n]*exp(2.0/3.0*0.01*sqrt(0.01))
|
1045
|
+
for n in range(2,4):
|
1046
|
+
b1[n] = b[n]*exp(-abs(real(2.0/3.0*0.01*sqrt(0.01))))
|
1047
|
+
assert_array_almost_equal(a,b1,6)
|
1048
|
+
|
1049
|
+
def test_bi_zeros(self):
|
1050
|
+
bi = special.bi_zeros(2)
|
1051
|
+
bia = (array([-1.17371322, -3.2710930]),
|
1052
|
+
array([-2.29443968, -4.07315509]),
|
1053
|
+
array([-0.45494438, 0.39652284]),
|
1054
|
+
array([0.60195789, -0.76031014]))
|
1055
|
+
assert_array_almost_equal(bi,bia,4)
|
1056
|
+
|
1057
|
+
bi = special.bi_zeros(5)
|
1058
|
+
assert_array_almost_equal(bi[0],array([-1.173713222709127,
|
1059
|
+
-3.271093302836352,
|
1060
|
+
-4.830737841662016,
|
1061
|
+
-6.169852128310251,
|
1062
|
+
-7.376762079367764]),11)
|
1063
|
+
|
1064
|
+
assert_array_almost_equal(bi[1],array([-2.294439682614122,
|
1065
|
+
-4.073155089071828,
|
1066
|
+
-5.512395729663599,
|
1067
|
+
-6.781294445990305,
|
1068
|
+
-7.940178689168587]),10)
|
1069
|
+
|
1070
|
+
assert_array_almost_equal(bi[2],array([-0.454944383639657,
|
1071
|
+
0.396522836094465,
|
1072
|
+
-0.367969161486959,
|
1073
|
+
0.349499116831805,
|
1074
|
+
-0.336026240133662]),11)
|
1075
|
+
|
1076
|
+
assert_array_almost_equal(bi[3],array([0.601957887976239,
|
1077
|
+
-0.760310141492801,
|
1078
|
+
0.836991012619261,
|
1079
|
+
-0.88947990142654,
|
1080
|
+
0.929983638568022]),10)
|
1081
|
+
|
1082
|
+
def test_ai_zeros(self):
|
1083
|
+
ai = special.ai_zeros(1)
|
1084
|
+
assert_array_almost_equal(ai,(array([-2.33810741]),
|
1085
|
+
array([-1.01879297]),
|
1086
|
+
array([0.5357]),
|
1087
|
+
array([0.7012])),4)
|
1088
|
+
|
1089
|
+
@pytest.mark.fail_slow(5)
|
1090
|
+
def test_ai_zeros_big(self):
|
1091
|
+
z, zp, ai_zpx, aip_zx = special.ai_zeros(50000)
|
1092
|
+
ai_z, aip_z, _, _ = special.airy(z)
|
1093
|
+
ai_zp, aip_zp, _, _ = special.airy(zp)
|
1094
|
+
|
1095
|
+
ai_envelope = 1/abs(z)**(1./4)
|
1096
|
+
aip_envelope = abs(zp)**(1./4)
|
1097
|
+
|
1098
|
+
# Check values
|
1099
|
+
assert_allclose(ai_zpx, ai_zp, rtol=1e-10)
|
1100
|
+
assert_allclose(aip_zx, aip_z, rtol=1e-10)
|
1101
|
+
|
1102
|
+
# Check they are zeros
|
1103
|
+
assert_allclose(ai_z/ai_envelope, 0, atol=1e-10, rtol=0)
|
1104
|
+
assert_allclose(aip_zp/aip_envelope, 0, atol=1e-10, rtol=0)
|
1105
|
+
|
1106
|
+
# Check first zeros, DLMF 9.9.1
|
1107
|
+
assert_allclose(z[:6],
|
1108
|
+
[-2.3381074105, -4.0879494441, -5.5205598281,
|
1109
|
+
-6.7867080901, -7.9441335871, -9.0226508533], rtol=1e-10)
|
1110
|
+
assert_allclose(zp[:6],
|
1111
|
+
[-1.0187929716, -3.2481975822, -4.8200992112,
|
1112
|
+
-6.1633073556, -7.3721772550, -8.4884867340], rtol=1e-10)
|
1113
|
+
|
1114
|
+
@pytest.mark.fail_slow(5)
|
1115
|
+
def test_bi_zeros_big(self):
|
1116
|
+
z, zp, bi_zpx, bip_zx = special.bi_zeros(50000)
|
1117
|
+
_, _, bi_z, bip_z = special.airy(z)
|
1118
|
+
_, _, bi_zp, bip_zp = special.airy(zp)
|
1119
|
+
|
1120
|
+
bi_envelope = 1/abs(z)**(1./4)
|
1121
|
+
bip_envelope = abs(zp)**(1./4)
|
1122
|
+
|
1123
|
+
# Check values
|
1124
|
+
assert_allclose(bi_zpx, bi_zp, rtol=1e-10)
|
1125
|
+
assert_allclose(bip_zx, bip_z, rtol=1e-10)
|
1126
|
+
|
1127
|
+
# Check they are zeros
|
1128
|
+
assert_allclose(bi_z/bi_envelope, 0, atol=1e-10, rtol=0)
|
1129
|
+
assert_allclose(bip_zp/bip_envelope, 0, atol=1e-10, rtol=0)
|
1130
|
+
|
1131
|
+
# Check first zeros, DLMF 9.9.2
|
1132
|
+
assert_allclose(z[:6],
|
1133
|
+
[-1.1737132227, -3.2710933028, -4.8307378417,
|
1134
|
+
-6.1698521283, -7.3767620794, -8.4919488465], rtol=1e-10)
|
1135
|
+
assert_allclose(zp[:6],
|
1136
|
+
[-2.2944396826, -4.0731550891, -5.5123957297,
|
1137
|
+
-6.7812944460, -7.9401786892, -9.0195833588], rtol=1e-10)
|
1138
|
+
|
1139
|
+
|
1140
|
+
class TestAssocLaguerre:
|
1141
|
+
def test_assoc_laguerre(self):
|
1142
|
+
a1 = special.genlaguerre(11,1)
|
1143
|
+
a2 = special.assoc_laguerre(.2,11,1)
|
1144
|
+
assert_array_almost_equal(a2,a1(.2),8)
|
1145
|
+
a2 = special.assoc_laguerre(1,11,1)
|
1146
|
+
assert_array_almost_equal(a2,a1(1),8)
|
1147
|
+
|
1148
|
+
|
1149
|
+
class TestBesselpoly:
|
1150
|
+
def test_besselpoly(self):
|
1151
|
+
pass
|
1152
|
+
|
1153
|
+
|
1154
|
+
class TestKelvin:
|
1155
|
+
def test_bei(self):
|
1156
|
+
mbei = special.bei(2)
|
1157
|
+
assert_almost_equal(mbei, 0.9722916273066613,5) # this may not be exact
|
1158
|
+
|
1159
|
+
def test_beip(self):
|
1160
|
+
mbeip = special.beip(2)
|
1161
|
+
assert_almost_equal(mbeip,0.91701361338403631,5) # this may not be exact
|
1162
|
+
|
1163
|
+
def test_ber(self):
|
1164
|
+
mber = special.ber(2)
|
1165
|
+
assert_almost_equal(mber,0.75173418271380821,5) # this may not be exact
|
1166
|
+
|
1167
|
+
def test_berp(self):
|
1168
|
+
mberp = special.berp(2)
|
1169
|
+
assert_almost_equal(mberp,-0.49306712470943909,5) # this may not be exact
|
1170
|
+
|
1171
|
+
def test_bei_zeros(self):
|
1172
|
+
# Abramowitz & Stegun, Table 9.12
|
1173
|
+
bi = special.bei_zeros(5)
|
1174
|
+
assert_array_almost_equal(bi,array([5.02622,
|
1175
|
+
9.45541,
|
1176
|
+
13.89349,
|
1177
|
+
18.33398,
|
1178
|
+
22.77544]),4)
|
1179
|
+
|
1180
|
+
def test_beip_zeros(self):
|
1181
|
+
bip = special.beip_zeros(5)
|
1182
|
+
assert_array_almost_equal(bip,array([3.772673304934953,
|
1183
|
+
8.280987849760042,
|
1184
|
+
12.742147523633703,
|
1185
|
+
17.193431752512542,
|
1186
|
+
21.641143941167325]),8)
|
1187
|
+
|
1188
|
+
def test_ber_zeros(self):
|
1189
|
+
ber = special.ber_zeros(5)
|
1190
|
+
assert_array_almost_equal(ber,array([2.84892,
|
1191
|
+
7.23883,
|
1192
|
+
11.67396,
|
1193
|
+
16.11356,
|
1194
|
+
20.55463]),4)
|
1195
|
+
|
1196
|
+
def test_berp_zeros(self):
|
1197
|
+
brp = special.berp_zeros(5)
|
1198
|
+
assert_array_almost_equal(brp,array([6.03871,
|
1199
|
+
10.51364,
|
1200
|
+
14.96844,
|
1201
|
+
19.41758,
|
1202
|
+
23.86430]),4)
|
1203
|
+
|
1204
|
+
def test_kelvin(self):
|
1205
|
+
mkelv = special.kelvin(2)
|
1206
|
+
assert_array_almost_equal(mkelv,(special.ber(2) + special.bei(2)*1j,
|
1207
|
+
special.ker(2) + special.kei(2)*1j,
|
1208
|
+
special.berp(2) + special.beip(2)*1j,
|
1209
|
+
special.kerp(2) + special.keip(2)*1j),8)
|
1210
|
+
|
1211
|
+
def test_kei(self):
|
1212
|
+
mkei = special.kei(2)
|
1213
|
+
assert_almost_equal(mkei,-0.20240006776470432,5)
|
1214
|
+
|
1215
|
+
def test_keip(self):
|
1216
|
+
mkeip = special.keip(2)
|
1217
|
+
assert_almost_equal(mkeip,0.21980790991960536,5)
|
1218
|
+
|
1219
|
+
def test_ker(self):
|
1220
|
+
mker = special.ker(2)
|
1221
|
+
assert_almost_equal(mker,-0.041664513991509472,5)
|
1222
|
+
|
1223
|
+
def test_kerp(self):
|
1224
|
+
mkerp = special.kerp(2)
|
1225
|
+
assert_almost_equal(mkerp,-0.10660096588105264,5)
|
1226
|
+
|
1227
|
+
def test_kei_zeros(self):
|
1228
|
+
kei = special.kei_zeros(5)
|
1229
|
+
assert_array_almost_equal(kei,array([3.91467,
|
1230
|
+
8.34422,
|
1231
|
+
12.78256,
|
1232
|
+
17.22314,
|
1233
|
+
21.66464]),4)
|
1234
|
+
|
1235
|
+
def test_keip_zeros(self):
|
1236
|
+
keip = special.keip_zeros(5)
|
1237
|
+
assert_array_almost_equal(keip,array([4.93181,
|
1238
|
+
9.40405,
|
1239
|
+
13.85827,
|
1240
|
+
18.30717,
|
1241
|
+
22.75379]),4)
|
1242
|
+
|
1243
|
+
# numbers come from 9.9 of A&S pg. 381
|
1244
|
+
def test_kelvin_zeros(self):
|
1245
|
+
tmp = special.kelvin_zeros(5)
|
1246
|
+
berz,beiz,kerz,keiz,berpz,beipz,kerpz,keipz = tmp
|
1247
|
+
assert_array_almost_equal(berz,array([2.84892,
|
1248
|
+
7.23883,
|
1249
|
+
11.67396,
|
1250
|
+
16.11356,
|
1251
|
+
20.55463]),4)
|
1252
|
+
assert_array_almost_equal(beiz,array([5.02622,
|
1253
|
+
9.45541,
|
1254
|
+
13.89349,
|
1255
|
+
18.33398,
|
1256
|
+
22.77544]),4)
|
1257
|
+
assert_array_almost_equal(kerz,array([1.71854,
|
1258
|
+
6.12728,
|
1259
|
+
10.56294,
|
1260
|
+
15.00269,
|
1261
|
+
19.44382]),4)
|
1262
|
+
assert_array_almost_equal(keiz,array([3.91467,
|
1263
|
+
8.34422,
|
1264
|
+
12.78256,
|
1265
|
+
17.22314,
|
1266
|
+
21.66464]),4)
|
1267
|
+
assert_array_almost_equal(berpz,array([6.03871,
|
1268
|
+
10.51364,
|
1269
|
+
14.96844,
|
1270
|
+
19.41758,
|
1271
|
+
23.86430]),4)
|
1272
|
+
assert_array_almost_equal(beipz,array([3.77267,
|
1273
|
+
# table from 1927 had 3.77320
|
1274
|
+
# but this is more accurate
|
1275
|
+
8.28099,
|
1276
|
+
12.74215,
|
1277
|
+
17.19343,
|
1278
|
+
21.64114]),4)
|
1279
|
+
assert_array_almost_equal(kerpz,array([2.66584,
|
1280
|
+
7.17212,
|
1281
|
+
11.63218,
|
1282
|
+
16.08312,
|
1283
|
+
20.53068]),4)
|
1284
|
+
assert_array_almost_equal(keipz,array([4.93181,
|
1285
|
+
9.40405,
|
1286
|
+
13.85827,
|
1287
|
+
18.30717,
|
1288
|
+
22.75379]),4)
|
1289
|
+
|
1290
|
+
def test_ker_zeros(self):
|
1291
|
+
ker = special.ker_zeros(5)
|
1292
|
+
assert_array_almost_equal(ker,array([1.71854,
|
1293
|
+
6.12728,
|
1294
|
+
10.56294,
|
1295
|
+
15.00269,
|
1296
|
+
19.44381]),4)
|
1297
|
+
|
1298
|
+
def test_kerp_zeros(self):
|
1299
|
+
kerp = special.kerp_zeros(5)
|
1300
|
+
assert_array_almost_equal(kerp,array([2.66584,
|
1301
|
+
7.17212,
|
1302
|
+
11.63218,
|
1303
|
+
16.08312,
|
1304
|
+
20.53068]),4)
|
1305
|
+
|
1306
|
+
|
1307
|
+
class TestBernoulli:
|
1308
|
+
def test_bernoulli(self):
|
1309
|
+
brn = special.bernoulli(5)
|
1310
|
+
assert_array_almost_equal(brn,array([1.0000,
|
1311
|
+
-0.5000,
|
1312
|
+
0.1667,
|
1313
|
+
0.0000,
|
1314
|
+
-0.0333,
|
1315
|
+
0.0000]),4)
|
1316
|
+
|
1317
|
+
|
1318
|
+
class TestBeta:
|
1319
|
+
"""
|
1320
|
+
Test beta and betaln.
|
1321
|
+
"""
|
1322
|
+
|
1323
|
+
def test_beta(self):
|
1324
|
+
assert_equal(special.beta(1, 1), 1.0)
|
1325
|
+
assert_allclose(special.beta(-100.3, 1e-200), special.gamma(1e-200))
|
1326
|
+
assert_allclose(special.beta(0.0342, 171), 24.070498359873497,
|
1327
|
+
rtol=1e-13, atol=0)
|
1328
|
+
|
1329
|
+
bet = special.beta(2, 4)
|
1330
|
+
betg = (special.gamma(2)*special.gamma(4))/special.gamma(6)
|
1331
|
+
assert_allclose(bet, betg, rtol=1e-13)
|
1332
|
+
|
1333
|
+
def test_beta_inf(self):
|
1334
|
+
assert_(np.isinf(special.beta(-1, 2)))
|
1335
|
+
|
1336
|
+
def test_betaln(self):
|
1337
|
+
assert_equal(special.betaln(1, 1), 0.0)
|
1338
|
+
assert_allclose(special.betaln(-100.3, 1e-200),
|
1339
|
+
special.gammaln(1e-200))
|
1340
|
+
assert_allclose(special.betaln(0.0342, 170), 3.1811881124242447,
|
1341
|
+
rtol=1e-14, atol=0)
|
1342
|
+
|
1343
|
+
betln = special.betaln(2, 4)
|
1344
|
+
bet = log(abs(special.beta(2, 4)))
|
1345
|
+
assert_allclose(betln, bet, rtol=1e-13)
|
1346
|
+
|
1347
|
+
|
1348
|
+
class TestBetaInc:
|
1349
|
+
"""
|
1350
|
+
Tests for betainc, betaincinv, betaincc, betainccinv.
|
1351
|
+
"""
|
1352
|
+
|
1353
|
+
def test_a1_b1(self):
|
1354
|
+
# betainc(1, 1, x) is x.
|
1355
|
+
x = np.array([0, 0.25, 1])
|
1356
|
+
assert_equal(special.betainc(1, 1, x), x)
|
1357
|
+
assert_equal(special.betaincinv(1, 1, x), x)
|
1358
|
+
assert_equal(special.betaincc(1, 1, x), 1 - x)
|
1359
|
+
assert_equal(special.betainccinv(1, 1, x), 1 - x)
|
1360
|
+
|
1361
|
+
# Nontrivial expected values computed with mpmath:
|
1362
|
+
# from mpmath import mp
|
1363
|
+
# mp.dps = 100
|
1364
|
+
# p = mp.betainc(a, b, 0, x, regularized=True)
|
1365
|
+
#
|
1366
|
+
# or, e.g.,
|
1367
|
+
#
|
1368
|
+
# p = 0.25
|
1369
|
+
# a, b = 0.0342, 171
|
1370
|
+
# x = mp.findroot(
|
1371
|
+
# lambda t: mp.betainc(a, b, 0, t, regularized=True) - p,
|
1372
|
+
# (8e-21, 9e-21),
|
1373
|
+
# solver='anderson',
|
1374
|
+
# )
|
1375
|
+
#
|
1376
|
+
@pytest.mark.parametrize(
|
1377
|
+
'a, b, x, p',
|
1378
|
+
[(2, 4, 0.3138101704556974, 0.5),
|
1379
|
+
(0.0342, 171.0, 1e-10, 0.552699169018070910641),
|
1380
|
+
# gh-3761:
|
1381
|
+
(0.0342, 171, 8.42313169354797e-21, 0.25),
|
1382
|
+
# gh-4244:
|
1383
|
+
(0.0002742794749792665, 289206.03125, 1.639984034231756e-56,
|
1384
|
+
0.9688708782196045),
|
1385
|
+
# gh-12796:
|
1386
|
+
(4, 99997, 0.0001947841578892121, 0.999995)])
|
1387
|
+
def test_betainc_betaincinv(self, a, b, x, p):
|
1388
|
+
p1 = special.betainc(a, b, x)
|
1389
|
+
assert_allclose(p1, p, rtol=1e-15)
|
1390
|
+
x1 = special.betaincinv(a, b, p)
|
1391
|
+
assert_allclose(x1, x, rtol=5e-13)
|
1392
|
+
|
1393
|
+
# Expected values computed with mpmath:
|
1394
|
+
# from mpmath import mp
|
1395
|
+
# mp.dps = 100
|
1396
|
+
# p = mp.betainc(a, b, x, 1, regularized=True)
|
1397
|
+
@pytest.mark.parametrize('a, b, x, p',
|
1398
|
+
[(2.5, 3.0, 0.25, 0.833251953125),
|
1399
|
+
(7.5, 13.25, 0.375, 0.43298734645560368593),
|
1400
|
+
(0.125, 7.5, 0.425, 0.0006688257851314237),
|
1401
|
+
(0.125, 18.0, 1e-6, 0.72982359145096327654),
|
1402
|
+
(0.125, 18.0, 0.996, 7.2745875538380150586e-46),
|
1403
|
+
(0.125, 24.0, 0.75, 3.70853404816862016966e-17),
|
1404
|
+
(16.0, 0.75, 0.99999999975,
|
1405
|
+
5.4408759277418629909e-07),
|
1406
|
+
# gh-4677 (numbers from stackoverflow question):
|
1407
|
+
(0.4211959643503401, 16939.046996018118,
|
1408
|
+
0.000815296167195521, 1e-7)])
|
1409
|
+
def test_betaincc_betainccinv(self, a, b, x, p):
|
1410
|
+
p1 = special.betaincc(a, b, x)
|
1411
|
+
assert_allclose(p1, p, rtol=5e-15)
|
1412
|
+
x1 = special.betainccinv(a, b, p)
|
1413
|
+
assert_allclose(x1, x, rtol=8e-15)
|
1414
|
+
|
1415
|
+
@pytest.mark.parametrize(
|
1416
|
+
'a, b, y, ref',
|
1417
|
+
[(14.208308325339239, 14.208308325339239, 7.703145458496392e-307,
|
1418
|
+
8.566004561846704e-23),
|
1419
|
+
(14.0, 14.5, 1e-280, 2.9343915006642424e-21),
|
1420
|
+
(3.5, 15.0, 4e-95, 1.3290751429289227e-28),
|
1421
|
+
(10.0, 1.25, 2e-234, 3.982659092143654e-24),
|
1422
|
+
(4.0, 99997.0, 5e-88, 3.309800566862242e-27)]
|
1423
|
+
)
|
1424
|
+
def test_betaincinv_tiny_y(self, a, b, y, ref):
|
1425
|
+
# Test with extremely small y values. This test includes
|
1426
|
+
# a regression test for an issue in the boost code;
|
1427
|
+
# see https://github.com/boostorg/math/issues/961
|
1428
|
+
#
|
1429
|
+
# The reference values were computed with mpmath. For example,
|
1430
|
+
#
|
1431
|
+
# from mpmath import mp
|
1432
|
+
# mp.dps = 1000
|
1433
|
+
# a = 14.208308325339239
|
1434
|
+
# p = 7.703145458496392e-307
|
1435
|
+
# x = mp.findroot(lambda t: mp.betainc(a, a, 0, t,
|
1436
|
+
# regularized=True) - p,
|
1437
|
+
# x0=8.566e-23)
|
1438
|
+
# print(float(x))
|
1439
|
+
#
|
1440
|
+
x = special.betaincinv(a, b, y)
|
1441
|
+
assert_allclose(x, ref, rtol=1e-14)
|
1442
|
+
|
1443
|
+
@pytest.mark.parametrize('func', [special.betainc, special.betaincinv,
|
1444
|
+
special.betaincc, special.betainccinv])
|
1445
|
+
@pytest.mark.parametrize('args', [(-1.0, 2, 0.5), (1.5, -2.0, 0.5),
|
1446
|
+
(1.5, 2.0, -0.3), (1.5, 2.0, 1.1)])
|
1447
|
+
def test_betainc_domain_errors(self, func, args):
|
1448
|
+
with special.errstate(domain='raise'):
|
1449
|
+
with pytest.raises(special.SpecialFunctionError, match='domain'):
|
1450
|
+
special.betainc(*args)
|
1451
|
+
|
1452
|
+
@pytest.mark.parametrize(
|
1453
|
+
"args,expected",
|
1454
|
+
[
|
1455
|
+
((0.0, 0.0, 0.0), np.nan),
|
1456
|
+
((0.0, 0.0, 0.5), np.nan),
|
1457
|
+
((0.0, 0.0, 1.0), np.nan),
|
1458
|
+
((np.inf, np.inf, 0.0), np.nan),
|
1459
|
+
((np.inf, np.inf, 0.5), np.nan),
|
1460
|
+
((np.inf, np.inf, 1.0), np.nan),
|
1461
|
+
((0.0, 1.0, 0.0), 0.0),
|
1462
|
+
((0.0, 1.0, 0.5), 1.0),
|
1463
|
+
((0.0, 1.0, 1.0), 1.0),
|
1464
|
+
((1.0, 0.0, 0.0), 0.0),
|
1465
|
+
((1.0, 0.0, 0.5), 0.0),
|
1466
|
+
((1.0, 0.0, 1.0), 1.0),
|
1467
|
+
((0.0, np.inf, 0.0), 0.0),
|
1468
|
+
((0.0, np.inf, 0.5), 1.0),
|
1469
|
+
((0.0, np.inf, 1.0), 1.0),
|
1470
|
+
((np.inf, 0.0, 0.0), 0.0),
|
1471
|
+
((np.inf, 0.0, 0.5), 0.0),
|
1472
|
+
((np.inf, 0.0, 1.0), 1.0),
|
1473
|
+
((1.0, np.inf, 0.0), 0.0),
|
1474
|
+
((1.0, np.inf, 0.5), 1.0),
|
1475
|
+
((1.0, np.inf, 1.0), 1.0),
|
1476
|
+
((np.inf, 1.0, 0.0), 0.0),
|
1477
|
+
((np.inf, 1.0, 0.5), 0.0),
|
1478
|
+
((np.inf, 1.0, 1.0), 1.0),
|
1479
|
+
]
|
1480
|
+
)
|
1481
|
+
def test_betainc_edge_cases(self, args, expected):
|
1482
|
+
observed = special.betainc(*args)
|
1483
|
+
assert_equal(observed, expected)
|
1484
|
+
|
1485
|
+
@pytest.mark.parametrize(
|
1486
|
+
"args,expected",
|
1487
|
+
[
|
1488
|
+
((0.0, 0.0, 0.0), np.nan),
|
1489
|
+
((0.0, 0.0, 0.5), np.nan),
|
1490
|
+
((0.0, 0.0, 1.0), np.nan),
|
1491
|
+
((np.inf, np.inf, 0.0), np.nan),
|
1492
|
+
((np.inf, np.inf, 0.5), np.nan),
|
1493
|
+
((np.inf, np.inf, 1.0), np.nan),
|
1494
|
+
((0.0, 1.0, 0.0), 1.0),
|
1495
|
+
((0.0, 1.0, 0.5), 0.0),
|
1496
|
+
((0.0, 1.0, 1.0), 0.0),
|
1497
|
+
((1.0, 0.0, 0.0), 1.0),
|
1498
|
+
((1.0, 0.0, 0.5), 1.0),
|
1499
|
+
((1.0, 0.0, 1.0), 0.0),
|
1500
|
+
((0.0, np.inf, 0.0), 1.0),
|
1501
|
+
((0.0, np.inf, 0.5), 0.0),
|
1502
|
+
((0.0, np.inf, 1.0), 0.0),
|
1503
|
+
((np.inf, 0.0, 0.0), 1.0),
|
1504
|
+
((np.inf, 0.0, 0.5), 1.0),
|
1505
|
+
((np.inf, 0.0, 1.0), 0.0),
|
1506
|
+
((1.0, np.inf, 0.0), 1.0),
|
1507
|
+
((1.0, np.inf, 0.5), 0.0),
|
1508
|
+
((1.0, np.inf, 1.0), 0.0),
|
1509
|
+
((np.inf, 1.0, 0.0), 1.0),
|
1510
|
+
((np.inf, 1.0, 0.5), 1.0),
|
1511
|
+
((np.inf, 1.0, 1.0), 0.0),
|
1512
|
+
]
|
1513
|
+
)
|
1514
|
+
def test_betaincc_edge_cases(self, args, expected):
|
1515
|
+
observed = special.betaincc(*args)
|
1516
|
+
assert_equal(observed, expected)
|
1517
|
+
|
1518
|
+
@pytest.mark.parametrize('dtype', [np.float32, np.float64])
|
1519
|
+
def test_gh21426(self, dtype):
|
1520
|
+
# Test for gh-21426: betaincinv must not return NaN
|
1521
|
+
a = np.array([5.], dtype=dtype)
|
1522
|
+
x = np.array([0.5], dtype=dtype)
|
1523
|
+
result = special.betaincinv(a, a, x)
|
1524
|
+
assert_allclose(result, x, rtol=10 * np.finfo(dtype).eps)
|
1525
|
+
|
1526
|
+
|
1527
|
+
class TestCombinatorics:
|
1528
|
+
def test_comb(self):
|
1529
|
+
assert_allclose(special.comb([10, 10], [3, 4]), [120., 210.])
|
1530
|
+
assert_allclose(special.comb(10, 3), 120.)
|
1531
|
+
assert_equal(special.comb(10, 3, exact=True), 120)
|
1532
|
+
assert_equal(special.comb(10, 3, exact=True, repetition=True), 220)
|
1533
|
+
|
1534
|
+
assert_allclose([special.comb(20, k, exact=True) for k in range(21)],
|
1535
|
+
special.comb(20, list(range(21))), atol=1e-15)
|
1536
|
+
|
1537
|
+
ii = np.iinfo(int).max + 1
|
1538
|
+
assert_equal(special.comb(ii, ii-1, exact=True), ii)
|
1539
|
+
|
1540
|
+
expected = 100891344545564193334812497256
|
1541
|
+
assert special.comb(100, 50, exact=True) == expected
|
1542
|
+
|
1543
|
+
def test_comb_with_np_int64(self):
|
1544
|
+
n = 70
|
1545
|
+
k = 30
|
1546
|
+
np_n = np.int64(n)
|
1547
|
+
np_k = np.int64(k)
|
1548
|
+
res_np = special.comb(np_n, np_k, exact=True)
|
1549
|
+
res_py = special.comb(n, k, exact=True)
|
1550
|
+
assert res_np == res_py
|
1551
|
+
|
1552
|
+
def test_comb_zeros(self):
|
1553
|
+
assert_equal(special.comb(2, 3, exact=True), 0)
|
1554
|
+
assert_equal(special.comb(-1, 3, exact=True), 0)
|
1555
|
+
assert_equal(special.comb(2, -1, exact=True), 0)
|
1556
|
+
assert_equal(special.comb(2, -1, exact=False), 0)
|
1557
|
+
assert_allclose(special.comb([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 120.])
|
1558
|
+
|
1559
|
+
@pytest.mark.thread_unsafe
|
1560
|
+
def test_comb_exact_non_int_error(self):
|
1561
|
+
msg = "`exact=True`"
|
1562
|
+
with pytest.raises(ValueError, match=msg):
|
1563
|
+
special.comb(3.4, 4, exact=True)
|
1564
|
+
with pytest.raises(ValueError, match=msg):
|
1565
|
+
special.comb(3, 4.4, exact=True)
|
1566
|
+
|
1567
|
+
|
1568
|
+
def test_perm(self):
|
1569
|
+
assert_allclose(special.perm([10, 10], [3, 4]), [720., 5040.])
|
1570
|
+
assert_almost_equal(special.perm(10, 3), 720.)
|
1571
|
+
assert_equal(special.perm(10, 3, exact=True), 720)
|
1572
|
+
|
1573
|
+
def test_perm_zeros(self):
|
1574
|
+
assert_equal(special.perm(2, 3, exact=True), 0)
|
1575
|
+
assert_equal(special.perm(-1, 3, exact=True), 0)
|
1576
|
+
assert_equal(special.perm(2, -1, exact=True), 0)
|
1577
|
+
assert_equal(special.perm(2, -1, exact=False), 0)
|
1578
|
+
assert_allclose(special.perm([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 720.])
|
1579
|
+
|
1580
|
+
@pytest.mark.thread_unsafe
|
1581
|
+
def test_perm_iv(self):
|
1582
|
+
# currently `exact=True` only support scalars
|
1583
|
+
with pytest.raises(ValueError, match="scalar integers"):
|
1584
|
+
special.perm([1, 2], [4, 5], exact=True)
|
1585
|
+
|
1586
|
+
with pytest.raises(ValueError, match="Non-integer"):
|
1587
|
+
special.perm(4.6, 6, exact=True)
|
1588
|
+
with pytest.raises(ValueError, match="Non-integer"):
|
1589
|
+
special.perm(-4.6, 3, exact=True)
|
1590
|
+
with pytest.raises(ValueError, match="Non-integer"):
|
1591
|
+
special.perm(4, -3.9, exact=True)
|
1592
|
+
with pytest.raises(ValueError, match="Non-integer"):
|
1593
|
+
special.perm(6.0, 4.6, exact=True)
|
1594
|
+
|
1595
|
+
|
1596
|
+
class TestTrigonometric:
|
1597
|
+
def test_cbrt(self):
|
1598
|
+
cb = special.cbrt(27)
|
1599
|
+
cbrl = 27**(1.0/3.0)
|
1600
|
+
assert_approx_equal(cb,cbrl)
|
1601
|
+
|
1602
|
+
def test_cbrtmore(self):
|
1603
|
+
cb1 = special.cbrt(27.9)
|
1604
|
+
cbrl1 = 27.9**(1.0/3.0)
|
1605
|
+
assert_almost_equal(cb1,cbrl1,8)
|
1606
|
+
|
1607
|
+
def test_cosdg(self):
|
1608
|
+
cdg = special.cosdg(90)
|
1609
|
+
cdgrl = cos(pi/2.0)
|
1610
|
+
assert_almost_equal(cdg,cdgrl,8)
|
1611
|
+
|
1612
|
+
def test_cosdgmore(self):
|
1613
|
+
cdgm = special.cosdg(30)
|
1614
|
+
cdgmrl = cos(pi/6.0)
|
1615
|
+
assert_almost_equal(cdgm,cdgmrl,8)
|
1616
|
+
|
1617
|
+
def test_cosm1(self):
|
1618
|
+
cs = (special.cosm1(0),special.cosm1(.3),special.cosm1(pi/10))
|
1619
|
+
csrl = (cos(0)-1,cos(.3)-1,cos(pi/10)-1)
|
1620
|
+
assert_array_almost_equal(cs,csrl,8)
|
1621
|
+
|
1622
|
+
def test_cotdg(self):
|
1623
|
+
ct = special.cotdg(30)
|
1624
|
+
ctrl = tan(pi/6.0)**(-1)
|
1625
|
+
assert_almost_equal(ct,ctrl,8)
|
1626
|
+
|
1627
|
+
def test_cotdgmore(self):
|
1628
|
+
ct1 = special.cotdg(45)
|
1629
|
+
ctrl1 = tan(pi/4.0)**(-1)
|
1630
|
+
assert_almost_equal(ct1,ctrl1,8)
|
1631
|
+
|
1632
|
+
def test_specialpoints(self):
|
1633
|
+
assert_almost_equal(special.cotdg(45), 1.0, 14)
|
1634
|
+
assert_almost_equal(special.cotdg(-45), -1.0, 14)
|
1635
|
+
assert_almost_equal(special.cotdg(90), 0.0, 14)
|
1636
|
+
assert_almost_equal(special.cotdg(-90), 0.0, 14)
|
1637
|
+
assert_almost_equal(special.cotdg(135), -1.0, 14)
|
1638
|
+
assert_almost_equal(special.cotdg(-135), 1.0, 14)
|
1639
|
+
assert_almost_equal(special.cotdg(225), 1.0, 14)
|
1640
|
+
assert_almost_equal(special.cotdg(-225), -1.0, 14)
|
1641
|
+
assert_almost_equal(special.cotdg(270), 0.0, 14)
|
1642
|
+
assert_almost_equal(special.cotdg(-270), 0.0, 14)
|
1643
|
+
assert_almost_equal(special.cotdg(315), -1.0, 14)
|
1644
|
+
assert_almost_equal(special.cotdg(-315), 1.0, 14)
|
1645
|
+
assert_almost_equal(special.cotdg(765), 1.0, 14)
|
1646
|
+
|
1647
|
+
def test_sinc(self):
|
1648
|
+
# the sinc implementation and more extensive sinc tests are in numpy
|
1649
|
+
assert_array_equal(special.sinc([0]), 1)
|
1650
|
+
assert_equal(special.sinc(0.0), 1.0)
|
1651
|
+
|
1652
|
+
def test_sindg(self):
|
1653
|
+
sn = special.sindg(90)
|
1654
|
+
assert_equal(sn,1.0)
|
1655
|
+
|
1656
|
+
def test_sindgmore(self):
|
1657
|
+
snm = special.sindg(30)
|
1658
|
+
snmrl = sin(pi/6.0)
|
1659
|
+
assert_almost_equal(snm,snmrl,8)
|
1660
|
+
snm1 = special.sindg(45)
|
1661
|
+
snmrl1 = sin(pi/4.0)
|
1662
|
+
assert_almost_equal(snm1,snmrl1,8)
|
1663
|
+
|
1664
|
+
|
1665
|
+
class TestTandg:
|
1666
|
+
|
1667
|
+
def test_tandg(self):
|
1668
|
+
tn = special.tandg(30)
|
1669
|
+
tnrl = tan(pi/6.0)
|
1670
|
+
assert_almost_equal(tn,tnrl,8)
|
1671
|
+
|
1672
|
+
def test_tandgmore(self):
|
1673
|
+
tnm = special.tandg(45)
|
1674
|
+
tnmrl = tan(pi/4.0)
|
1675
|
+
assert_almost_equal(tnm,tnmrl,8)
|
1676
|
+
tnm1 = special.tandg(60)
|
1677
|
+
tnmrl1 = tan(pi/3.0)
|
1678
|
+
assert_almost_equal(tnm1,tnmrl1,8)
|
1679
|
+
|
1680
|
+
def test_specialpoints(self):
|
1681
|
+
assert_almost_equal(special.tandg(0), 0.0, 14)
|
1682
|
+
assert_almost_equal(special.tandg(45), 1.0, 14)
|
1683
|
+
assert_almost_equal(special.tandg(-45), -1.0, 14)
|
1684
|
+
assert_almost_equal(special.tandg(135), -1.0, 14)
|
1685
|
+
assert_almost_equal(special.tandg(-135), 1.0, 14)
|
1686
|
+
assert_almost_equal(special.tandg(180), 0.0, 14)
|
1687
|
+
assert_almost_equal(special.tandg(-180), 0.0, 14)
|
1688
|
+
assert_almost_equal(special.tandg(225), 1.0, 14)
|
1689
|
+
assert_almost_equal(special.tandg(-225), -1.0, 14)
|
1690
|
+
assert_almost_equal(special.tandg(315), -1.0, 14)
|
1691
|
+
assert_almost_equal(special.tandg(-315), 1.0, 14)
|
1692
|
+
|
1693
|
+
|
1694
|
+
class TestEllip:
|
1695
|
+
def test_ellipj_nan(self):
|
1696
|
+
"""Regression test for #912."""
|
1697
|
+
special.ellipj(0.5, np.nan)
|
1698
|
+
|
1699
|
+
def test_ellipj(self):
|
1700
|
+
el = special.ellipj(0.2,0)
|
1701
|
+
rel = [sin(0.2),cos(0.2),1.0,0.20]
|
1702
|
+
assert_array_almost_equal(el,rel,13)
|
1703
|
+
|
1704
|
+
def test_ellipk(self):
|
1705
|
+
elk = special.ellipk(.2)
|
1706
|
+
assert_almost_equal(elk,1.659623598610528,11)
|
1707
|
+
|
1708
|
+
assert_equal(special.ellipkm1(0.0), np.inf)
|
1709
|
+
assert_equal(special.ellipkm1(1.0), pi/2)
|
1710
|
+
assert_equal(special.ellipkm1(np.inf), 0.0)
|
1711
|
+
assert_equal(special.ellipkm1(np.nan), np.nan)
|
1712
|
+
assert_equal(special.ellipkm1(-1), np.nan)
|
1713
|
+
assert_allclose(special.ellipk(-10), 0.7908718902387385)
|
1714
|
+
|
1715
|
+
def test_ellipkinc(self):
|
1716
|
+
elkinc = special.ellipkinc(pi/2,.2)
|
1717
|
+
elk = special.ellipk(0.2)
|
1718
|
+
assert_almost_equal(elkinc,elk,15)
|
1719
|
+
alpha = 20*pi/180
|
1720
|
+
phi = 45*pi/180
|
1721
|
+
m = sin(alpha)**2
|
1722
|
+
elkinc = special.ellipkinc(phi,m)
|
1723
|
+
assert_almost_equal(elkinc,0.79398143,8)
|
1724
|
+
# From pg. 614 of A & S
|
1725
|
+
|
1726
|
+
assert_equal(special.ellipkinc(pi/2, 0.0), pi/2)
|
1727
|
+
assert_equal(special.ellipkinc(pi/2, 1.0), np.inf)
|
1728
|
+
assert_equal(special.ellipkinc(pi/2, -np.inf), 0.0)
|
1729
|
+
assert_equal(special.ellipkinc(pi/2, np.nan), np.nan)
|
1730
|
+
assert_equal(special.ellipkinc(pi/2, 2), np.nan)
|
1731
|
+
assert_equal(special.ellipkinc(0, 0.5), 0.0)
|
1732
|
+
assert_equal(special.ellipkinc(np.inf, 0.5), np.inf)
|
1733
|
+
assert_equal(special.ellipkinc(-np.inf, 0.5), -np.inf)
|
1734
|
+
assert_equal(special.ellipkinc(np.inf, np.inf), np.nan)
|
1735
|
+
assert_equal(special.ellipkinc(np.inf, -np.inf), np.nan)
|
1736
|
+
assert_equal(special.ellipkinc(-np.inf, -np.inf), np.nan)
|
1737
|
+
assert_equal(special.ellipkinc(-np.inf, np.inf), np.nan)
|
1738
|
+
assert_equal(special.ellipkinc(np.nan, 0.5), np.nan)
|
1739
|
+
assert_equal(special.ellipkinc(np.nan, np.nan), np.nan)
|
1740
|
+
|
1741
|
+
assert_allclose(special.ellipkinc(0.38974112035318718, 1), 0.4, rtol=1e-14)
|
1742
|
+
assert_allclose(special.ellipkinc(1.5707, -10), 0.79084284661724946)
|
1743
|
+
|
1744
|
+
def test_ellipkinc_2(self):
|
1745
|
+
# Regression test for gh-3550
|
1746
|
+
# ellipkinc(phi, mbad) was NaN and mvals[2:6] were twice the correct value
|
1747
|
+
mbad = 0.68359375000000011
|
1748
|
+
phi = 0.9272952180016123
|
1749
|
+
m = np.nextafter(mbad, 0)
|
1750
|
+
mvals = []
|
1751
|
+
for j in range(10):
|
1752
|
+
mvals.append(m)
|
1753
|
+
m = np.nextafter(m, 1)
|
1754
|
+
f = special.ellipkinc(phi, mvals)
|
1755
|
+
assert_array_almost_equal_nulp(f, np.full_like(f, 1.0259330100195334), 1)
|
1756
|
+
# this bug also appears at phi + n * pi for at least small n
|
1757
|
+
f1 = special.ellipkinc(phi + pi, mvals)
|
1758
|
+
assert_array_almost_equal_nulp(f1, np.full_like(f1, 5.1296650500976675), 2)
|
1759
|
+
|
1760
|
+
def test_ellipkinc_singular(self):
|
1761
|
+
# ellipkinc(phi, 1) has closed form and is finite only for phi in (-pi/2, pi/2)
|
1762
|
+
xlog = np.logspace(-300, -17, 25)
|
1763
|
+
xlin = np.linspace(1e-17, 0.1, 25)
|
1764
|
+
xlin2 = np.linspace(0.1, pi/2, 25, endpoint=False)
|
1765
|
+
|
1766
|
+
assert_allclose(special.ellipkinc(xlog, 1), np.arcsinh(np.tan(xlog)),
|
1767
|
+
rtol=1e14)
|
1768
|
+
assert_allclose(special.ellipkinc(xlin, 1), np.arcsinh(np.tan(xlin)),
|
1769
|
+
rtol=1e14)
|
1770
|
+
assert_allclose(special.ellipkinc(xlin2, 1), np.arcsinh(np.tan(xlin2)),
|
1771
|
+
rtol=1e14)
|
1772
|
+
assert_equal(special.ellipkinc(np.pi/2, 1), np.inf)
|
1773
|
+
assert_allclose(special.ellipkinc(-xlog, 1), np.arcsinh(np.tan(-xlog)),
|
1774
|
+
rtol=1e14)
|
1775
|
+
assert_allclose(special.ellipkinc(-xlin, 1), np.arcsinh(np.tan(-xlin)),
|
1776
|
+
rtol=1e14)
|
1777
|
+
assert_allclose(special.ellipkinc(-xlin2, 1), np.arcsinh(np.tan(-xlin2)),
|
1778
|
+
rtol=1e14)
|
1779
|
+
assert_equal(special.ellipkinc(-np.pi/2, 1), np.inf)
|
1780
|
+
|
1781
|
+
def test_ellipe(self):
|
1782
|
+
ele = special.ellipe(.2)
|
1783
|
+
assert_almost_equal(ele,1.4890350580958529,8)
|
1784
|
+
|
1785
|
+
assert_equal(special.ellipe(0.0), pi/2)
|
1786
|
+
assert_equal(special.ellipe(1.0), 1.0)
|
1787
|
+
assert_equal(special.ellipe(-np.inf), np.inf)
|
1788
|
+
assert_equal(special.ellipe(np.nan), np.nan)
|
1789
|
+
assert_equal(special.ellipe(2), np.nan)
|
1790
|
+
assert_allclose(special.ellipe(-10), 3.6391380384177689)
|
1791
|
+
|
1792
|
+
def test_ellipeinc(self):
|
1793
|
+
eleinc = special.ellipeinc(pi/2,.2)
|
1794
|
+
ele = special.ellipe(0.2)
|
1795
|
+
assert_almost_equal(eleinc,ele,14)
|
1796
|
+
# pg 617 of A & S
|
1797
|
+
alpha, phi = 52*pi/180,35*pi/180
|
1798
|
+
m = sin(alpha)**2
|
1799
|
+
eleinc = special.ellipeinc(phi,m)
|
1800
|
+
assert_almost_equal(eleinc, 0.58823065, 8)
|
1801
|
+
|
1802
|
+
assert_equal(special.ellipeinc(pi/2, 0.0), pi/2)
|
1803
|
+
assert_equal(special.ellipeinc(pi/2, 1.0), 1.0)
|
1804
|
+
assert_equal(special.ellipeinc(pi/2, -np.inf), np.inf)
|
1805
|
+
assert_equal(special.ellipeinc(pi/2, np.nan), np.nan)
|
1806
|
+
assert_equal(special.ellipeinc(pi/2, 2), np.nan)
|
1807
|
+
assert_equal(special.ellipeinc(0, 0.5), 0.0)
|
1808
|
+
assert_equal(special.ellipeinc(np.inf, 0.5), np.inf)
|
1809
|
+
assert_equal(special.ellipeinc(-np.inf, 0.5), -np.inf)
|
1810
|
+
assert_equal(special.ellipeinc(np.inf, -np.inf), np.inf)
|
1811
|
+
assert_equal(special.ellipeinc(-np.inf, -np.inf), -np.inf)
|
1812
|
+
assert_equal(special.ellipeinc(np.inf, np.inf), np.nan)
|
1813
|
+
assert_equal(special.ellipeinc(-np.inf, np.inf), np.nan)
|
1814
|
+
assert_equal(special.ellipeinc(np.nan, 0.5), np.nan)
|
1815
|
+
assert_equal(special.ellipeinc(np.nan, np.nan), np.nan)
|
1816
|
+
assert_allclose(special.ellipeinc(1.5707, -10), 3.6388185585822876)
|
1817
|
+
|
1818
|
+
def test_ellipeinc_2(self):
|
1819
|
+
# Regression test for gh-3550
|
1820
|
+
# ellipeinc(phi, mbad) was NaN and mvals[2:6] were twice the correct value
|
1821
|
+
mbad = 0.68359375000000011
|
1822
|
+
phi = 0.9272952180016123
|
1823
|
+
m = np.nextafter(mbad, 0)
|
1824
|
+
mvals = []
|
1825
|
+
for j in range(10):
|
1826
|
+
mvals.append(m)
|
1827
|
+
m = np.nextafter(m, 1)
|
1828
|
+
f = special.ellipeinc(phi, mvals)
|
1829
|
+
assert_array_almost_equal_nulp(f, np.full_like(f, 0.84442884574781019), 2)
|
1830
|
+
# this bug also appears at phi + n * pi for at least small n
|
1831
|
+
f1 = special.ellipeinc(phi + pi, mvals)
|
1832
|
+
assert_array_almost_equal_nulp(f1, np.full_like(f1, 3.3471442287390509), 4)
|
1833
|
+
|
1834
|
+
|
1835
|
+
class TestEllipCarlson:
|
1836
|
+
"""Test for Carlson elliptic integrals ellipr[cdfgj].
|
1837
|
+
The special values used in these tests can be found in Sec. 3 of Carlson
|
1838
|
+
(1994), https://arxiv.org/abs/math/9409227
|
1839
|
+
"""
|
1840
|
+
def test_elliprc(self):
|
1841
|
+
assert_allclose(elliprc(1, 1), 1)
|
1842
|
+
assert elliprc(1, inf) == 0.0
|
1843
|
+
assert isnan(elliprc(1, 0))
|
1844
|
+
assert elliprc(1, complex(1, inf)) == 0.0
|
1845
|
+
args = array([[0.0, 0.25],
|
1846
|
+
[2.25, 2.0],
|
1847
|
+
[0.0, 1.0j],
|
1848
|
+
[-1.0j, 1.0j],
|
1849
|
+
[0.25, -2.0],
|
1850
|
+
[1.0j, -1.0]])
|
1851
|
+
expected_results = array([np.pi,
|
1852
|
+
np.log(2.0),
|
1853
|
+
1.1107207345396 * (1.0-1.0j),
|
1854
|
+
1.2260849569072-0.34471136988768j,
|
1855
|
+
np.log(2.0) / 3.0,
|
1856
|
+
0.77778596920447+0.19832484993429j])
|
1857
|
+
for i, arr in enumerate(args):
|
1858
|
+
assert_allclose(elliprc(*arr), expected_results[i])
|
1859
|
+
|
1860
|
+
def test_elliprd(self):
|
1861
|
+
assert_allclose(elliprd(1, 1, 1), 1)
|
1862
|
+
assert_allclose(elliprd(0, 2, 1) / 3.0, 0.59907011736779610371)
|
1863
|
+
assert elliprd(1, 1, inf) == 0.0
|
1864
|
+
assert np.isinf(elliprd(1, 1, 0))
|
1865
|
+
assert np.isinf(elliprd(1, 1, complex(0, 0)))
|
1866
|
+
assert np.isinf(elliprd(0, 1, complex(0, 0)))
|
1867
|
+
assert isnan(elliprd(1, 1, -np.finfo(np.float64).tiny / 2.0))
|
1868
|
+
assert isnan(elliprd(1, 1, complex(-1, 0)))
|
1869
|
+
args = array([[0.0, 2.0, 1.0],
|
1870
|
+
[2.0, 3.0, 4.0],
|
1871
|
+
[1.0j, -1.0j, 2.0],
|
1872
|
+
[0.0, 1.0j, -1.0j],
|
1873
|
+
[0.0, -1.0+1.0j, 1.0j],
|
1874
|
+
[-2.0-1.0j, -1.0j, -1.0+1.0j]])
|
1875
|
+
expected_results = array([1.7972103521034,
|
1876
|
+
0.16510527294261,
|
1877
|
+
0.65933854154220,
|
1878
|
+
1.2708196271910+2.7811120159521j,
|
1879
|
+
-1.8577235439239-0.96193450888839j,
|
1880
|
+
1.8249027393704-1.2218475784827j])
|
1881
|
+
for i, arr in enumerate(args):
|
1882
|
+
assert_allclose(elliprd(*arr), expected_results[i])
|
1883
|
+
|
1884
|
+
def test_elliprf(self):
|
1885
|
+
assert_allclose(elliprf(1, 1, 1), 1)
|
1886
|
+
assert_allclose(elliprf(0, 1, 2), 1.31102877714605990523)
|
1887
|
+
assert elliprf(1, inf, 1) == 0.0
|
1888
|
+
assert np.isinf(elliprf(0, 1, 0))
|
1889
|
+
assert isnan(elliprf(1, 1, -1))
|
1890
|
+
assert elliprf(complex(inf), 0, 1) == 0.0
|
1891
|
+
assert isnan(elliprf(1, 1, complex(-inf, 1)))
|
1892
|
+
args = array([[1.0, 2.0, 0.0],
|
1893
|
+
[1.0j, -1.0j, 0.0],
|
1894
|
+
[0.5, 1.0, 0.0],
|
1895
|
+
[-1.0+1.0j, 1.0j, 0.0],
|
1896
|
+
[2.0, 3.0, 4.0],
|
1897
|
+
[1.0j, -1.0j, 2.0],
|
1898
|
+
[-1.0+1.0j, 1.0j, 1.0-1.0j]])
|
1899
|
+
expected_results = array([1.3110287771461,
|
1900
|
+
1.8540746773014,
|
1901
|
+
1.8540746773014,
|
1902
|
+
0.79612586584234-1.2138566698365j,
|
1903
|
+
0.58408284167715,
|
1904
|
+
1.0441445654064,
|
1905
|
+
0.93912050218619-0.53296252018635j])
|
1906
|
+
for i, arr in enumerate(args):
|
1907
|
+
assert_allclose(elliprf(*arr), expected_results[i])
|
1908
|
+
|
1909
|
+
def test_elliprg(self):
|
1910
|
+
assert_allclose(elliprg(1, 1, 1), 1)
|
1911
|
+
assert_allclose(elliprg(0, 0, 1), 0.5)
|
1912
|
+
assert_allclose(elliprg(0, 0, 0), 0)
|
1913
|
+
assert np.isinf(elliprg(1, inf, 1))
|
1914
|
+
assert np.isinf(elliprg(complex(inf), 1, 1))
|
1915
|
+
args = array([[0.0, 16.0, 16.0],
|
1916
|
+
[2.0, 3.0, 4.0],
|
1917
|
+
[0.0, 1.0j, -1.0j],
|
1918
|
+
[-1.0+1.0j, 1.0j, 0.0],
|
1919
|
+
[-1.0j, -1.0+1.0j, 1.0j],
|
1920
|
+
[0.0, 0.0796, 4.0]])
|
1921
|
+
expected_results = array([np.pi,
|
1922
|
+
1.7255030280692,
|
1923
|
+
0.42360654239699,
|
1924
|
+
0.44660591677018+0.70768352357515j,
|
1925
|
+
0.36023392184473+0.40348623401722j,
|
1926
|
+
1.0284758090288])
|
1927
|
+
for i, arr in enumerate(args):
|
1928
|
+
assert_allclose(elliprg(*arr), expected_results[i])
|
1929
|
+
|
1930
|
+
def test_elliprj(self):
|
1931
|
+
assert_allclose(elliprj(1, 1, 1, 1), 1)
|
1932
|
+
assert elliprj(1, 1, inf, 1) == 0.0
|
1933
|
+
assert isnan(elliprj(1, 0, 0, 0))
|
1934
|
+
assert isnan(elliprj(-1, 1, 1, 1))
|
1935
|
+
assert elliprj(1, 1, 1, inf) == 0.0
|
1936
|
+
args = array([[0.0, 1.0, 2.0, 3.0],
|
1937
|
+
[2.0, 3.0, 4.0, 5.0],
|
1938
|
+
[2.0, 3.0, 4.0, -1.0+1.0j],
|
1939
|
+
[1.0j, -1.0j, 0.0, 2.0],
|
1940
|
+
[-1.0+1.0j, -1.0-1.0j, 1.0, 2.0],
|
1941
|
+
[1.0j, -1.0j, 0.0, 1.0-1.0j],
|
1942
|
+
[-1.0+1.0j, -1.0-1.0j, 1.0, -3.0+1.0j],
|
1943
|
+
[2.0, 3.0, 4.0, -0.5], # Cauchy principal value
|
1944
|
+
[2.0, 3.0, 4.0, -5.0]]) # Cauchy principal value
|
1945
|
+
expected_results = array([0.77688623778582,
|
1946
|
+
0.14297579667157,
|
1947
|
+
0.13613945827771-0.38207561624427j,
|
1948
|
+
1.6490011662711,
|
1949
|
+
0.94148358841220,
|
1950
|
+
1.8260115229009+1.2290661908643j,
|
1951
|
+
-0.61127970812028-1.0684038390007j,
|
1952
|
+
0.24723819703052, # Cauchy principal value
|
1953
|
+
-0.12711230042964]) # Caucny principal value
|
1954
|
+
for i, arr in enumerate(args):
|
1955
|
+
assert_allclose(elliprj(*arr), expected_results[i])
|
1956
|
+
|
1957
|
+
@pytest.mark.xfail(reason="Insufficient accuracy on 32-bit")
|
1958
|
+
def test_elliprj_hard(self):
|
1959
|
+
assert_allclose(elliprj(6.483625725195452e-08,
|
1960
|
+
1.1649136528196886e-27,
|
1961
|
+
3.6767340167168e+13,
|
1962
|
+
0.493704617023468),
|
1963
|
+
8.63426920644241857617477551054e-6,
|
1964
|
+
rtol=5e-15, atol=1e-20)
|
1965
|
+
assert_allclose(elliprj(14.375105857849121,
|
1966
|
+
9.993988969725365e-11,
|
1967
|
+
1.72844262269944e-26,
|
1968
|
+
5.898871222598245e-06),
|
1969
|
+
829774.1424801627252574054378691828,
|
1970
|
+
rtol=5e-15, atol=1e-20)
|
1971
|
+
|
1972
|
+
|
1973
|
+
class TestEllipLegendreCarlsonIdentities:
|
1974
|
+
"""Test identities expressing the Legendre elliptic integrals in terms
|
1975
|
+
of Carlson's symmetric integrals. These identities can be found
|
1976
|
+
in the DLMF https://dlmf.nist.gov/19.25#i .
|
1977
|
+
"""
|
1978
|
+
|
1979
|
+
def setup_class(self):
|
1980
|
+
self.m_n1_1 = np.arange(-1., 1., 0.01)
|
1981
|
+
# For double, this is -(2**1024)
|
1982
|
+
self.max_neg = finfo(double).min
|
1983
|
+
# Lots of very negative numbers
|
1984
|
+
self.very_neg_m = -1. * 2.**arange(-1 +
|
1985
|
+
np.log2(-self.max_neg), 0.,
|
1986
|
+
-1.)
|
1987
|
+
self.ms_up_to_1 = np.concatenate(([self.max_neg],
|
1988
|
+
self.very_neg_m,
|
1989
|
+
self.m_n1_1))
|
1990
|
+
|
1991
|
+
def test_k(self):
|
1992
|
+
"""Test identity:
|
1993
|
+
K(m) = R_F(0, 1-m, 1)
|
1994
|
+
"""
|
1995
|
+
m = self.ms_up_to_1
|
1996
|
+
assert_allclose(ellipk(m), elliprf(0., 1.-m, 1.))
|
1997
|
+
|
1998
|
+
def test_km1(self):
|
1999
|
+
"""Test identity:
|
2000
|
+
K(m) = R_F(0, 1-m, 1)
|
2001
|
+
But with the ellipkm1 function
|
2002
|
+
"""
|
2003
|
+
# For double, this is 2**-1022
|
2004
|
+
tiny = finfo(double).tiny
|
2005
|
+
# All these small powers of 2, up to 2**-1
|
2006
|
+
m1 = tiny * 2.**arange(0., -np.log2(tiny))
|
2007
|
+
assert_allclose(ellipkm1(m1), elliprf(0., m1, 1.))
|
2008
|
+
|
2009
|
+
def test_e(self):
|
2010
|
+
"""Test identity:
|
2011
|
+
E(m) = 2*R_G(0, 1-k^2, 1)
|
2012
|
+
"""
|
2013
|
+
m = self.ms_up_to_1
|
2014
|
+
assert_allclose(ellipe(m), 2.*elliprg(0., 1.-m, 1.))
|
2015
|
+
|
2016
|
+
|
2017
|
+
class TestErf:
|
2018
|
+
|
2019
|
+
def test_erf(self):
|
2020
|
+
er = special.erf(.25)
|
2021
|
+
assert_almost_equal(er,0.2763263902,8)
|
2022
|
+
|
2023
|
+
def test_erf_zeros(self):
|
2024
|
+
erz = special.erf_zeros(5)
|
2025
|
+
erzr = array([1.45061616+1.88094300j,
|
2026
|
+
2.24465928+2.61657514j,
|
2027
|
+
2.83974105+3.17562810j,
|
2028
|
+
3.33546074+3.64617438j,
|
2029
|
+
3.76900557+4.06069723j])
|
2030
|
+
assert_array_almost_equal(erz,erzr,4)
|
2031
|
+
|
2032
|
+
def _check_variant_func(self, func, other_func, rtol, atol=0):
|
2033
|
+
rng = np.random.RandomState(1234)
|
2034
|
+
n = 10000
|
2035
|
+
x = rng.pareto(0.02, n) * (2*rng.randint(0, 2, n) - 1)
|
2036
|
+
y = rng.pareto(0.02, n) * (2*rng.randint(0, 2, n) - 1)
|
2037
|
+
z = x + 1j*y
|
2038
|
+
|
2039
|
+
with np.errstate(all='ignore'):
|
2040
|
+
w = other_func(z)
|
2041
|
+
w_real = other_func(x).real
|
2042
|
+
|
2043
|
+
mask = np.isfinite(w)
|
2044
|
+
w = w[mask]
|
2045
|
+
z = z[mask]
|
2046
|
+
|
2047
|
+
mask = np.isfinite(w_real)
|
2048
|
+
w_real = w_real[mask]
|
2049
|
+
x = x[mask]
|
2050
|
+
|
2051
|
+
# test both real and complex variants
|
2052
|
+
assert_func_equal(func, w, z, rtol=rtol, atol=atol)
|
2053
|
+
assert_func_equal(func, w_real, x, rtol=rtol, atol=atol)
|
2054
|
+
|
2055
|
+
def test_erfc_consistent(self):
|
2056
|
+
self._check_variant_func(
|
2057
|
+
cephes.erfc,
|
2058
|
+
lambda z: 1 - cephes.erf(z),
|
2059
|
+
rtol=1e-12,
|
2060
|
+
atol=1e-14 # <- the test function loses precision
|
2061
|
+
)
|
2062
|
+
|
2063
|
+
def test_erfcx_consistent(self):
|
2064
|
+
self._check_variant_func(
|
2065
|
+
cephes.erfcx,
|
2066
|
+
lambda z: np.exp(z*z) * cephes.erfc(z),
|
2067
|
+
rtol=1e-12
|
2068
|
+
)
|
2069
|
+
|
2070
|
+
def test_erfi_consistent(self):
|
2071
|
+
self._check_variant_func(
|
2072
|
+
cephes.erfi,
|
2073
|
+
lambda z: -1j * cephes.erf(1j*z),
|
2074
|
+
rtol=1e-12
|
2075
|
+
)
|
2076
|
+
|
2077
|
+
def test_dawsn_consistent(self):
|
2078
|
+
self._check_variant_func(
|
2079
|
+
cephes.dawsn,
|
2080
|
+
lambda z: sqrt(pi)/2 * np.exp(-z*z) * cephes.erfi(z),
|
2081
|
+
rtol=1e-12
|
2082
|
+
)
|
2083
|
+
|
2084
|
+
def test_erf_nan_inf(self):
|
2085
|
+
vals = [np.nan, -np.inf, np.inf]
|
2086
|
+
expected = [np.nan, -1, 1]
|
2087
|
+
assert_allclose(special.erf(vals), expected, rtol=1e-15)
|
2088
|
+
|
2089
|
+
def test_erfc_nan_inf(self):
|
2090
|
+
vals = [np.nan, -np.inf, np.inf]
|
2091
|
+
expected = [np.nan, 2, 0]
|
2092
|
+
assert_allclose(special.erfc(vals), expected, rtol=1e-15)
|
2093
|
+
|
2094
|
+
def test_erfcx_nan_inf(self):
|
2095
|
+
vals = [np.nan, -np.inf, np.inf]
|
2096
|
+
expected = [np.nan, np.inf, 0]
|
2097
|
+
assert_allclose(special.erfcx(vals), expected, rtol=1e-15)
|
2098
|
+
|
2099
|
+
def test_erfi_nan_inf(self):
|
2100
|
+
vals = [np.nan, -np.inf, np.inf]
|
2101
|
+
expected = [np.nan, -np.inf, np.inf]
|
2102
|
+
assert_allclose(special.erfi(vals), expected, rtol=1e-15)
|
2103
|
+
|
2104
|
+
def test_dawsn_nan_inf(self):
|
2105
|
+
vals = [np.nan, -np.inf, np.inf]
|
2106
|
+
expected = [np.nan, -0.0, 0.0]
|
2107
|
+
assert_allclose(special.dawsn(vals), expected, rtol=1e-15)
|
2108
|
+
|
2109
|
+
def test_wofz_nan_inf(self):
|
2110
|
+
vals = [np.nan, -np.inf, np.inf]
|
2111
|
+
expected = [np.nan + np.nan * 1.j, 0.-0.j, 0.+0.j]
|
2112
|
+
assert_allclose(special.wofz(vals), expected, rtol=1e-15)
|
2113
|
+
|
2114
|
+
|
2115
|
+
class TestEuler:
|
2116
|
+
def test_euler(self):
|
2117
|
+
eu0 = special.euler(0)
|
2118
|
+
eu1 = special.euler(1)
|
2119
|
+
eu2 = special.euler(2) # just checking segfaults
|
2120
|
+
assert_allclose(eu0, [1], rtol=1e-15)
|
2121
|
+
assert_allclose(eu1, [1, 0], rtol=1e-15)
|
2122
|
+
assert_allclose(eu2, [1, 0, -1], rtol=1e-15)
|
2123
|
+
eu24 = special.euler(24)
|
2124
|
+
mathworld = [1,1,5,61,1385,50521,2702765,199360981,
|
2125
|
+
19391512145,2404879675441,
|
2126
|
+
370371188237525,69348874393137901,
|
2127
|
+
15514534163557086905]
|
2128
|
+
correct = zeros((25,),'d')
|
2129
|
+
for k in range(0,13):
|
2130
|
+
if (k % 2):
|
2131
|
+
correct[2*k] = -float(mathworld[k])
|
2132
|
+
else:
|
2133
|
+
correct[2*k] = float(mathworld[k])
|
2134
|
+
with np.errstate(all='ignore'):
|
2135
|
+
err = nan_to_num((eu24-correct)/correct)
|
2136
|
+
errmax = max(err)
|
2137
|
+
assert_almost_equal(errmax, 0.0, 14)
|
2138
|
+
|
2139
|
+
|
2140
|
+
class TestExp:
|
2141
|
+
def test_exp2(self):
|
2142
|
+
ex = special.exp2(2)
|
2143
|
+
exrl = 2**2
|
2144
|
+
assert_equal(ex,exrl)
|
2145
|
+
|
2146
|
+
def test_exp2more(self):
|
2147
|
+
exm = special.exp2(2.5)
|
2148
|
+
exmrl = 2**(2.5)
|
2149
|
+
assert_almost_equal(exm,exmrl,8)
|
2150
|
+
|
2151
|
+
def test_exp10(self):
|
2152
|
+
ex = special.exp10(2)
|
2153
|
+
exrl = 10**2
|
2154
|
+
assert_approx_equal(ex,exrl)
|
2155
|
+
|
2156
|
+
def test_exp10more(self):
|
2157
|
+
exm = special.exp10(2.5)
|
2158
|
+
exmrl = 10**(2.5)
|
2159
|
+
assert_almost_equal(exm,exmrl,8)
|
2160
|
+
|
2161
|
+
def test_expm1(self):
|
2162
|
+
ex = (special.expm1(2),special.expm1(3),special.expm1(4))
|
2163
|
+
exrl = (exp(2)-1,exp(3)-1,exp(4)-1)
|
2164
|
+
assert_array_almost_equal(ex,exrl,8)
|
2165
|
+
|
2166
|
+
def test_expm1more(self):
|
2167
|
+
ex1 = (special.expm1(2),special.expm1(2.1),special.expm1(2.2))
|
2168
|
+
exrl1 = (exp(2)-1,exp(2.1)-1,exp(2.2)-1)
|
2169
|
+
assert_array_almost_equal(ex1,exrl1,8)
|
2170
|
+
|
2171
|
+
|
2172
|
+
def assert_really_equal(x, y, rtol=None):
|
2173
|
+
"""
|
2174
|
+
Sharper assertion function that is stricter about matching types, not just values
|
2175
|
+
|
2176
|
+
This is useful/necessary in some cases:
|
2177
|
+
* dtypes for arrays that have the same _values_ (e.g. element 1.0 vs 1)
|
2178
|
+
* distinguishing complex from real NaN
|
2179
|
+
* result types for scalars
|
2180
|
+
|
2181
|
+
We still want to be able to allow a relative tolerance for the values though.
|
2182
|
+
The main logic comparison logic is handled by the xp_assert_* functions.
|
2183
|
+
"""
|
2184
|
+
def assert_func(x, y):
|
2185
|
+
xp_assert_equal(x, y) if rtol is None else xp_assert_close(x, y, rtol=rtol)
|
2186
|
+
|
2187
|
+
def assert_complex_nan(x):
|
2188
|
+
assert np.isnan(x.real) and np.isnan(x.imag)
|
2189
|
+
|
2190
|
+
assert type(x) is type(y), f"types not equal: {type(x)}, {type(y)}"
|
2191
|
+
|
2192
|
+
# ensure we also compare the values _within_ an array appropriately,
|
2193
|
+
# e.g. assert_equal does not distinguish different complex nans in arrays
|
2194
|
+
if isinstance(x, np.ndarray):
|
2195
|
+
# assert_equal does not compare (all) types, only values
|
2196
|
+
assert x.dtype == y.dtype
|
2197
|
+
# for empty arrays resp. to ensure shapes match
|
2198
|
+
assert_func(x, y)
|
2199
|
+
for elem_x, elem_y in zip(x.ravel(), y.ravel()):
|
2200
|
+
assert_really_equal(elem_x, elem_y, rtol=rtol)
|
2201
|
+
elif np.isnan(x) and np.isnan(y) and _is_subdtype(type(x), "c"):
|
2202
|
+
assert_complex_nan(x) and assert_complex_nan(y)
|
2203
|
+
# no need to consider complex infinities due to numpy/numpy#25493
|
2204
|
+
else:
|
2205
|
+
assert_func(x, y)
|
2206
|
+
|
2207
|
+
|
2208
|
+
class TestFactorialFunctions:
|
2209
|
+
def factorialk_ref(self, n, k, exact, extend):
|
2210
|
+
if exact:
|
2211
|
+
return special.factorialk(n, k=k, exact=True)
|
2212
|
+
# for details / explanation see factorialk-docstring
|
2213
|
+
r = np.mod(n, k) if extend == "zero" else 1
|
2214
|
+
vals = np.power(k, (n - r)/k) * special.gamma(n/k + 1) * special.rgamma(r/k + 1)
|
2215
|
+
# np.maximum is element-wise, which is what we want
|
2216
|
+
return vals * np.maximum(r, 1)
|
2217
|
+
|
2218
|
+
@pytest.mark.parametrize("exact,extend",
|
2219
|
+
[(True, "zero"), (False, "zero"), (False, "complex")])
|
2220
|
+
def test_factorialx_scalar_return_type(self, exact, extend):
|
2221
|
+
kw = {"exact": exact, "extend": extend}
|
2222
|
+
assert np.isscalar(special.factorial(1, **kw))
|
2223
|
+
assert np.isscalar(special.factorial2(1, **kw))
|
2224
|
+
assert np.isscalar(special.factorialk(1, k=3, **kw))
|
2225
|
+
|
2226
|
+
@pytest.mark.parametrize("n", [-1, -2, -3])
|
2227
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2228
|
+
def test_factorialx_negative_extend_zero(self, exact, n):
|
2229
|
+
kw = {"exact": exact}
|
2230
|
+
assert_equal(special.factorial(n, **kw), 0)
|
2231
|
+
assert_equal(special.factorial2(n, **kw), 0)
|
2232
|
+
assert_equal(special.factorialk(n, k=3, **kw), 0)
|
2233
|
+
|
2234
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2235
|
+
def test_factorialx_negative_extend_zero_array(self, exact):
|
2236
|
+
kw = {"exact": exact}
|
2237
|
+
rtol = 1e-15
|
2238
|
+
n = [-5, -4, 0, 1]
|
2239
|
+
# Consistent output for n < 0
|
2240
|
+
expected = np.array([0, 0, 1, 1], dtype=native_int if exact else np.float64)
|
2241
|
+
assert_really_equal(special.factorial(n, **kw), expected, rtol=rtol)
|
2242
|
+
assert_really_equal(special.factorial2(n, **kw), expected, rtol=rtol)
|
2243
|
+
assert_really_equal(special.factorialk(n, k=3, **kw), expected, rtol=rtol)
|
2244
|
+
|
2245
|
+
@pytest.mark.parametrize("n", [-1.1, -2.2, -3.3])
|
2246
|
+
def test_factorialx_negative_extend_complex(self, n):
|
2247
|
+
kw = {"extend": "complex"}
|
2248
|
+
exp_1 = {-1.1: -10.686287021193184771,
|
2249
|
+
-2.2: 4.8509571405220931958,
|
2250
|
+
-3.3: -1.4471073942559181166}
|
2251
|
+
exp_2 = {-1.1: 1.0725776858167496309,
|
2252
|
+
-2.2: -3.9777171783768419874,
|
2253
|
+
-3.3: -0.99588841846200555977}
|
2254
|
+
exp_k = {-1.1: 0.73565345382163025659,
|
2255
|
+
-2.2: 1.1749163167190809498,
|
2256
|
+
-3.3: -2.4780584257450583713}
|
2257
|
+
rtol = 3e-15
|
2258
|
+
assert_allclose(special.factorial(n, **kw), exp_1[n], rtol=rtol)
|
2259
|
+
assert_allclose(special.factorial2(n, **kw), exp_2[n], rtol=rtol)
|
2260
|
+
assert_allclose(special.factorialk(n, k=3, **kw), exp_k[n], rtol=rtol)
|
2261
|
+
assert_allclose(special.factorial([n], **kw)[0], exp_1[n], rtol=rtol)
|
2262
|
+
assert_allclose(special.factorial2([n], **kw)[0], exp_2[n], rtol=rtol)
|
2263
|
+
assert_allclose(special.factorialk([n], k=3, **kw)[0], exp_k[n], rtol=rtol)
|
2264
|
+
|
2265
|
+
@pytest.mark.parametrize("imag", [0, 0j])
|
2266
|
+
@pytest.mark.parametrize("n_outer", [-1, -2, -3])
|
2267
|
+
def test_factorialx_negative_extend_complex_poles(self, n_outer, imag):
|
2268
|
+
kw = {"extend": "complex"}
|
2269
|
+
def _check(n):
|
2270
|
+
complexify = _is_subdtype(type(n), "c")
|
2271
|
+
# like for gamma, we expect complex nans for complex inputs
|
2272
|
+
complex_nan = np.complex128("nan+nanj")
|
2273
|
+
exp = np.complex128("nan+nanj") if complexify else np.float64("nan")
|
2274
|
+
# poles are at negative integers that are multiples of k
|
2275
|
+
assert_really_equal(special.factorial(n, **kw), exp)
|
2276
|
+
assert_really_equal(special.factorial2(n * 2, **kw), exp)
|
2277
|
+
assert_really_equal(special.factorialk(n * 3, k=3, **kw), exp)
|
2278
|
+
# also test complex k for factorialk
|
2279
|
+
c = 1.5 - 2j
|
2280
|
+
assert_really_equal(special.factorialk(n * c, k=c, **kw), complex_nan)
|
2281
|
+
# same for array case
|
2282
|
+
assert_really_equal(special.factorial([n], **kw)[0], exp)
|
2283
|
+
assert_really_equal(special.factorial2([n * 2], **kw)[0], exp)
|
2284
|
+
assert_really_equal(special.factorialk([n * 3], k=3, **kw)[0], exp)
|
2285
|
+
assert_really_equal(special.factorialk([n * c], k=c, **kw)[0], complex_nan)
|
2286
|
+
# more specific tests in test_factorial{,2,k}_complex_reference
|
2287
|
+
|
2288
|
+
# imag ensures we test both real and complex representations of the poles
|
2289
|
+
_check(n_outer + imag)
|
2290
|
+
# check for large multiple of period
|
2291
|
+
_check(100_000 * n_outer + imag)
|
2292
|
+
|
2293
|
+
@pytest.mark.parametrize("boxed", [True, False])
|
2294
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2295
|
+
@pytest.mark.parametrize(
|
2296
|
+
"n",
|
2297
|
+
[
|
2298
|
+
np.nan, np.float64("nan"), np.nan + np.nan*1j, np.complex128("nan+nanj"),
|
2299
|
+
np.inf, np.inf + 0j, -np.inf, -np.inf + 0j, None, np.datetime64("nat")
|
2300
|
+
],
|
2301
|
+
ids=[
|
2302
|
+
"NaN", "np.float64('nan')", "NaN+i*NaN", "np.complex128('nan+nanj')",
|
2303
|
+
"inf", "inf+0i", "-inf", "-inf+0i", "None", "NaT"
|
2304
|
+
]
|
2305
|
+
)
|
2306
|
+
@pytest.mark.parametrize(
|
2307
|
+
"factorialx",
|
2308
|
+
[special.factorial, special.factorial2, special.factorialk]
|
2309
|
+
)
|
2310
|
+
def test_factorialx_inf_nan(self, factorialx, n, extend, boxed):
|
2311
|
+
# NaNs not allowed (by dtype) for exact=True
|
2312
|
+
kw = {"exact": False, "extend": extend}
|
2313
|
+
if factorialx == special.factorialk:
|
2314
|
+
kw["k"] = 3
|
2315
|
+
|
2316
|
+
# None is allowed for scalars, but would cause object type in array case
|
2317
|
+
permissible_types = ["i", "f", "c"] if boxed else ["i", "f", "c", type(None)]
|
2318
|
+
# factorial allows floats also for extend="zero"
|
2319
|
+
types_need_complex_ext = "c" if factorialx == special.factorial else ["f", "c"]
|
2320
|
+
|
2321
|
+
if not _is_subdtype(type(n), permissible_types):
|
2322
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2323
|
+
factorialx([n] if boxed else n, **kw)
|
2324
|
+
elif _is_subdtype(type(n), types_need_complex_ext) and extend != "complex":
|
2325
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2326
|
+
factorialx([n] if boxed else n, **kw)
|
2327
|
+
else:
|
2328
|
+
# account for type and whether extend="complex"
|
2329
|
+
complexify = (extend == "complex") and _is_subdtype(type(n), "c")
|
2330
|
+
# note that the type of the naïve `np.nan + np.nan * 1j` is `complex`
|
2331
|
+
# instead of `numpy.complex128`, which trips up assert_really_equal
|
2332
|
+
expected = np.complex128("nan+nanj") if complexify else np.float64("nan")
|
2333
|
+
# the only exception are real infinities
|
2334
|
+
if _is_subdtype(type(n), "f") and np.isinf(n):
|
2335
|
+
# unchanged for positive infinity; negative one depends on extension
|
2336
|
+
neg_inf_result = np.float64(0 if (extend == "zero") else "nan")
|
2337
|
+
expected = np.float64("inf") if (n > 0) else neg_inf_result
|
2338
|
+
|
2339
|
+
result = factorialx([n], **kw)[0] if boxed else factorialx(n, **kw)
|
2340
|
+
assert_really_equal(result, expected)
|
2341
|
+
# also tested in test_factorial{,2,k}_{array,scalar}_corner_cases
|
2342
|
+
|
2343
|
+
@pytest.mark.parametrize("extend", [0, 1.1, np.nan, "string"])
|
2344
|
+
def test_factorialx_raises_extend(self, extend):
|
2345
|
+
with pytest.raises(ValueError, match="argument `extend` must be.*"):
|
2346
|
+
special.factorial(1, extend=extend)
|
2347
|
+
with pytest.raises(ValueError, match="argument `extend` must be.*"):
|
2348
|
+
special.factorial2(1, extend=extend)
|
2349
|
+
with pytest.raises(ValueError, match="argument `extend` must be.*"):
|
2350
|
+
special.factorialk(1, k=3, exact=True, extend=extend)
|
2351
|
+
|
2352
|
+
@pytest.mark.parametrize("levels", range(1, 5))
|
2353
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2354
|
+
def test_factorialx_array_shape(self, levels, exact):
|
2355
|
+
def _nest_me(x, k=1):
|
2356
|
+
"""
|
2357
|
+
Double x and nest it k times
|
2358
|
+
|
2359
|
+
For example:
|
2360
|
+
>>> _nest_me([3, 4], 2)
|
2361
|
+
[[[3, 4], [3, 4]], [[3, 4], [3, 4]]]
|
2362
|
+
"""
|
2363
|
+
if k == 0:
|
2364
|
+
return x
|
2365
|
+
else:
|
2366
|
+
return _nest_me([x, x], k-1)
|
2367
|
+
|
2368
|
+
def _check(res, nucleus):
|
2369
|
+
exp = np.array(_nest_me(nucleus, k=levels), dtype=object)
|
2370
|
+
# test that ndarray shape is maintained
|
2371
|
+
# need to cast to float due to numpy/numpy#21220
|
2372
|
+
assert_allclose(res.astype(np.float64), exp.astype(np.float64))
|
2373
|
+
|
2374
|
+
n = np.array(_nest_me([5, 25], k=levels))
|
2375
|
+
exp_nucleus = {1: [120, math.factorial(25)],
|
2376
|
+
# correctness of factorial{2,k}() is tested elsewhere
|
2377
|
+
2: [15, special.factorial2(25, exact=True)],
|
2378
|
+
3: [10, special.factorialk(25, 3, exact=True)]}
|
2379
|
+
|
2380
|
+
_check(special.factorial(n, exact=exact), exp_nucleus[1])
|
2381
|
+
_check(special.factorial2(n, exact=exact), exp_nucleus[2])
|
2382
|
+
_check(special.factorialk(n, 3, exact=exact), exp_nucleus[3])
|
2383
|
+
|
2384
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2385
|
+
@pytest.mark.parametrize("dtype", [
|
2386
|
+
None, int, np.int8, np.int16, np.int32, np.int64,
|
2387
|
+
np.uint8, np.uint16, np.uint32, np.uint64
|
2388
|
+
])
|
2389
|
+
@pytest.mark.parametrize("dim", range(0, 5))
|
2390
|
+
def test_factorialx_array_dimension(self, dim, dtype, exact):
|
2391
|
+
n = np.array(5, dtype=dtype, ndmin=dim)
|
2392
|
+
exp = {1: 120, 2: 15, 3: 10}
|
2393
|
+
assert_allclose(special.factorial(n, exact=exact),
|
2394
|
+
np.array(exp[1], ndmin=dim))
|
2395
|
+
assert_allclose(special.factorial2(n, exact=exact),
|
2396
|
+
np.array(exp[2], ndmin=dim))
|
2397
|
+
assert_allclose(special.factorialk(n, 3, exact=exact),
|
2398
|
+
np.array(exp[3], ndmin=dim))
|
2399
|
+
|
2400
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2401
|
+
@pytest.mark.parametrize("level", range(1, 5))
|
2402
|
+
def test_factorialx_array_like(self, level, exact):
|
2403
|
+
def _nest_me(x, k=1):
|
2404
|
+
if k == 0:
|
2405
|
+
return x
|
2406
|
+
else:
|
2407
|
+
return _nest_me([x], k-1)
|
2408
|
+
|
2409
|
+
n = _nest_me([5], k=level-1) # nested list
|
2410
|
+
exp_nucleus = {1: 120, 2: 15, 3: 10}
|
2411
|
+
assert_func = assert_array_equal if exact else assert_allclose
|
2412
|
+
assert_func(special.factorial(n, exact=exact),
|
2413
|
+
np.array(exp_nucleus[1], ndmin=level))
|
2414
|
+
assert_func(special.factorial2(n, exact=exact),
|
2415
|
+
np.array(exp_nucleus[2], ndmin=level))
|
2416
|
+
assert_func(special.factorialk(n, 3, exact=exact),
|
2417
|
+
np.array(exp_nucleus[3], ndmin=level))
|
2418
|
+
|
2419
|
+
@pytest.mark.fail_slow(5)
|
2420
|
+
@pytest.mark.parametrize("dtype", [np.uint8, np.uint16, np.uint32, np.uint64])
|
2421
|
+
@pytest.mark.parametrize("exact,extend",
|
2422
|
+
[(True, "zero"), (False, "zero"), (False, "complex")])
|
2423
|
+
def test_factorialx_uint(self, exact, extend, dtype):
|
2424
|
+
# ensure that uint types work correctly as inputs
|
2425
|
+
kw = {"exact": exact, "extend": extend}
|
2426
|
+
assert_func = assert_array_equal if exact else assert_allclose
|
2427
|
+
def _check(n):
|
2428
|
+
n_ref = n.astype(np.int64) if isinstance(n, np.ndarray) else np.int64(n)
|
2429
|
+
assert_func(special.factorial(n, **kw), special.factorial(n_ref, **kw))
|
2430
|
+
assert_func(special.factorial2(n, **kw), special.factorial2(n_ref, **kw))
|
2431
|
+
assert_func(special.factorialk(n, k=3, **kw),
|
2432
|
+
special.factorialk(n_ref, k=3, **kw))
|
2433
|
+
def _check_inf(n):
|
2434
|
+
# produce inf of same type/dimension
|
2435
|
+
with suppress_warnings() as sup:
|
2436
|
+
sup.filter(RuntimeWarning)
|
2437
|
+
shaped_inf = n / 0
|
2438
|
+
assert_func(special.factorial(n, **kw), shaped_inf)
|
2439
|
+
assert_func(special.factorial2(n, **kw), shaped_inf)
|
2440
|
+
assert_func(special.factorialk(n, k=3, **kw), shaped_inf)
|
2441
|
+
|
2442
|
+
_check(dtype(0))
|
2443
|
+
_check(dtype(1))
|
2444
|
+
_check(np.array(0, dtype=dtype))
|
2445
|
+
_check(np.array([0, 1], dtype=dtype))
|
2446
|
+
# test that maximal uint values work as well
|
2447
|
+
N = dtype(np.iinfo(dtype).max)
|
2448
|
+
# TODO: cannot use N itself yet; factorial uses `gamma(N+1)` resp. `(hi+lo)//2`
|
2449
|
+
if dtype == np.uint64:
|
2450
|
+
if exact:
|
2451
|
+
# avoid attempting huge calculation
|
2452
|
+
pass
|
2453
|
+
elif np.lib.NumpyVersion(np.__version__) >= "2.0.0":
|
2454
|
+
# N does not fit into int64 --> cannot use _check
|
2455
|
+
_check_inf(dtype(N-1))
|
2456
|
+
_check_inf(np.array(N-1, dtype=dtype))
|
2457
|
+
_check_inf(np.array([N-1], dtype=dtype))
|
2458
|
+
elif dtype in [np.uint8, np.uint16] or not exact:
|
2459
|
+
# factorial(65535, exact=True) has 287189 digits and is calculated almost
|
2460
|
+
# instantaneously on modern hardware; however, dtypes bigger than uint16
|
2461
|
+
# would blow up runtime and memory consumption for exact=True
|
2462
|
+
_check(N-1)
|
2463
|
+
_check(np.array(N-1, dtype=dtype))
|
2464
|
+
_check(np.array([N-2, N-1], dtype=dtype))
|
2465
|
+
|
2466
|
+
# note that n=170 is the last integer such that factorial(n) fits float64
|
2467
|
+
@pytest.mark.parametrize('n', range(30, 180, 10))
|
2468
|
+
def test_factorial_accuracy(self, n):
|
2469
|
+
# Compare exact=True vs False, i.e. that the accuracy of the
|
2470
|
+
# approximation is better than the specified tolerance.
|
2471
|
+
|
2472
|
+
rtol = 6e-14 if sys.platform == 'win32' else 1e-15
|
2473
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2474
|
+
assert_allclose(float(special.factorial(n, exact=True)),
|
2475
|
+
special.factorial(n, exact=False), rtol=rtol)
|
2476
|
+
assert_allclose(special.factorial([n], exact=True).astype(float),
|
2477
|
+
special.factorial([n], exact=False), rtol=rtol)
|
2478
|
+
|
2479
|
+
@pytest.mark.parametrize('n',
|
2480
|
+
list(range(0, 22)) + list(range(30, 180, 10)))
|
2481
|
+
def test_factorial_int_reference(self, n):
|
2482
|
+
# Compare all with math.factorial
|
2483
|
+
correct = math.factorial(n)
|
2484
|
+
assert_array_equal(correct, special.factorial(n, exact=True))
|
2485
|
+
assert_array_equal(correct, special.factorial([n], exact=True)[0])
|
2486
|
+
|
2487
|
+
rtol = 8e-14 if sys.platform == 'win32' else 1e-15
|
2488
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2489
|
+
correct = float(correct)
|
2490
|
+
assert_allclose(correct, special.factorial(n, exact=False), rtol=rtol)
|
2491
|
+
assert_allclose(correct, special.factorial([n], exact=False)[0], rtol=rtol)
|
2492
|
+
|
2493
|
+
# extend="complex" only works for exact=False
|
2494
|
+
kw = {"exact": False, "extend": "complex"}
|
2495
|
+
assert_allclose(correct, special.factorial(n, **kw), rtol=rtol)
|
2496
|
+
assert_allclose(correct, special.factorial([n], **kw)[0], rtol=rtol)
|
2497
|
+
|
2498
|
+
def test_factorial_float_reference(self):
|
2499
|
+
def _check(n, expected):
|
2500
|
+
rtol = 8e-14 if sys.platform == 'win32' else 1e-15
|
2501
|
+
assert_allclose(special.factorial(n), expected, rtol=rtol)
|
2502
|
+
assert_allclose(special.factorial([n])[0], expected, rtol=rtol)
|
2503
|
+
# using floats with `exact=True` raises an error for scalars and arrays
|
2504
|
+
with pytest.raises(ValueError, match="`exact=True` only supports.*"):
|
2505
|
+
special.factorial(n, exact=True)
|
2506
|
+
with pytest.raises(ValueError, match="`exact=True` only supports.*"):
|
2507
|
+
special.factorial([n], exact=True)
|
2508
|
+
|
2509
|
+
# Reference values from mpmath for gamma(n+1)
|
2510
|
+
_check(0.01, 0.994325851191506032181932988)
|
2511
|
+
_check(1.11, 1.051609009483625091514147465)
|
2512
|
+
_check(5.55, 314.9503192327208241614959052)
|
2513
|
+
_check(11.1, 50983227.84411615655137170553)
|
2514
|
+
_check(33.3, 2.493363339642036352229215273e+37)
|
2515
|
+
_check(55.5, 9.479934358436729043289162027e+73)
|
2516
|
+
_check(77.7, 3.060540559059579022358692625e+114)
|
2517
|
+
_check(99.9, 5.885840419492871504575693337e+157)
|
2518
|
+
# close to maximum for float64
|
2519
|
+
_check(170.6243, 1.79698185749571048960082e+308)
|
2520
|
+
|
2521
|
+
def test_factorial_complex_reference(self):
|
2522
|
+
def _check(n, expected):
|
2523
|
+
rtol = 3e-15 if sys.platform == 'win32' else 2e-15
|
2524
|
+
kw = {"exact": False, "extend": "complex"}
|
2525
|
+
assert_allclose(special.factorial(n, **kw), expected, rtol=rtol)
|
2526
|
+
assert_allclose(special.factorial([n], **kw)[0], expected, rtol=rtol)
|
2527
|
+
|
2528
|
+
# Reference values from mpmath.gamma(n+1)
|
2529
|
+
# negative & complex values
|
2530
|
+
_check(-0.5, expected=1.7724538509055160276)
|
2531
|
+
_check(-0.5 + 0j, expected=1.7724538509055160276 + 0j)
|
2532
|
+
_check(2 + 2j, expected=-0.42263728631120216694 + 0.87181425569650686062j)
|
2533
|
+
# close to poles
|
2534
|
+
_check(-0.9999, expected=9999.422883232725532)
|
2535
|
+
_check(-1 + 0.0001j, expected=-0.57721565582674219 - 9999.9999010944009697j)
|
2536
|
+
|
2537
|
+
@pytest.mark.parametrize("dtype", [np.int64, np.float64,
|
2538
|
+
np.complex128, object])
|
2539
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2540
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2541
|
+
@pytest.mark.parametrize("dim", range(0, 5))
|
2542
|
+
# test empty & non-empty arrays, with nans and mixed
|
2543
|
+
@pytest.mark.parametrize(
|
2544
|
+
"content",
|
2545
|
+
[[], [1], [1.1], [np.nan], [np.nan + np.nan * 1j], [np.nan, 1]],
|
2546
|
+
ids=["[]", "[1]", "[1.1]", "[NaN]", "[NaN+i*NaN]", "[NaN, 1]"],
|
2547
|
+
)
|
2548
|
+
def test_factorial_array_corner_cases(self, content, dim, exact, extend, dtype):
|
2549
|
+
if dtype is object and SCIPY_ARRAY_API:
|
2550
|
+
pytest.skip("object arrays unsupported in array API mode")
|
2551
|
+
# get dtype without calling array constructor (that might fail or mutate)
|
2552
|
+
if dtype is np.int64 and any(np.isnan(x) or (x != int(x)) for x in content):
|
2553
|
+
pytest.skip("impossible combination")
|
2554
|
+
if dtype == np.float64 and any(_is_subdtype(type(x), "c") for x in content):
|
2555
|
+
pytest.skip("impossible combination")
|
2556
|
+
|
2557
|
+
kw = {"exact": exact, "extend": extend}
|
2558
|
+
# np.array(x, ndim=0) will not be 0-dim. unless x is too
|
2559
|
+
content = content if (dim > 0 or len(content) != 1) else content[0]
|
2560
|
+
n = np.array(content, ndmin=dim, dtype=dtype)
|
2561
|
+
|
2562
|
+
result = None
|
2563
|
+
if extend == "complex" and exact:
|
2564
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2565
|
+
special.factorial(n, **kw)
|
2566
|
+
elif not _is_subdtype(n.dtype, ["i", "f", "c"]):
|
2567
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2568
|
+
special.factorial(n, **kw)
|
2569
|
+
elif _is_subdtype(n.dtype, "c") and extend != "complex":
|
2570
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2571
|
+
special.factorial(n, **kw)
|
2572
|
+
elif exact and not _is_subdtype(n.dtype, "i"):
|
2573
|
+
with pytest.raises(ValueError, match="`exact=True` only supports.*"):
|
2574
|
+
special.factorial(n, **kw)
|
2575
|
+
else:
|
2576
|
+
result = special.factorial(n, **kw)
|
2577
|
+
|
2578
|
+
if result is not None:
|
2579
|
+
# use scalar case as reference; tested separately in *_scalar_corner_cases
|
2580
|
+
ref = [special.factorial(x, **kw) for x in n.ravel()]
|
2581
|
+
# unpack length-1 lists so that np.array(x, ndim=0) works correctly
|
2582
|
+
ref = ref[0] if len(ref) == 1 else ref
|
2583
|
+
# result is empty if and only if n is empty, and has the same dimension
|
2584
|
+
# as n; dtype stays the same, except when not empty and not exact:
|
2585
|
+
if n.size:
|
2586
|
+
cx = (extend == "complex") and _is_subdtype(n.dtype, "c")
|
2587
|
+
dtype = np.complex128 if cx else (native_int if exact else np.float64)
|
2588
|
+
expected = np.array(ref, ndmin=dim, dtype=dtype)
|
2589
|
+
assert_really_equal(result, expected, rtol=1e-15)
|
2590
|
+
|
2591
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2592
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2593
|
+
@pytest.mark.parametrize("n", [1, 1.1, 2 + 2j, np.nan, np.nan + np.nan*1j, None],
|
2594
|
+
ids=["1", "1.1", "2+2j", "NaN", "NaN+i*NaN", "None"])
|
2595
|
+
def test_factorial_scalar_corner_cases(self, n, exact, extend):
|
2596
|
+
kw = {"exact": exact, "extend": extend}
|
2597
|
+
if extend == "complex" and exact:
|
2598
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2599
|
+
special.factorial(n, **kw)
|
2600
|
+
elif not _is_subdtype(type(n), ["i", "f", "c", type(None)]):
|
2601
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2602
|
+
special.factorial(n, **kw)
|
2603
|
+
elif _is_subdtype(type(n), "c") and extend != "complex":
|
2604
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2605
|
+
special.factorial(n, **kw)
|
2606
|
+
elif n is None or np.isnan(n):
|
2607
|
+
# account for dtype and whether extend="complex"
|
2608
|
+
complexify = (extend == "complex") and _is_subdtype(type(n), "c")
|
2609
|
+
expected = np.complex128("nan+nanj") if complexify else np.float64("nan")
|
2610
|
+
assert_really_equal(special.factorial(n, **kw), expected)
|
2611
|
+
elif exact and _is_subdtype(type(n), "f"):
|
2612
|
+
with pytest.raises(ValueError, match="`exact=True` only supports.*"):
|
2613
|
+
special.factorial(n, **kw)
|
2614
|
+
else:
|
2615
|
+
assert_equal(special.factorial(n, **kw), special.gamma(n + 1))
|
2616
|
+
|
2617
|
+
# use odd increment to make sure both odd & even numbers are tested!
|
2618
|
+
@pytest.mark.parametrize('n', range(30, 180, 11))
|
2619
|
+
def test_factorial2_accuracy(self, n):
|
2620
|
+
# Compare exact=True vs False, i.e. that the accuracy of the
|
2621
|
+
# approximation is better than the specified tolerance.
|
2622
|
+
|
2623
|
+
rtol = 2e-14 if sys.platform == 'win32' else 1e-15
|
2624
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2625
|
+
assert_allclose(float(special.factorial2(n, exact=True)),
|
2626
|
+
special.factorial2(n, exact=False), rtol=rtol)
|
2627
|
+
assert_allclose(special.factorial2([n], exact=True).astype(float),
|
2628
|
+
special.factorial2([n], exact=False), rtol=rtol)
|
2629
|
+
|
2630
|
+
@pytest.mark.parametrize('n',
|
2631
|
+
list(range(0, 22)) + list(range(30, 180, 11)))
|
2632
|
+
def test_factorial2_int_reference(self, n):
|
2633
|
+
# Compare all with correct value
|
2634
|
+
|
2635
|
+
# Cannot use np.product due to overflow
|
2636
|
+
correct = functools.reduce(operator.mul, list(range(n, 0, -2)), 1)
|
2637
|
+
|
2638
|
+
assert_array_equal(correct, special.factorial2(n, exact=True))
|
2639
|
+
assert_array_equal(correct, special.factorial2([n], exact=True)[0])
|
2640
|
+
|
2641
|
+
rtol = 2e-14 if sys.platform == 'win32' else 1e-15
|
2642
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2643
|
+
correct = float(correct)
|
2644
|
+
assert_allclose(correct, special.factorial2(n, exact=False), rtol=rtol)
|
2645
|
+
assert_allclose(correct, special.factorial2([n], exact=False)[0], rtol=rtol)
|
2646
|
+
|
2647
|
+
# extend="complex" only works for exact=False
|
2648
|
+
kw = {"exact": False, "extend": "complex"}
|
2649
|
+
# approximation only matches exactly for `n == 1 (mod k)`, see docstring
|
2650
|
+
if n % 2 == 1:
|
2651
|
+
assert_allclose(correct, special.factorial2(n, **kw), rtol=rtol)
|
2652
|
+
assert_allclose(correct, special.factorial2([n], **kw)[0], rtol=rtol)
|
2653
|
+
|
2654
|
+
def test_factorial2_complex_reference(self):
|
2655
|
+
# this tests for both floats and complex
|
2656
|
+
def _check(n, expected):
|
2657
|
+
rtol = 5e-15
|
2658
|
+
kw = {"exact": False, "extend": "complex"}
|
2659
|
+
assert_allclose(special.factorial2(n, **kw), expected, rtol=rtol)
|
2660
|
+
assert_allclose(special.factorial2([n], **kw)[0], expected, rtol=rtol)
|
2661
|
+
|
2662
|
+
# Reference values from mpmath for:
|
2663
|
+
# mpmath.power(2, n/2) * mpmath.gamma(n/2 + 1) * mpmath.sqrt(2 / mpmath.pi)
|
2664
|
+
_check(3, expected=3)
|
2665
|
+
_check(4, expected=special.factorial2(4) * math.sqrt(2 / math.pi))
|
2666
|
+
_check(20, expected=special.factorial2(20) * math.sqrt(2 / math.pi))
|
2667
|
+
# negative & complex values
|
2668
|
+
_check(-0.5, expected=0.82217895866245855122)
|
2669
|
+
_check(-0.5 + 0j, expected=0.82217895866245855122 + 0j)
|
2670
|
+
_check(3 + 3j, expected=-1.0742236630142471526 + 1.4421398439387262897j)
|
2671
|
+
# close to poles
|
2672
|
+
_check(-1.9999, expected=7978.8918745523440682)
|
2673
|
+
_check(-2 + 0.0001j, expected=0.0462499835314308444 - 7978.84559148876374493j)
|
2674
|
+
|
2675
|
+
@pytest.mark.parametrize("dtype", [np.int64, np.float64,
|
2676
|
+
np.complex128, object])
|
2677
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2678
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2679
|
+
@pytest.mark.parametrize("dim", range(0, 5))
|
2680
|
+
# test empty & non-empty arrays, with nans and mixed
|
2681
|
+
@pytest.mark.parametrize(
|
2682
|
+
"content",
|
2683
|
+
[[], [1], [1.1], [np.nan], [np.nan + np.nan * 1j], [np.nan, 1]],
|
2684
|
+
ids=["[]", "[1]", "[1.1]", "[NaN]", "[NaN+i*NaN]", "[NaN, 1]"],
|
2685
|
+
)
|
2686
|
+
def test_factorial2_array_corner_cases(self, content, dim, exact, extend, dtype):
|
2687
|
+
# get dtype without calling array constructor (that might fail or mutate)
|
2688
|
+
if dtype == np.int64 and any(np.isnan(x) or (x != int(x)) for x in content):
|
2689
|
+
pytest.skip("impossible combination")
|
2690
|
+
if dtype == np.float64 and any(_is_subdtype(type(x), "c") for x in content):
|
2691
|
+
pytest.skip("impossible combination")
|
2692
|
+
|
2693
|
+
kw = {"exact": exact, "extend": extend}
|
2694
|
+
# np.array(x, ndim=0) will not be 0-dim. unless x is too
|
2695
|
+
content = content if (dim > 0 or len(content) != 1) else content[0]
|
2696
|
+
n = np.array(content, ndmin=dim, dtype=dtype)
|
2697
|
+
|
2698
|
+
result = None
|
2699
|
+
if extend == "complex" and exact:
|
2700
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2701
|
+
special.factorial2(n, **kw)
|
2702
|
+
elif not _is_subdtype(n.dtype, ["i", "f", "c"]):
|
2703
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2704
|
+
special.factorial2(n, **kw)
|
2705
|
+
elif _is_subdtype(n.dtype, ["f", "c"]) and extend != "complex":
|
2706
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2707
|
+
special.factorial2(n, **kw)
|
2708
|
+
else:
|
2709
|
+
result = special.factorial2(n, **kw)
|
2710
|
+
|
2711
|
+
if result is not None:
|
2712
|
+
# use scalar case as reference; tested separately in *_scalar_corner_cases
|
2713
|
+
ref = [special.factorial2(x, **kw) for x in n.ravel()]
|
2714
|
+
# unpack length-1 lists so that np.array(x, ndim=0) works correctly
|
2715
|
+
ref = ref[0] if len(ref) == 1 else ref
|
2716
|
+
# result is empty if and only if n is empty, and has the same dimension
|
2717
|
+
# as n; dtype stays the same, except when not empty and not exact:
|
2718
|
+
if n.size:
|
2719
|
+
cx = (extend == "complex") and _is_subdtype(n.dtype, "c")
|
2720
|
+
dtype = np.complex128 if cx else (native_int if exact else np.float64)
|
2721
|
+
expected = np.array(ref, ndmin=dim, dtype=dtype)
|
2722
|
+
assert_really_equal(result, expected, rtol=2e-15)
|
2723
|
+
|
2724
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2725
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2726
|
+
@pytest.mark.parametrize("n", [1, 1.1, 2 + 2j, np.nan, np.nan + np.nan*1j, None],
|
2727
|
+
ids=["1", "1.1", "2+2j", "NaN", "NaN+i*NaN", "None"])
|
2728
|
+
def test_factorial2_scalar_corner_cases(self, n, exact, extend):
|
2729
|
+
kw = {"exact": exact, "extend": extend}
|
2730
|
+
if extend == "complex" and exact:
|
2731
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2732
|
+
special.factorial2(n, **kw)
|
2733
|
+
elif not _is_subdtype(type(n), ["i", "f", "c", type(None)]):
|
2734
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2735
|
+
special.factorial2(n, **kw)
|
2736
|
+
elif _is_subdtype(type(n), ["f", "c"]) and extend != "complex":
|
2737
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2738
|
+
special.factorial2(n, **kw)
|
2739
|
+
elif n is None or np.isnan(n):
|
2740
|
+
# account for dtype and whether extend="complex"
|
2741
|
+
complexify = (extend == "complex") and _is_subdtype(type(n), "c")
|
2742
|
+
expected = np.complex128("nan+nanj") if complexify else np.float64("nan")
|
2743
|
+
assert_really_equal(special.factorial2(n, **kw), expected)
|
2744
|
+
else:
|
2745
|
+
expected = self.factorialk_ref(n, k=2, **kw)
|
2746
|
+
assert_really_equal(special.factorial2(n, **kw), expected, rtol=1e-15)
|
2747
|
+
|
2748
|
+
@pytest.mark.parametrize("k", range(1, 5))
|
2749
|
+
# note that n=170 is the last integer such that factorial(n) fits float64;
|
2750
|
+
# use odd increment to make sure both odd & even numbers are tested
|
2751
|
+
@pytest.mark.parametrize('n', range(170, 20, -29))
|
2752
|
+
def test_factorialk_accuracy(self, n, k):
|
2753
|
+
# Compare exact=True vs False, i.e. that the accuracy of the
|
2754
|
+
# approximation is better than the specified tolerance.
|
2755
|
+
|
2756
|
+
rtol = 6e-14 if sys.platform == 'win32' else 2e-14
|
2757
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2758
|
+
assert_allclose(float(special.factorialk(n, k=k, exact=True)),
|
2759
|
+
special.factorialk(n, k=k, exact=False), rtol=rtol)
|
2760
|
+
assert_allclose(special.factorialk([n], k=k, exact=True).astype(float),
|
2761
|
+
special.factorialk([n], k=k, exact=False), rtol=rtol)
|
2762
|
+
|
2763
|
+
@pytest.mark.parametrize('k', list(range(1, 5)) + [10, 20])
|
2764
|
+
@pytest.mark.parametrize('n',
|
2765
|
+
list(range(0, 22)) + list(range(22, 100, 11)))
|
2766
|
+
def test_factorialk_int_reference(self, n, k):
|
2767
|
+
# Compare all with correct value
|
2768
|
+
|
2769
|
+
# Would be nice to use np.product here, but that's
|
2770
|
+
# broken on windows, see numpy/numpy#21219
|
2771
|
+
correct = functools.reduce(operator.mul, list(range(n, 0, -k)), 1)
|
2772
|
+
|
2773
|
+
assert_array_equal(correct, special.factorialk(n, k, exact=True))
|
2774
|
+
assert_array_equal(correct, special.factorialk([n], k, exact=True)[0])
|
2775
|
+
|
2776
|
+
rtol = 3e-14 if sys.platform == 'win32' else 1e-14
|
2777
|
+
# need to cast exact result to float due to numpy/numpy#21220
|
2778
|
+
correct = float(correct)
|
2779
|
+
assert_allclose(correct, special.factorialk(n, k, exact=False), rtol=rtol)
|
2780
|
+
assert_allclose(correct, special.factorialk([n], k, exact=False)[0], rtol=rtol)
|
2781
|
+
|
2782
|
+
# extend="complex" only works for exact=False
|
2783
|
+
kw = {"k": k, "exact": False, "extend": "complex"}
|
2784
|
+
# approximation only matches exactly for `n == 1 (mod k)`, see docstring
|
2785
|
+
if n % k == 1:
|
2786
|
+
rtol = 2e-14
|
2787
|
+
assert_allclose(correct, special.factorialk(n, **kw), rtol=rtol)
|
2788
|
+
assert_allclose(correct, special.factorialk([n], **kw)[0], rtol=rtol)
|
2789
|
+
|
2790
|
+
def test_factorialk_complex_reference(self):
|
2791
|
+
# this tests for both floats and complex
|
2792
|
+
def _check(n, k, exp):
|
2793
|
+
rtol = 1e-14
|
2794
|
+
kw = {"k": k, "exact": False, "extend": "complex"}
|
2795
|
+
assert_allclose(special.factorialk(n, **kw), exp, rtol=rtol)
|
2796
|
+
assert_allclose(special.factorialk([n], **kw)[0], exp, rtol=rtol)
|
2797
|
+
|
2798
|
+
# Reference values from mpmath for:
|
2799
|
+
# mpmath.power(k, (n-1)/k) * mpmath.gamma(n/k + 1) / mpmath.gamma(1/k + 1)
|
2800
|
+
_check(n=4, k=3, exp=special.factorialk(4, k=3, exact=True))
|
2801
|
+
_check(n=5, k=3, exp=7.29011132947227083)
|
2802
|
+
_check(n=6.5, k=3, exp=19.6805080113566010)
|
2803
|
+
# non-integer k
|
2804
|
+
_check(n=3, k=2.5, exp=2.58465740293218541)
|
2805
|
+
_check(n=11, k=2.5, exp=1963.5) # ==11*8.5*6*3.5; c.f. n == 1 (mod k)
|
2806
|
+
_check(n=-3 + 3j + 1, k=-3 + 3j, exp=-2 + 3j)
|
2807
|
+
# complex values
|
2808
|
+
_check(n=4 + 4j, k=4, exp=-0.67855904082768043854 + 2.1993925819930311497j)
|
2809
|
+
_check(n=4, k=4 - 4j, exp=1.9775338957222718742 + 0.92607172675423901371j)
|
2810
|
+
_check(n=4 + 4j, k=4 - 4j, exp=0.1868492880824934475 + 0.87660580316894290247j)
|
2811
|
+
# negative values
|
2812
|
+
_check(n=-0.5, k=3, exp=0.72981013240713739354)
|
2813
|
+
_check(n=-0.5 + 0j, k=3, exp=0.72981013240713739354 + 0j)
|
2814
|
+
_check(n=2.9, k=-0.7, exp=0.45396591474966867296 + 0.56925525174685228866j)
|
2815
|
+
_check(n=-0.6, k=-0.7, exp=-0.07190820089634757334 - 0.090170031876701730081j)
|
2816
|
+
# close to poles
|
2817
|
+
_check(n=-2.9999, k=3, exp=7764.7170695908828364)
|
2818
|
+
_check(n=-3 + 0.0001j, k=3, exp=0.1349475632879599864 - 7764.5821055158365027j)
|
2819
|
+
|
2820
|
+
@pytest.mark.parametrize("dtype", [np.int64, np.float64,
|
2821
|
+
np.complex128, object])
|
2822
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2823
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2824
|
+
@pytest.mark.parametrize("dim", range(0, 5))
|
2825
|
+
# test empty & non-empty arrays, with nans and mixed
|
2826
|
+
@pytest.mark.parametrize(
|
2827
|
+
"content",
|
2828
|
+
[[], [1], [1.1], [np.nan], [np.nan + np.nan * 1j], [np.nan, 1]],
|
2829
|
+
ids=["[]", "[1]", "[1.1]", "[NaN]", "[NaN+i*NaN]", "[NaN, 1]"],
|
2830
|
+
)
|
2831
|
+
def test_factorialk_array_corner_cases(self, content, dim, exact, extend, dtype):
|
2832
|
+
# get dtype without calling array constructor (that might fail or mutate)
|
2833
|
+
if dtype == np.int64 and any(np.isnan(x) or (x != int(x)) for x in content):
|
2834
|
+
pytest.skip("impossible combination")
|
2835
|
+
if dtype == np.float64 and any(_is_subdtype(type(x), "c") for x in content):
|
2836
|
+
pytest.skip("impossible combination")
|
2837
|
+
|
2838
|
+
kw = {"k": 3, "exact": exact, "extend": extend}
|
2839
|
+
# np.array(x, ndim=0) will not be 0-dim. unless x is too
|
2840
|
+
content = content if (dim > 0 or len(content) != 1) else content[0]
|
2841
|
+
n = np.array(content, ndmin=dim, dtype=dtype)
|
2842
|
+
|
2843
|
+
result = None
|
2844
|
+
if extend == "complex" and exact:
|
2845
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2846
|
+
special.factorialk(n, **kw)
|
2847
|
+
elif not _is_subdtype(n.dtype, ["i", "f", "c"]):
|
2848
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2849
|
+
special.factorialk(n, **kw)
|
2850
|
+
elif _is_subdtype(n.dtype, ["f", "c"]) and extend != "complex":
|
2851
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2852
|
+
special.factorialk(n, **kw)
|
2853
|
+
else:
|
2854
|
+
result = special.factorialk(n, **kw)
|
2855
|
+
|
2856
|
+
if result is not None:
|
2857
|
+
# use scalar case as reference; tested separately in *_scalar_corner_cases
|
2858
|
+
ref = [special.factorialk(x, **kw) for x in n.ravel()]
|
2859
|
+
# unpack length-1 lists so that np.array(x, ndim=0) works correctly
|
2860
|
+
ref = ref[0] if len(ref) == 1 else ref
|
2861
|
+
# result is empty if and only if n is empty, and has the same dimension
|
2862
|
+
# as n; dtype stays the same, except when not empty and not exact:
|
2863
|
+
if n.size:
|
2864
|
+
cx = (extend == "complex") and _is_subdtype(n.dtype, "c")
|
2865
|
+
dtype = np.complex128 if cx else (native_int if exact else np.float64)
|
2866
|
+
expected = np.array(ref, ndmin=dim, dtype=dtype)
|
2867
|
+
assert_really_equal(result, expected, rtol=2e-15)
|
2868
|
+
|
2869
|
+
@pytest.mark.parametrize("extend", ["zero", "complex"])
|
2870
|
+
@pytest.mark.parametrize("exact", [True, False])
|
2871
|
+
@pytest.mark.parametrize("k", range(1, 5))
|
2872
|
+
@pytest.mark.parametrize("n", [1, 1.1, 2 + 2j, np.nan, np.nan + np.nan*1j, None],
|
2873
|
+
ids=["1", "1.1", "2+2j", "NaN", "NaN+i*NaN", "None"])
|
2874
|
+
def test_factorialk_scalar_corner_cases(self, n, k, exact, extend):
|
2875
|
+
kw = {"k": k, "exact": exact, "extend": extend}
|
2876
|
+
if extend == "complex" and exact:
|
2877
|
+
with pytest.raises(ValueError, match="Incompatible options:.*"):
|
2878
|
+
special.factorialk(n, **kw)
|
2879
|
+
elif not _is_subdtype(type(n), ["i", "f", "c", type(None)]):
|
2880
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2881
|
+
special.factorialk(n, **kw)
|
2882
|
+
elif _is_subdtype(type(n), ["f", "c"]) and extend != "complex":
|
2883
|
+
with pytest.raises(ValueError, match="In order to use non-integer.*"):
|
2884
|
+
special.factorialk(n, **kw)
|
2885
|
+
elif n is None or np.isnan(n):
|
2886
|
+
# account for dtype and whether extend="complex"
|
2887
|
+
complexify = (extend == "complex") and _is_subdtype(type(n), "c")
|
2888
|
+
expected = np.complex128("nan+nanj") if complexify else np.float64("nan")
|
2889
|
+
assert_really_equal(special.factorialk(n, **kw), expected)
|
2890
|
+
else:
|
2891
|
+
expected = self.factorialk_ref(n, **kw)
|
2892
|
+
assert_really_equal(special.factorialk(n, **kw), expected, rtol=1e-15)
|
2893
|
+
|
2894
|
+
@pytest.mark.parametrize("boxed", [True, False])
|
2895
|
+
@pytest.mark.parametrize("exact,extend",
|
2896
|
+
[(True, "zero"), (False, "zero"), (False, "complex")])
|
2897
|
+
@pytest.mark.parametrize("k", [-1, -1.0, 0, 0.0, 0 + 1j, 1.1, np.nan])
|
2898
|
+
def test_factorialk_raises_k_complex(self, k, exact, extend, boxed):
|
2899
|
+
n = [1] if boxed else 1
|
2900
|
+
kw = {"k": k, "exact": exact, "extend": extend}
|
2901
|
+
if extend == "zero":
|
2902
|
+
msg = "In order to use non-integer.*"
|
2903
|
+
if _is_subdtype(type(k), "i") and (k < 1):
|
2904
|
+
msg = "For `extend='zero'`.*"
|
2905
|
+
with pytest.raises(ValueError, match=msg):
|
2906
|
+
special.factorialk(n, **kw)
|
2907
|
+
elif k == 0:
|
2908
|
+
with pytest.raises(ValueError, match="Parameter k cannot be zero!"):
|
2909
|
+
special.factorialk(n, **kw)
|
2910
|
+
else:
|
2911
|
+
# no error
|
2912
|
+
special.factorialk(n, **kw)
|
2913
|
+
|
2914
|
+
@pytest.mark.parametrize("boxed", [True, False])
|
2915
|
+
@pytest.mark.parametrize("exact,extend",
|
2916
|
+
[(True, "zero"), (False, "zero"), (False, "complex")])
|
2917
|
+
# neither integer, float nor complex
|
2918
|
+
@pytest.mark.parametrize("k", ["string", np.datetime64("nat")],
|
2919
|
+
ids=["string", "NaT"])
|
2920
|
+
def test_factorialk_raises_k_other(self, k, exact, extend, boxed):
|
2921
|
+
n = [1] if boxed else 1
|
2922
|
+
kw = {"k": k, "exact": exact, "extend": extend}
|
2923
|
+
with pytest.raises(ValueError, match="Unsupported data type.*"):
|
2924
|
+
special.factorialk(n, **kw)
|
2925
|
+
|
2926
|
+
@pytest.mark.parametrize("exact,extend",
|
2927
|
+
[(True, "zero"), (False, "zero"), (False, "complex")])
|
2928
|
+
@pytest.mark.parametrize("k", range(1, 12))
|
2929
|
+
def test_factorialk_dtype(self, k, exact, extend):
|
2930
|
+
kw = {"k": k, "exact": exact, "extend": extend}
|
2931
|
+
if exact and k in _FACTORIALK_LIMITS_64BITS.keys():
|
2932
|
+
n = np.array([_FACTORIALK_LIMITS_32BITS[k]])
|
2933
|
+
assert_equal(special.factorialk(n, **kw).dtype, np_long)
|
2934
|
+
assert_equal(special.factorialk(n + 1, **kw).dtype, np.int64)
|
2935
|
+
# assert maximality of limits for given dtype
|
2936
|
+
assert special.factorialk(n + 1, **kw) > np.iinfo(np.int32).max
|
2937
|
+
|
2938
|
+
n = np.array([_FACTORIALK_LIMITS_64BITS[k]])
|
2939
|
+
assert_equal(special.factorialk(n, **kw).dtype, np.int64)
|
2940
|
+
assert_equal(special.factorialk(n + 1, **kw).dtype, object)
|
2941
|
+
assert special.factorialk(n + 1, **kw) > np.iinfo(np.int64).max
|
2942
|
+
else:
|
2943
|
+
n = np.array([_FACTORIALK_LIMITS_64BITS.get(k, 1)])
|
2944
|
+
# for exact=True and k >= 10, we always return object;
|
2945
|
+
# for exact=False it's always float (unless input is complex)
|
2946
|
+
dtype = object if exact else np.float64
|
2947
|
+
assert_equal(special.factorialk(n, **kw).dtype, dtype)
|
2948
|
+
|
2949
|
+
def test_factorial_mixed_nan_inputs(self):
|
2950
|
+
x = np.array([np.nan, 1, 2, 3, np.nan])
|
2951
|
+
expected = np.array([np.nan, 1, 2, 6, np.nan])
|
2952
|
+
assert_equal(special.factorial(x, exact=False), expected)
|
2953
|
+
with pytest.raises(ValueError, match="`exact=True` only supports.*"):
|
2954
|
+
special.factorial(x, exact=True)
|
2955
|
+
|
2956
|
+
|
2957
|
+
class TestFresnel:
|
2958
|
+
@pytest.mark.parametrize("z, s, c", [
|
2959
|
+
# some positive value
|
2960
|
+
(.5, 0.064732432859999287, 0.49234422587144644),
|
2961
|
+
(.5 + .0j, 0.064732432859999287, 0.49234422587144644),
|
2962
|
+
# negative half annulus
|
2963
|
+
# https://github.com/scipy/scipy/issues/12309
|
2964
|
+
# Reference values can be reproduced with
|
2965
|
+
# https://www.wolframalpha.com/input/?i=FresnelS%5B-2.0+%2B+0.1i%5D
|
2966
|
+
# https://www.wolframalpha.com/input/?i=FresnelC%5B-2.0+%2B+0.1i%5D
|
2967
|
+
(
|
2968
|
+
-2.0 + 0.1j,
|
2969
|
+
-0.3109538687728942-0.0005870728836383176j,
|
2970
|
+
-0.4879956866358554+0.10670801832903172j
|
2971
|
+
),
|
2972
|
+
(
|
2973
|
+
-0.1 - 1.5j,
|
2974
|
+
-0.03918309471866977+0.7197508454568574j,
|
2975
|
+
0.09605692502968956-0.43625191013617465j
|
2976
|
+
),
|
2977
|
+
# a different algorithm kicks in for "large" values, i.e., |z| >= 4.5,
|
2978
|
+
# make sure to test both float and complex values; a different
|
2979
|
+
# algorithm is used
|
2980
|
+
(6.0, 0.44696076, 0.49953147),
|
2981
|
+
(6.0 + 0.0j, 0.44696076, 0.49953147),
|
2982
|
+
(6.0j, -0.44696076j, 0.49953147j),
|
2983
|
+
(-6.0 + 0.0j, -0.44696076, -0.49953147),
|
2984
|
+
(-6.0j, 0.44696076j, -0.49953147j),
|
2985
|
+
# inf
|
2986
|
+
(np.inf, 0.5, 0.5),
|
2987
|
+
(-np.inf, -0.5, -0.5),
|
2988
|
+
])
|
2989
|
+
def test_fresnel_values(self, z, s, c):
|
2990
|
+
frs = array(special.fresnel(z))
|
2991
|
+
assert_array_almost_equal(frs, array([s, c]), 8)
|
2992
|
+
|
2993
|
+
# values from pg 329 Table 7.11 of A & S
|
2994
|
+
# slightly corrected in 4th decimal place
|
2995
|
+
def test_fresnel_zeros(self):
|
2996
|
+
szo, czo = special.fresnel_zeros(5)
|
2997
|
+
assert_array_almost_equal(szo,
|
2998
|
+
array([2.0093+0.2885j,
|
2999
|
+
2.8335+0.2443j,
|
3000
|
+
3.4675+0.2185j,
|
3001
|
+
4.0026+0.2009j,
|
3002
|
+
4.4742+0.1877j]),3)
|
3003
|
+
assert_array_almost_equal(czo,
|
3004
|
+
array([1.7437+0.3057j,
|
3005
|
+
2.6515+0.2529j,
|
3006
|
+
3.3204+0.2240j,
|
3007
|
+
3.8757+0.2047j,
|
3008
|
+
4.3611+0.1907j]),3)
|
3009
|
+
vals1 = special.fresnel(szo)[0]
|
3010
|
+
vals2 = special.fresnel(czo)[1]
|
3011
|
+
assert_array_almost_equal(vals1,0,14)
|
3012
|
+
assert_array_almost_equal(vals2,0,14)
|
3013
|
+
|
3014
|
+
def test_fresnelc_zeros(self):
|
3015
|
+
szo, czo = special.fresnel_zeros(6)
|
3016
|
+
frc = special.fresnelc_zeros(6)
|
3017
|
+
assert_array_almost_equal(frc,czo,12)
|
3018
|
+
|
3019
|
+
def test_fresnels_zeros(self):
|
3020
|
+
szo, czo = special.fresnel_zeros(5)
|
3021
|
+
frs = special.fresnels_zeros(5)
|
3022
|
+
assert_array_almost_equal(frs,szo,12)
|
3023
|
+
|
3024
|
+
|
3025
|
+
class TestGamma:
|
3026
|
+
def test_gamma(self):
|
3027
|
+
gam = special.gamma(5)
|
3028
|
+
assert_equal(gam,24.0)
|
3029
|
+
|
3030
|
+
def test_gammaln(self):
|
3031
|
+
gamln = special.gammaln(3)
|
3032
|
+
lngam = log(special.gamma(3))
|
3033
|
+
assert_almost_equal(gamln,lngam,8)
|
3034
|
+
|
3035
|
+
def test_gammainccinv(self):
|
3036
|
+
gccinv = special.gammainccinv(.5,.5)
|
3037
|
+
gcinv = special.gammaincinv(.5,.5)
|
3038
|
+
assert_almost_equal(gccinv,gcinv,8)
|
3039
|
+
|
3040
|
+
@with_special_errors
|
3041
|
+
def test_gammaincinv(self):
|
3042
|
+
y = special.gammaincinv(.4,.4)
|
3043
|
+
x = special.gammainc(.4,y)
|
3044
|
+
assert_almost_equal(x,0.4,1)
|
3045
|
+
y = special.gammainc(10, 0.05)
|
3046
|
+
x = special.gammaincinv(10, 2.5715803516000736e-20)
|
3047
|
+
assert_almost_equal(0.05, x, decimal=10)
|
3048
|
+
assert_almost_equal(y, 2.5715803516000736e-20, decimal=10)
|
3049
|
+
x = special.gammaincinv(50, 8.20754777388471303050299243573393e-18)
|
3050
|
+
assert_almost_equal(11.0, x, decimal=10)
|
3051
|
+
|
3052
|
+
@with_special_errors
|
3053
|
+
def test_975(self):
|
3054
|
+
# Regression test for ticket #975 -- switch point in algorithm
|
3055
|
+
# check that things work OK at the point, immediately next floats
|
3056
|
+
# around it, and a bit further away
|
3057
|
+
pts = [0.25,
|
3058
|
+
np.nextafter(0.25, 0), 0.25 - 1e-12,
|
3059
|
+
np.nextafter(0.25, 1), 0.25 + 1e-12]
|
3060
|
+
for pt in pts:
|
3061
|
+
y = special.gammaincinv(.4, pt)
|
3062
|
+
x = special.gammainc(0.4, y)
|
3063
|
+
assert_allclose(x, pt, rtol=1e-12)
|
3064
|
+
|
3065
|
+
def test_rgamma(self):
|
3066
|
+
rgam = special.rgamma(8)
|
3067
|
+
rlgam = 1/special.gamma(8)
|
3068
|
+
assert_almost_equal(rgam,rlgam,8)
|
3069
|
+
|
3070
|
+
def test_infinity(self):
|
3071
|
+
assert_equal(special.rgamma(-1), 0)
|
3072
|
+
|
3073
|
+
@pytest.mark.parametrize(
|
3074
|
+
"x,expected",
|
3075
|
+
[
|
3076
|
+
# infinities
|
3077
|
+
([-np.inf, np.inf], [np.nan, np.inf]),
|
3078
|
+
# negative and positive zero
|
3079
|
+
([-0.0, 0.0], [-np.inf, np.inf]),
|
3080
|
+
# small poles
|
3081
|
+
(range(-32, 0), np.full(32, np.nan)),
|
3082
|
+
# medium sized poles
|
3083
|
+
(range(-1024, -32, 99), np.full(11, np.nan)),
|
3084
|
+
# large pole
|
3085
|
+
([-4.141512231792294e+16], [np.nan]),
|
3086
|
+
]
|
3087
|
+
)
|
3088
|
+
def test_poles(self, x, expected):
|
3089
|
+
assert_array_equal(special.gamma(x), expected)
|
3090
|
+
|
3091
|
+
|
3092
|
+
class TestHankel:
|
3093
|
+
|
3094
|
+
def test_negv1(self):
|
3095
|
+
assert_almost_equal(special.hankel1(-3,2), -special.hankel1(3,2), 14)
|
3096
|
+
|
3097
|
+
def test_hankel1(self):
|
3098
|
+
hank1 = special.hankel1(1,.1)
|
3099
|
+
hankrl = (special.jv(1,.1) + special.yv(1,.1)*1j)
|
3100
|
+
assert_almost_equal(hank1,hankrl,8)
|
3101
|
+
|
3102
|
+
def test_negv1e(self):
|
3103
|
+
assert_almost_equal(special.hankel1e(-3,2), -special.hankel1e(3,2), 14)
|
3104
|
+
|
3105
|
+
def test_hankel1e(self):
|
3106
|
+
hank1e = special.hankel1e(1,.1)
|
3107
|
+
hankrle = special.hankel1(1,.1)*exp(-.1j)
|
3108
|
+
assert_almost_equal(hank1e,hankrle,8)
|
3109
|
+
|
3110
|
+
def test_negv2(self):
|
3111
|
+
assert_almost_equal(special.hankel2(-3,2), -special.hankel2(3,2), 14)
|
3112
|
+
|
3113
|
+
def test_hankel2(self):
|
3114
|
+
hank2 = special.hankel2(1,.1)
|
3115
|
+
hankrl2 = (special.jv(1,.1) - special.yv(1,.1)*1j)
|
3116
|
+
assert_almost_equal(hank2,hankrl2,8)
|
3117
|
+
|
3118
|
+
def test_neg2e(self):
|
3119
|
+
assert_almost_equal(special.hankel2e(-3,2), -special.hankel2e(3,2), 14)
|
3120
|
+
|
3121
|
+
def test_hankl2e(self):
|
3122
|
+
hank2e = special.hankel2e(1,.1)
|
3123
|
+
hankrl2e = special.hankel2e(1,.1)
|
3124
|
+
assert_almost_equal(hank2e,hankrl2e,8)
|
3125
|
+
|
3126
|
+
def test_hankel2_gh4517(self):
|
3127
|
+
# Test edge case reported in https://github.com/scipy/scipy/issues/4517
|
3128
|
+
res = special.hankel2(0, 0)
|
3129
|
+
assert np.isnan(res.real)
|
3130
|
+
assert np.isposinf(res.imag)
|
3131
|
+
|
3132
|
+
|
3133
|
+
class TestHyper:
|
3134
|
+
def test_h1vp(self):
|
3135
|
+
h1 = special.h1vp(1,.1)
|
3136
|
+
h1real = (special.jvp(1,.1) + special.yvp(1,.1)*1j)
|
3137
|
+
assert_almost_equal(h1,h1real,8)
|
3138
|
+
|
3139
|
+
def test_h2vp(self):
|
3140
|
+
h2 = special.h2vp(1,.1)
|
3141
|
+
h2real = (special.jvp(1,.1) - special.yvp(1,.1)*1j)
|
3142
|
+
assert_almost_equal(h2,h2real,8)
|
3143
|
+
|
3144
|
+
def test_hyp0f1(self):
|
3145
|
+
# scalar input
|
3146
|
+
assert_allclose(special.hyp0f1(2.5, 0.5), 1.21482702689997, rtol=1e-12)
|
3147
|
+
assert_allclose(special.hyp0f1(2.5, 0), 1.0, rtol=1e-15)
|
3148
|
+
|
3149
|
+
# float input, expected values match mpmath
|
3150
|
+
x = special.hyp0f1(3.0, [-1.5, -1, 0, 1, 1.5])
|
3151
|
+
expected = np.array([0.58493659229143, 0.70566805723127, 1.0,
|
3152
|
+
1.37789689539747, 1.60373685288480])
|
3153
|
+
assert_allclose(x, expected, rtol=1e-12)
|
3154
|
+
|
3155
|
+
# complex input
|
3156
|
+
x = special.hyp0f1(3.0, np.array([-1.5, -1, 0, 1, 1.5]) + 0.j)
|
3157
|
+
assert_allclose(x, expected.astype(complex), rtol=1e-12)
|
3158
|
+
|
3159
|
+
# test broadcasting
|
3160
|
+
x1 = [0.5, 1.5, 2.5]
|
3161
|
+
x2 = [0, 1, 0.5]
|
3162
|
+
x = special.hyp0f1(x1, x2)
|
3163
|
+
expected = [1.0, 1.8134302039235093, 1.21482702689997]
|
3164
|
+
assert_allclose(x, expected, rtol=1e-12)
|
3165
|
+
x = special.hyp0f1(np.vstack([x1] * 2), x2)
|
3166
|
+
assert_allclose(x, np.vstack([expected] * 2), rtol=1e-12)
|
3167
|
+
assert_raises(ValueError, special.hyp0f1,
|
3168
|
+
np.vstack([x1] * 3), [0, 1])
|
3169
|
+
|
3170
|
+
def test_hyp0f1_gh5764(self):
|
3171
|
+
# Just checks the point that failed; there's a more systematic
|
3172
|
+
# test in test_mpmath
|
3173
|
+
res = special.hyp0f1(0.8, 0.5 + 0.5*1J)
|
3174
|
+
# The expected value was generated using mpmath
|
3175
|
+
assert_almost_equal(res, 1.6139719776441115 + 1J*0.80893054061790665)
|
3176
|
+
|
3177
|
+
def test_hyp1f1(self):
|
3178
|
+
hyp1 = special.hyp1f1(.1,.1,.3)
|
3179
|
+
assert_almost_equal(hyp1, 1.3498588075760032,7)
|
3180
|
+
|
3181
|
+
# test contributed by Moritz Deger (2008-05-29)
|
3182
|
+
# https://github.com/scipy/scipy/issues/1186 (Trac #659)
|
3183
|
+
|
3184
|
+
# reference data obtained from mathematica [ a, b, x, m(a,b,x)]:
|
3185
|
+
# produced with test_hyp1f1.nb
|
3186
|
+
ref_data = array([
|
3187
|
+
[-8.38132975e+00, -1.28436461e+01, -2.91081397e+01, 1.04178330e+04],
|
3188
|
+
[2.91076882e+00, -6.35234333e+00, -1.27083993e+01, 6.68132725e+00],
|
3189
|
+
[-1.42938258e+01, 1.80869131e-01, 1.90038728e+01, 1.01385897e+05],
|
3190
|
+
[5.84069088e+00, 1.33187908e+01, 2.91290106e+01, 1.59469411e+08],
|
3191
|
+
[-2.70433202e+01, -1.16274873e+01, -2.89582384e+01, 1.39900152e+24],
|
3192
|
+
[4.26344966e+00, -2.32701773e+01, 1.91635759e+01, 6.13816915e+21],
|
3193
|
+
[1.20514340e+01, -3.40260240e+00, 7.26832235e+00, 1.17696112e+13],
|
3194
|
+
[2.77372955e+01, -1.99424687e+00, 3.61332246e+00, 3.07419615e+13],
|
3195
|
+
[1.50310939e+01, -2.91198675e+01, -1.53581080e+01, -3.79166033e+02],
|
3196
|
+
[1.43995827e+01, 9.84311196e+00, 1.93204553e+01, 2.55836264e+10],
|
3197
|
+
[-4.08759686e+00, 1.34437025e+01, -1.42072843e+01, 1.70778449e+01],
|
3198
|
+
[8.05595738e+00, -1.31019838e+01, 1.52180721e+01, 3.06233294e+21],
|
3199
|
+
[1.81815804e+01, -1.42908793e+01, 9.57868793e+00, -2.84771348e+20],
|
3200
|
+
[-2.49671396e+01, 1.25082843e+01, -1.71562286e+01, 2.36290426e+07],
|
3201
|
+
[2.67277673e+01, 1.70315414e+01, 6.12701450e+00, 7.77917232e+03],
|
3202
|
+
[2.49565476e+01, 2.91694684e+01, 6.29622660e+00, 2.35300027e+02],
|
3203
|
+
[6.11924542e+00, -1.59943768e+00, 9.57009289e+00, 1.32906326e+11],
|
3204
|
+
[-1.47863653e+01, 2.41691301e+01, -1.89981821e+01, 2.73064953e+03],
|
3205
|
+
[2.24070483e+01, -2.93647433e+00, 8.19281432e+00, -6.42000372e+17],
|
3206
|
+
[8.04042600e-01, 1.82710085e+01, -1.97814534e+01, 5.48372441e-01],
|
3207
|
+
[1.39590390e+01, 1.97318686e+01, 2.37606635e+00, 5.51923681e+00],
|
3208
|
+
[-4.66640483e+00, -2.00237930e+01, 7.40365095e+00, 4.50310752e+00],
|
3209
|
+
[2.76821999e+01, -6.36563968e+00, 1.11533984e+01, -9.28725179e+23],
|
3210
|
+
[-2.56764457e+01, 1.24544906e+00, 1.06407572e+01, 1.25922076e+01],
|
3211
|
+
[3.20447808e+00, 1.30874383e+01, 2.26098014e+01, 2.03202059e+04],
|
3212
|
+
[-1.24809647e+01, 4.15137113e+00, -2.92265700e+01, 2.39621411e+08],
|
3213
|
+
[2.14778108e+01, -2.35162960e+00, -1.13758664e+01, 4.46882152e-01],
|
3214
|
+
[-9.85469168e+00, -3.28157680e+00, 1.67447548e+01, -1.07342390e+07],
|
3215
|
+
[1.08122310e+01, -2.47353236e+01, -1.15622349e+01, -2.91733796e+03],
|
3216
|
+
[-2.67933347e+01, -3.39100709e+00, 2.56006986e+01, -5.29275382e+09],
|
3217
|
+
[-8.60066776e+00, -8.02200924e+00, 1.07231926e+01, 1.33548320e+06],
|
3218
|
+
[-1.01724238e-01, -1.18479709e+01, -2.55407104e+01, 1.55436570e+00],
|
3219
|
+
[-3.93356771e+00, 2.11106818e+01, -2.57598485e+01, 2.13467840e+01],
|
3220
|
+
[3.74750503e+00, 1.55687633e+01, -2.92841720e+01, 1.43873509e-02],
|
3221
|
+
[6.99726781e+00, 2.69855571e+01, -1.63707771e+01, 3.08098673e-02],
|
3222
|
+
[-2.31996011e+01, 3.47631054e+00, 9.75119815e-01, 1.79971073e-02],
|
3223
|
+
[2.38951044e+01, -2.91460190e+01, -2.50774708e+00, 9.56934814e+00],
|
3224
|
+
[1.52730825e+01, 5.77062507e+00, 1.21922003e+01, 1.32345307e+09],
|
3225
|
+
[1.74673917e+01, 1.89723426e+01, 4.94903250e+00, 9.90859484e+01],
|
3226
|
+
[1.88971241e+01, 2.86255413e+01, 5.52360109e-01, 1.44165360e+00],
|
3227
|
+
[1.02002319e+01, -1.66855152e+01, -2.55426235e+01, 6.56481554e+02],
|
3228
|
+
[-1.79474153e+01, 1.22210200e+01, -1.84058212e+01, 8.24041812e+05],
|
3229
|
+
[-1.36147103e+01, 1.32365492e+00, -7.22375200e+00, 9.92446491e+05],
|
3230
|
+
[7.57407832e+00, 2.59738234e+01, -1.34139168e+01, 3.64037761e-02],
|
3231
|
+
[2.21110169e+00, 1.28012666e+01, 1.62529102e+01, 1.33433085e+02],
|
3232
|
+
[-2.64297569e+01, -1.63176658e+01, -1.11642006e+01, -2.44797251e+13],
|
3233
|
+
[-2.46622944e+01, -3.02147372e+00, 8.29159315e+00, -3.21799070e+05],
|
3234
|
+
[-1.37215095e+01, -1.96680183e+01, 2.91940118e+01, 3.21457520e+12],
|
3235
|
+
[-5.45566105e+00, 2.81292086e+01, 1.72548215e-01, 9.66973000e-01],
|
3236
|
+
[-1.55751298e+00, -8.65703373e+00, 2.68622026e+01, -3.17190834e+16],
|
3237
|
+
[2.45393609e+01, -2.70571903e+01, 1.96815505e+01, 1.80708004e+37],
|
3238
|
+
[5.77482829e+00, 1.53203143e+01, 2.50534322e+01, 1.14304242e+06],
|
3239
|
+
[-1.02626819e+01, 2.36887658e+01, -2.32152102e+01, 7.28965646e+02],
|
3240
|
+
[-1.30833446e+00, -1.28310210e+01, 1.87275544e+01, -9.33487904e+12],
|
3241
|
+
[5.83024676e+00, -1.49279672e+01, 2.44957538e+01, -7.61083070e+27],
|
3242
|
+
[-2.03130747e+01, 2.59641715e+01, -2.06174328e+01, 4.54744859e+04],
|
3243
|
+
[1.97684551e+01, -2.21410519e+01, -2.26728740e+01, 3.53113026e+06],
|
3244
|
+
[2.73673444e+01, 2.64491725e+01, 1.57599882e+01, 1.07385118e+07],
|
3245
|
+
[5.73287971e+00, 1.21111904e+01, 1.33080171e+01, 2.63220467e+03],
|
3246
|
+
[-2.82751072e+01, 2.08605881e+01, 9.09838900e+00, -6.60957033e-07],
|
3247
|
+
[1.87270691e+01, -1.74437016e+01, 1.52413599e+01, 6.59572851e+27],
|
3248
|
+
[6.60681457e+00, -2.69449855e+00, 9.78972047e+00, -2.38587870e+12],
|
3249
|
+
[1.20895561e+01, -2.51355765e+01, 2.30096101e+01, 7.58739886e+32],
|
3250
|
+
[-2.44682278e+01, 2.10673441e+01, -1.36705538e+01, 4.54213550e+04],
|
3251
|
+
[-4.50665152e+00, 3.72292059e+00, -4.83403707e+00, 2.68938214e+01],
|
3252
|
+
[-7.46540049e+00, -1.08422222e+01, -1.72203805e+01, -2.09402162e+02],
|
3253
|
+
[-2.00307551e+01, -7.50604431e+00, -2.78640020e+01, 4.15985444e+19],
|
3254
|
+
[1.99890876e+01, 2.20677419e+01, -2.51301778e+01, 1.23840297e-09],
|
3255
|
+
[2.03183823e+01, -7.66942559e+00, 2.10340070e+01, 1.46285095e+31],
|
3256
|
+
[-2.90315825e+00, -2.55785967e+01, -9.58779316e+00, 2.65714264e-01],
|
3257
|
+
[2.73960829e+01, -1.80097203e+01, -2.03070131e+00, 2.52908999e+02],
|
3258
|
+
[-2.11708058e+01, -2.70304032e+01, 2.48257944e+01, 3.09027527e+08],
|
3259
|
+
[2.21959758e+01, 4.00258675e+00, -1.62853977e+01, -9.16280090e-09],
|
3260
|
+
[1.61661840e+01, -2.26845150e+01, 2.17226940e+01, -8.24774394e+33],
|
3261
|
+
[-3.35030306e+00, 1.32670581e+00, 9.39711214e+00, -1.47303163e+01],
|
3262
|
+
[7.23720726e+00, -2.29763909e+01, 2.34709682e+01, -9.20711735e+29],
|
3263
|
+
[2.71013568e+01, 1.61951087e+01, -7.11388906e-01, 2.98750911e-01],
|
3264
|
+
[8.40057933e+00, -7.49665220e+00, 2.95587388e+01, 6.59465635e+29],
|
3265
|
+
[-1.51603423e+01, 1.94032322e+01, -7.60044357e+00, 1.05186941e+02],
|
3266
|
+
[-8.83788031e+00, -2.72018313e+01, 1.88269907e+00, 1.81687019e+00],
|
3267
|
+
[-1.87283712e+01, 5.87479570e+00, -1.91210203e+01, 2.52235612e+08],
|
3268
|
+
[-5.61338513e-01, 2.69490237e+01, 1.16660111e-01, 9.97567783e-01],
|
3269
|
+
[-5.44354025e+00, -1.26721408e+01, -4.66831036e+00, 1.06660735e-01],
|
3270
|
+
[-2.18846497e+00, 2.33299566e+01, 9.62564397e+00, 3.03842061e-01],
|
3271
|
+
[6.65661299e+00, -2.39048713e+01, 1.04191807e+01, 4.73700451e+13],
|
3272
|
+
[-2.57298921e+01, -2.60811296e+01, 2.74398110e+01, -5.32566307e+11],
|
3273
|
+
[-1.11431826e+01, -1.59420160e+01, -1.84880553e+01, -1.01514747e+02],
|
3274
|
+
[6.50301931e+00, 2.59859051e+01, -2.33270137e+01, 1.22760500e-02],
|
3275
|
+
[-1.94987891e+01, -2.62123262e+01, 3.90323225e+00, 1.71658894e+01],
|
3276
|
+
[7.26164601e+00, -1.41469402e+01, 2.81499763e+01, -2.50068329e+31],
|
3277
|
+
[-1.52424040e+01, 2.99719005e+01, -2.85753678e+01, 1.31906693e+04],
|
3278
|
+
[5.24149291e+00, -1.72807223e+01, 2.22129493e+01, 2.50748475e+25],
|
3279
|
+
[3.63207230e-01, -9.54120862e-02, -2.83874044e+01, 9.43854939e-01],
|
3280
|
+
[-2.11326457e+00, -1.25707023e+01, 1.17172130e+00, 1.20812698e+00],
|
3281
|
+
[2.48513582e+00, 1.03652647e+01, -1.84625148e+01, 6.47910997e-02],
|
3282
|
+
[2.65395942e+01, 2.74794672e+01, 1.29413428e+01, 2.89306132e+05],
|
3283
|
+
[-9.49445460e+00, 1.59930921e+01, -1.49596331e+01, 3.27574841e+02],
|
3284
|
+
[-5.89173945e+00, 9.96742426e+00, 2.60318889e+01, -3.15842908e-01],
|
3285
|
+
[-1.15387239e+01, -2.21433107e+01, -2.17686413e+01, 1.56724718e-01],
|
3286
|
+
[-5.30592244e+00, -2.42752190e+01, 1.29734035e+00, 1.31985534e+00]
|
3287
|
+
])
|
3288
|
+
|
3289
|
+
for a,b,c,expected in ref_data:
|
3290
|
+
result = special.hyp1f1(a,b,c)
|
3291
|
+
assert_(abs(expected - result)/expected < 1e-4)
|
3292
|
+
|
3293
|
+
def test_hyp1f1_gh2957(self):
|
3294
|
+
hyp1 = special.hyp1f1(0.5, 1.5, -709.7827128933)
|
3295
|
+
hyp2 = special.hyp1f1(0.5, 1.5, -709.7827128934)
|
3296
|
+
assert_almost_equal(hyp1, hyp2, 12)
|
3297
|
+
|
3298
|
+
def test_hyp1f1_gh2282(self):
|
3299
|
+
hyp = special.hyp1f1(0.5, 1.5, -1000)
|
3300
|
+
assert_almost_equal(hyp, 0.028024956081989643, 12)
|
3301
|
+
|
3302
|
+
def test_hyp2f1(self):
|
3303
|
+
# a collection of special cases taken from AMS 55
|
3304
|
+
values = [
|
3305
|
+
[0.5, 1, 1.5, 0.2**2, 0.5/0.2*log((1+0.2)/(1-0.2))],
|
3306
|
+
[0.5, 1, 1.5, -0.2**2, 1./0.2*arctan(0.2)],
|
3307
|
+
[1, 1, 2, 0.2, -1/0.2*log(1-0.2)],
|
3308
|
+
[3, 3.5, 1.5, 0.2**2, 0.5/0.2/(-5)*((1+0.2)**(-5)-(1-0.2)**(-5))],
|
3309
|
+
[-3, 3, 0.5, sin(0.2)**2, cos(2*3*0.2)],
|
3310
|
+
[3, 4, 8, 1,
|
3311
|
+
special.gamma(8) * special.gamma(8-4-3)
|
3312
|
+
/ special.gamma(8-3) / special.gamma(8-4)],
|
3313
|
+
[3, 2, 3-2+1, -1,
|
3314
|
+
1./2**3*sqrt(pi) * special.gamma(1+3-2)
|
3315
|
+
/ special.gamma(1+0.5*3-2) / special.gamma(0.5+0.5*3)],
|
3316
|
+
[5, 2, 5-2+1, -1,
|
3317
|
+
1./2**5*sqrt(pi) * special.gamma(1+5-2)
|
3318
|
+
/ special.gamma(1+0.5*5-2) / special.gamma(0.5+0.5*5)],
|
3319
|
+
[4, 0.5+4, 1.5-2*4, -1./3,
|
3320
|
+
(8./9)**(-2*4)*special.gamma(4./3) * special.gamma(1.5-2*4)
|
3321
|
+
/ special.gamma(3./2) / special.gamma(4./3-2*4)],
|
3322
|
+
# and some others
|
3323
|
+
# ticket #424
|
3324
|
+
[1.5, -0.5, 1.0, -10.0, 4.1300097765277476484],
|
3325
|
+
# negative integer a or b, with c-a-b integer and x > 0.9
|
3326
|
+
[-2,3,1,0.95,0.715],
|
3327
|
+
[2,-3,1,0.95,-0.007],
|
3328
|
+
[-6,3,1,0.95,0.0000810625],
|
3329
|
+
[2,-5,1,0.95,-0.000029375],
|
3330
|
+
# huge negative integers
|
3331
|
+
(10, -900, 10.5, 0.99, 1.91853705796607664803709475658e-24),
|
3332
|
+
(10, -900, -10.5, 0.99, 3.54279200040355710199058559155e-18),
|
3333
|
+
]
|
3334
|
+
for i, (a, b, c, x, v) in enumerate(values):
|
3335
|
+
cv = special.hyp2f1(a, b, c, x)
|
3336
|
+
assert_almost_equal(cv, v, 8, err_msg=f'test #{i}')
|
3337
|
+
|
3338
|
+
def test_hyperu(self):
|
3339
|
+
val1 = special.hyperu(1,0.1,100)
|
3340
|
+
assert_almost_equal(val1,0.0098153,7)
|
3341
|
+
a,b = [0.3,0.6,1.2,-2.7],[1.5,3.2,-0.4,-3.2]
|
3342
|
+
a,b = asarray(a), asarray(b)
|
3343
|
+
z = 0.5
|
3344
|
+
hypu = special.hyperu(a,b,z)
|
3345
|
+
hprl = (pi/sin(pi*b))*(special.hyp1f1(a,b,z) /
|
3346
|
+
(special.gamma(1+a-b)*special.gamma(b)) -
|
3347
|
+
z**(1-b)*special.hyp1f1(1+a-b,2-b,z)
|
3348
|
+
/ (special.gamma(a)*special.gamma(2-b)))
|
3349
|
+
assert_array_almost_equal(hypu,hprl,12)
|
3350
|
+
|
3351
|
+
def test_hyperu_gh2287(self):
|
3352
|
+
assert_almost_equal(special.hyperu(1, 1.5, 20.2),
|
3353
|
+
0.048360918656699191, 12)
|
3354
|
+
|
3355
|
+
|
3356
|
+
class TestBessel:
|
3357
|
+
def test_itj0y0(self):
|
3358
|
+
it0 = array(special.itj0y0(.2))
|
3359
|
+
assert_array_almost_equal(
|
3360
|
+
it0,
|
3361
|
+
array([0.19933433254006822, -0.34570883800412566]),
|
3362
|
+
8,
|
3363
|
+
)
|
3364
|
+
|
3365
|
+
def test_it2j0y0(self):
|
3366
|
+
it2 = array(special.it2j0y0(.2))
|
3367
|
+
assert_array_almost_equal(
|
3368
|
+
it2,
|
3369
|
+
array([0.0049937546274601858, -0.43423067011231614]),
|
3370
|
+
8,
|
3371
|
+
)
|
3372
|
+
|
3373
|
+
def test_negv_iv(self):
|
3374
|
+
assert_equal(special.iv(3,2), special.iv(-3,2))
|
3375
|
+
|
3376
|
+
def test_j0(self):
|
3377
|
+
oz = special.j0(.1)
|
3378
|
+
ozr = special.jn(0,.1)
|
3379
|
+
assert_almost_equal(oz,ozr,8)
|
3380
|
+
|
3381
|
+
def test_j1(self):
|
3382
|
+
o1 = special.j1(.1)
|
3383
|
+
o1r = special.jn(1,.1)
|
3384
|
+
assert_almost_equal(o1,o1r,8)
|
3385
|
+
|
3386
|
+
def test_jn(self):
|
3387
|
+
jnnr = special.jn(1,.2)
|
3388
|
+
assert_almost_equal(jnnr,0.099500832639235995,8)
|
3389
|
+
|
3390
|
+
def test_negv_jv(self):
|
3391
|
+
assert_almost_equal(special.jv(-3,2), -special.jv(3,2), 14)
|
3392
|
+
|
3393
|
+
def test_jv(self):
|
3394
|
+
values = [[0, 0.1, 0.99750156206604002],
|
3395
|
+
[2./3, 1e-8, 0.3239028506761532e-5],
|
3396
|
+
[2./3, 1e-10, 0.1503423854873779e-6],
|
3397
|
+
[3.1, 1e-10, 0.1711956265409013e-32],
|
3398
|
+
[2./3, 4.0, -0.2325440850267039],
|
3399
|
+
]
|
3400
|
+
for i, (v, x, y) in enumerate(values):
|
3401
|
+
yc = special.jv(v, x)
|
3402
|
+
assert_almost_equal(yc, y, 8, err_msg=f'test #{i}')
|
3403
|
+
|
3404
|
+
def test_negv_jve(self):
|
3405
|
+
assert_almost_equal(special.jve(-3,2), -special.jve(3,2), 14)
|
3406
|
+
|
3407
|
+
def test_jve(self):
|
3408
|
+
jvexp = special.jve(1,.2)
|
3409
|
+
assert_almost_equal(jvexp,0.099500832639235995,8)
|
3410
|
+
jvexp1 = special.jve(1,.2+1j)
|
3411
|
+
z = .2+1j
|
3412
|
+
jvexpr = special.jv(1,z)*exp(-abs(z.imag))
|
3413
|
+
assert_almost_equal(jvexp1,jvexpr,8)
|
3414
|
+
|
3415
|
+
def test_jn_zeros(self):
|
3416
|
+
jn0 = special.jn_zeros(0,5)
|
3417
|
+
jn1 = special.jn_zeros(1,5)
|
3418
|
+
assert_array_almost_equal(jn0,array([2.4048255577,
|
3419
|
+
5.5200781103,
|
3420
|
+
8.6537279129,
|
3421
|
+
11.7915344391,
|
3422
|
+
14.9309177086]),4)
|
3423
|
+
assert_array_almost_equal(jn1,array([3.83171,
|
3424
|
+
7.01559,
|
3425
|
+
10.17347,
|
3426
|
+
13.32369,
|
3427
|
+
16.47063]),4)
|
3428
|
+
|
3429
|
+
jn102 = special.jn_zeros(102,5)
|
3430
|
+
assert_allclose(jn102, array([110.89174935992040343,
|
3431
|
+
117.83464175788308398,
|
3432
|
+
123.70194191713507279,
|
3433
|
+
129.02417238949092824,
|
3434
|
+
134.00114761868422559]), rtol=1e-13)
|
3435
|
+
|
3436
|
+
jn301 = special.jn_zeros(301,5)
|
3437
|
+
assert_allclose(jn301, array([313.59097866698830153,
|
3438
|
+
323.21549776096288280,
|
3439
|
+
331.22338738656748796,
|
3440
|
+
338.39676338872084500,
|
3441
|
+
345.03284233056064157]), rtol=1e-13)
|
3442
|
+
|
3443
|
+
def test_jn_zeros_slow(self):
|
3444
|
+
jn0 = special.jn_zeros(0, 300)
|
3445
|
+
assert_allclose(jn0[260-1], 816.02884495068867280, rtol=1e-13)
|
3446
|
+
assert_allclose(jn0[280-1], 878.86068707124422606, rtol=1e-13)
|
3447
|
+
assert_allclose(jn0[300-1], 941.69253065317954064, rtol=1e-13)
|
3448
|
+
|
3449
|
+
jn10 = special.jn_zeros(10, 300)
|
3450
|
+
assert_allclose(jn10[260-1], 831.67668514305631151, rtol=1e-13)
|
3451
|
+
assert_allclose(jn10[280-1], 894.51275095371316931, rtol=1e-13)
|
3452
|
+
assert_allclose(jn10[300-1], 957.34826370866539775, rtol=1e-13)
|
3453
|
+
|
3454
|
+
jn3010 = special.jn_zeros(3010,5)
|
3455
|
+
assert_allclose(jn3010, array([3036.86590780927,
|
3456
|
+
3057.06598526482,
|
3457
|
+
3073.66360690272,
|
3458
|
+
3088.37736494778,
|
3459
|
+
3101.86438139042]), rtol=1e-8)
|
3460
|
+
|
3461
|
+
def test_jnjnp_zeros(self):
|
3462
|
+
jn = special.jn
|
3463
|
+
|
3464
|
+
def jnp(n, x):
|
3465
|
+
return (jn(n-1,x) - jn(n+1,x))/2
|
3466
|
+
for nt in range(1, 30):
|
3467
|
+
z, n, m, t = special.jnjnp_zeros(nt)
|
3468
|
+
for zz, nn, tt in zip(z, n, t):
|
3469
|
+
if tt == 0:
|
3470
|
+
assert_allclose(jn(nn, zz), 0, atol=1e-6)
|
3471
|
+
elif tt == 1:
|
3472
|
+
assert_allclose(jnp(nn, zz), 0, atol=1e-6)
|
3473
|
+
else:
|
3474
|
+
raise AssertionError(f"Invalid t return for nt={nt}")
|
3475
|
+
|
3476
|
+
def test_jnp_zeros(self):
|
3477
|
+
jnp = special.jnp_zeros(1,5)
|
3478
|
+
assert_array_almost_equal(jnp, array([1.84118,
|
3479
|
+
5.33144,
|
3480
|
+
8.53632,
|
3481
|
+
11.70600,
|
3482
|
+
14.86359]),4)
|
3483
|
+
jnp = special.jnp_zeros(443,5)
|
3484
|
+
assert_allclose(special.jvp(443, jnp), 0, atol=1e-15)
|
3485
|
+
|
3486
|
+
def test_jnyn_zeros(self):
|
3487
|
+
jnz = special.jnyn_zeros(1,5)
|
3488
|
+
assert_array_almost_equal(jnz,(array([3.83171,
|
3489
|
+
7.01559,
|
3490
|
+
10.17347,
|
3491
|
+
13.32369,
|
3492
|
+
16.47063]),
|
3493
|
+
array([1.84118,
|
3494
|
+
5.33144,
|
3495
|
+
8.53632,
|
3496
|
+
11.70600,
|
3497
|
+
14.86359]),
|
3498
|
+
array([2.19714,
|
3499
|
+
5.42968,
|
3500
|
+
8.59601,
|
3501
|
+
11.74915,
|
3502
|
+
14.89744]),
|
3503
|
+
array([3.68302,
|
3504
|
+
6.94150,
|
3505
|
+
10.12340,
|
3506
|
+
13.28576,
|
3507
|
+
16.44006])),5)
|
3508
|
+
|
3509
|
+
def test_jvp(self):
|
3510
|
+
jvprim = special.jvp(2,2)
|
3511
|
+
jv0 = (special.jv(1,2)-special.jv(3,2))/2
|
3512
|
+
assert_almost_equal(jvprim,jv0,10)
|
3513
|
+
|
3514
|
+
def test_k0(self):
|
3515
|
+
ozk = special.k0(.1)
|
3516
|
+
ozkr = special.kv(0,.1)
|
3517
|
+
assert_almost_equal(ozk,ozkr,8)
|
3518
|
+
|
3519
|
+
def test_k0e(self):
|
3520
|
+
ozke = special.k0e(.1)
|
3521
|
+
ozker = special.kve(0,.1)
|
3522
|
+
assert_almost_equal(ozke,ozker,8)
|
3523
|
+
|
3524
|
+
def test_k1(self):
|
3525
|
+
o1k = special.k1(.1)
|
3526
|
+
o1kr = special.kv(1,.1)
|
3527
|
+
assert_almost_equal(o1k,o1kr,8)
|
3528
|
+
|
3529
|
+
def test_k1e(self):
|
3530
|
+
o1ke = special.k1e(.1)
|
3531
|
+
o1ker = special.kve(1,.1)
|
3532
|
+
assert_almost_equal(o1ke,o1ker,8)
|
3533
|
+
|
3534
|
+
def test_jacobi(self):
|
3535
|
+
a = 5*np.random.random() - 1
|
3536
|
+
b = 5*np.random.random() - 1
|
3537
|
+
P0 = special.jacobi(0,a,b)
|
3538
|
+
P1 = special.jacobi(1,a,b)
|
3539
|
+
P2 = special.jacobi(2,a,b)
|
3540
|
+
P3 = special.jacobi(3,a,b)
|
3541
|
+
|
3542
|
+
assert_array_almost_equal(P0.c,[1],13)
|
3543
|
+
assert_array_almost_equal(P1.c,array([a+b+2,a-b])/2.0,13)
|
3544
|
+
cp = [(a+b+3)*(a+b+4), 4*(a+b+3)*(a+2), 4*(a+1)*(a+2)]
|
3545
|
+
p2c = [cp[0],cp[1]-2*cp[0],cp[2]-cp[1]+cp[0]]
|
3546
|
+
assert_array_almost_equal(P2.c,array(p2c)/8.0,13)
|
3547
|
+
cp = [(a+b+4)*(a+b+5)*(a+b+6),6*(a+b+4)*(a+b+5)*(a+3),
|
3548
|
+
12*(a+b+4)*(a+2)*(a+3),8*(a+1)*(a+2)*(a+3)]
|
3549
|
+
p3c = [cp[0],cp[1]-3*cp[0],cp[2]-2*cp[1]+3*cp[0],cp[3]-cp[2]+cp[1]-cp[0]]
|
3550
|
+
assert_array_almost_equal(P3.c,array(p3c)/48.0,13)
|
3551
|
+
|
3552
|
+
def test_kn(self):
|
3553
|
+
kn1 = special.kn(0,.2)
|
3554
|
+
assert_almost_equal(kn1,1.7527038555281462,8)
|
3555
|
+
|
3556
|
+
def test_negv_kv(self):
|
3557
|
+
assert_equal(special.kv(3.0, 2.2), special.kv(-3.0, 2.2))
|
3558
|
+
|
3559
|
+
def test_kv0(self):
|
3560
|
+
kv0 = special.kv(0,.2)
|
3561
|
+
assert_almost_equal(kv0, 1.7527038555281462, 10)
|
3562
|
+
|
3563
|
+
def test_kv1(self):
|
3564
|
+
kv1 = special.kv(1,0.2)
|
3565
|
+
assert_almost_equal(kv1, 4.775972543220472, 10)
|
3566
|
+
|
3567
|
+
def test_kv2(self):
|
3568
|
+
kv2 = special.kv(2,0.2)
|
3569
|
+
assert_almost_equal(kv2, 49.51242928773287, 10)
|
3570
|
+
|
3571
|
+
def test_kn_largeorder(self):
|
3572
|
+
assert_allclose(special.kn(32, 1), 1.7516596664574289e+43)
|
3573
|
+
|
3574
|
+
def test_kv_largearg(self):
|
3575
|
+
assert_equal(special.kv(0, 1e19), 0)
|
3576
|
+
|
3577
|
+
def test_negv_kve(self):
|
3578
|
+
assert_equal(special.kve(3.0, 2.2), special.kve(-3.0, 2.2))
|
3579
|
+
|
3580
|
+
def test_kve(self):
|
3581
|
+
kve1 = special.kve(0,.2)
|
3582
|
+
kv1 = special.kv(0,.2)*exp(.2)
|
3583
|
+
assert_almost_equal(kve1,kv1,8)
|
3584
|
+
z = .2+1j
|
3585
|
+
kve2 = special.kve(0,z)
|
3586
|
+
kv2 = special.kv(0,z)*exp(z)
|
3587
|
+
assert_almost_equal(kve2,kv2,8)
|
3588
|
+
|
3589
|
+
def test_kvp_v0n1(self):
|
3590
|
+
z = 2.2
|
3591
|
+
assert_almost_equal(-special.kv(1,z), special.kvp(0,z, n=1), 10)
|
3592
|
+
|
3593
|
+
def test_kvp_n1(self):
|
3594
|
+
v = 3.
|
3595
|
+
z = 2.2
|
3596
|
+
xc = -special.kv(v+1,z) + v/z*special.kv(v,z)
|
3597
|
+
x = special.kvp(v,z, n=1)
|
3598
|
+
assert_almost_equal(xc, x, 10) # this function (kvp) is broken
|
3599
|
+
|
3600
|
+
def test_kvp_n2(self):
|
3601
|
+
v = 3.
|
3602
|
+
z = 2.2
|
3603
|
+
xc = (z**2+v**2-v)/z**2 * special.kv(v,z) + special.kv(v+1,z)/z
|
3604
|
+
x = special.kvp(v, z, n=2)
|
3605
|
+
assert_almost_equal(xc, x, 10)
|
3606
|
+
|
3607
|
+
def test_y0(self):
|
3608
|
+
oz = special.y0(.1)
|
3609
|
+
ozr = special.yn(0,.1)
|
3610
|
+
assert_almost_equal(oz,ozr,8)
|
3611
|
+
|
3612
|
+
def test_y1(self):
|
3613
|
+
o1 = special.y1(.1)
|
3614
|
+
o1r = special.yn(1,.1)
|
3615
|
+
assert_almost_equal(o1,o1r,8)
|
3616
|
+
|
3617
|
+
def test_y0_zeros(self):
|
3618
|
+
yo,ypo = special.y0_zeros(2)
|
3619
|
+
zo,zpo = special.y0_zeros(2,complex=1)
|
3620
|
+
all = r_[yo,zo]
|
3621
|
+
allval = r_[ypo,zpo]
|
3622
|
+
assert_array_almost_equal(abs(special.yv(0.0,all)),0.0,11)
|
3623
|
+
assert_array_almost_equal(abs(special.yv(1,all)-allval),0.0,11)
|
3624
|
+
|
3625
|
+
def test_y1_zeros(self):
|
3626
|
+
y1 = special.y1_zeros(1)
|
3627
|
+
assert_array_almost_equal(y1,(array([2.19714]),array([0.52079])),5)
|
3628
|
+
|
3629
|
+
def test_y1p_zeros(self):
|
3630
|
+
y1p = special.y1p_zeros(1,complex=1)
|
3631
|
+
assert_array_almost_equal(
|
3632
|
+
y1p,
|
3633
|
+
(array([0.5768+0.904j]), array([-0.7635+0.5892j])),
|
3634
|
+
3,
|
3635
|
+
)
|
3636
|
+
|
3637
|
+
def test_yn_zeros(self):
|
3638
|
+
an = special.yn_zeros(4,2)
|
3639
|
+
assert_array_almost_equal(an,array([5.64515, 9.36162]),5)
|
3640
|
+
an = special.yn_zeros(443,5)
|
3641
|
+
assert_allclose(an, [450.13573091578090314,
|
3642
|
+
463.05692376675001542,
|
3643
|
+
472.80651546418663566,
|
3644
|
+
481.27353184725625838,
|
3645
|
+
488.98055964441374646],
|
3646
|
+
rtol=1e-15,)
|
3647
|
+
|
3648
|
+
def test_ynp_zeros(self):
|
3649
|
+
ao = special.ynp_zeros(0,2)
|
3650
|
+
assert_array_almost_equal(ao,array([2.19714133, 5.42968104]),6)
|
3651
|
+
ao = special.ynp_zeros(43,5)
|
3652
|
+
assert_allclose(special.yvp(43, ao), 0, atol=1e-15)
|
3653
|
+
ao = special.ynp_zeros(443,5)
|
3654
|
+
assert_allclose(special.yvp(443, ao), 0, atol=1e-9)
|
3655
|
+
|
3656
|
+
def test_ynp_zeros_large_order(self):
|
3657
|
+
ao = special.ynp_zeros(443,5)
|
3658
|
+
assert_allclose(special.yvp(443, ao), 0, atol=1e-14)
|
3659
|
+
|
3660
|
+
def test_yn(self):
|
3661
|
+
yn2n = special.yn(1,.2)
|
3662
|
+
assert_almost_equal(yn2n,-3.3238249881118471,8)
|
3663
|
+
|
3664
|
+
def test_yn_gh_20405(self):
|
3665
|
+
# Enforce correct asymptotic behavior for large n.
|
3666
|
+
observed = cephes.yn(500, 1)
|
3667
|
+
assert observed == -np.inf
|
3668
|
+
|
3669
|
+
def test_negv_yv(self):
|
3670
|
+
assert_almost_equal(special.yv(-3,2), -special.yv(3,2), 14)
|
3671
|
+
|
3672
|
+
def test_yv(self):
|
3673
|
+
yv2 = special.yv(1,.2)
|
3674
|
+
assert_almost_equal(yv2,-3.3238249881118471,8)
|
3675
|
+
|
3676
|
+
def test_negv_yve(self):
|
3677
|
+
assert_almost_equal(special.yve(-3,2), -special.yve(3,2), 14)
|
3678
|
+
|
3679
|
+
def test_yve(self):
|
3680
|
+
yve2 = special.yve(1,.2)
|
3681
|
+
assert_almost_equal(yve2,-3.3238249881118471,8)
|
3682
|
+
yve2r = special.yv(1,.2+1j)*exp(-1)
|
3683
|
+
yve22 = special.yve(1,.2+1j)
|
3684
|
+
assert_almost_equal(yve22,yve2r,8)
|
3685
|
+
|
3686
|
+
def test_yvp(self):
|
3687
|
+
yvpr = (special.yv(1,.2) - special.yv(3,.2))/2.0
|
3688
|
+
yvp1 = special.yvp(2,.2)
|
3689
|
+
assert_array_almost_equal(yvp1,yvpr,10)
|
3690
|
+
|
3691
|
+
def _cephes_vs_amos_points(self):
|
3692
|
+
"""Yield points at which to compare Cephes implementation to AMOS"""
|
3693
|
+
# check several points, including large-amplitude ones
|
3694
|
+
v = [-120, -100.3, -20., -10., -1., -.5, 0., 1., 12.49, 120., 301]
|
3695
|
+
z = [-1300, -11, -10, -1, 1., 10., 200.5, 401., 600.5, 700.6, 1300,
|
3696
|
+
10003]
|
3697
|
+
yield from itertools.product(v, z)
|
3698
|
+
|
3699
|
+
# check half-integers; these are problematic points at least
|
3700
|
+
# for cephes/iv
|
3701
|
+
yield from itertools.product(0.5 + arange(-60, 60), [3.5])
|
3702
|
+
|
3703
|
+
def check_cephes_vs_amos(self, f1, f2, rtol=1e-11, atol=0, skip=None):
|
3704
|
+
for v, z in self._cephes_vs_amos_points():
|
3705
|
+
if skip is not None and skip(v, z):
|
3706
|
+
continue
|
3707
|
+
c1, c2, c3 = f1(v, z), f1(v,z+0j), f2(int(v), z)
|
3708
|
+
if np.isinf(c1):
|
3709
|
+
assert_(np.abs(c2) >= 1e300, (v, z))
|
3710
|
+
elif np.isnan(c1):
|
3711
|
+
assert_(c2.imag != 0, (v, z))
|
3712
|
+
else:
|
3713
|
+
assert_allclose(c1, c2, err_msg=(v, z), rtol=rtol, atol=atol)
|
3714
|
+
if v == int(v):
|
3715
|
+
assert_allclose(c3, c2, err_msg=(v, z),
|
3716
|
+
rtol=rtol, atol=atol)
|
3717
|
+
|
3718
|
+
@pytest.mark.xfail(platform.machine() == 'ppc64le',
|
3719
|
+
reason="fails on ppc64le")
|
3720
|
+
def test_jv_cephes_vs_amos(self):
|
3721
|
+
self.check_cephes_vs_amos(special.jv, special.jn, rtol=1e-10, atol=1e-305)
|
3722
|
+
|
3723
|
+
@pytest.mark.xfail(platform.machine() == 'ppc64le',
|
3724
|
+
reason="fails on ppc64le")
|
3725
|
+
def test_yv_cephes_vs_amos(self):
|
3726
|
+
self.check_cephes_vs_amos(special.yv, special.yn, rtol=1e-11, atol=1e-305)
|
3727
|
+
|
3728
|
+
def test_yv_cephes_vs_amos_only_small_orders(self):
|
3729
|
+
def skipper(v, z):
|
3730
|
+
return abs(v) > 50
|
3731
|
+
self.check_cephes_vs_amos(special.yv, special.yn, rtol=1e-11, atol=1e-305,
|
3732
|
+
skip=skipper)
|
3733
|
+
|
3734
|
+
def test_iv_cephes_vs_amos(self):
|
3735
|
+
with np.errstate(all='ignore'):
|
3736
|
+
self.check_cephes_vs_amos(special.iv, special.iv, rtol=5e-9, atol=1e-305)
|
3737
|
+
|
3738
|
+
@pytest.mark.slow
|
3739
|
+
def test_iv_cephes_vs_amos_mass_test(self):
|
3740
|
+
N = 1000000
|
3741
|
+
np.random.seed(1)
|
3742
|
+
v = np.random.pareto(0.5, N) * (-1)**np.random.randint(2, size=N)
|
3743
|
+
x = np.random.pareto(0.2, N) * (-1)**np.random.randint(2, size=N)
|
3744
|
+
|
3745
|
+
imsk = (np.random.randint(8, size=N) == 0)
|
3746
|
+
v[imsk] = v[imsk].astype(np.int64)
|
3747
|
+
|
3748
|
+
with np.errstate(all='ignore'):
|
3749
|
+
c1 = special.iv(v, x)
|
3750
|
+
c2 = special.iv(v, x+0j)
|
3751
|
+
|
3752
|
+
# deal with differences in the inf and zero cutoffs
|
3753
|
+
c1[abs(c1) > 1e300] = np.inf
|
3754
|
+
c2[abs(c2) > 1e300] = np.inf
|
3755
|
+
c1[abs(c1) < 1e-300] = 0
|
3756
|
+
c2[abs(c2) < 1e-300] = 0
|
3757
|
+
|
3758
|
+
dc = abs(c1/c2 - 1)
|
3759
|
+
dc[np.isnan(dc)] = 0
|
3760
|
+
|
3761
|
+
k = np.argmax(dc)
|
3762
|
+
|
3763
|
+
# Most error apparently comes from AMOS and not our implementation;
|
3764
|
+
# there are some problems near integer orders there
|
3765
|
+
assert_(
|
3766
|
+
dc[k] < 2e-7,
|
3767
|
+
(v[k], x[k], special.iv(v[k], x[k]), special.iv(v[k], x[k]+0j))
|
3768
|
+
)
|
3769
|
+
|
3770
|
+
def test_kv_cephes_vs_amos(self):
|
3771
|
+
self.check_cephes_vs_amos(special.kv, special.kn, rtol=1e-9, atol=1e-305)
|
3772
|
+
self.check_cephes_vs_amos(special.kv, special.kv, rtol=1e-9, atol=1e-305)
|
3773
|
+
|
3774
|
+
def test_ticket_623(self):
|
3775
|
+
assert_allclose(special.jv(3, 4), 0.43017147387562193)
|
3776
|
+
assert_allclose(special.jv(301, 1300), 0.0183487151115275)
|
3777
|
+
assert_allclose(special.jv(301, 1296.0682), -0.0224174325312048)
|
3778
|
+
|
3779
|
+
def test_ticket_853(self):
|
3780
|
+
"""Negative-order Bessels"""
|
3781
|
+
# cephes
|
3782
|
+
assert_allclose(special.jv(-1, 1), -0.4400505857449335)
|
3783
|
+
assert_allclose(special.jv(-2, 1), 0.1149034849319005)
|
3784
|
+
assert_allclose(special.yv(-1, 1), 0.7812128213002887)
|
3785
|
+
assert_allclose(special.yv(-2, 1), -1.650682606816255)
|
3786
|
+
assert_allclose(special.iv(-1, 1), 0.5651591039924851)
|
3787
|
+
assert_allclose(special.iv(-2, 1), 0.1357476697670383)
|
3788
|
+
assert_allclose(special.kv(-1, 1), 0.6019072301972347)
|
3789
|
+
assert_allclose(special.kv(-2, 1), 1.624838898635178)
|
3790
|
+
assert_allclose(special.jv(-0.5, 1), 0.43109886801837607952)
|
3791
|
+
assert_allclose(special.yv(-0.5, 1), 0.6713967071418031)
|
3792
|
+
assert_allclose(special.iv(-0.5, 1), 1.231200214592967)
|
3793
|
+
assert_allclose(special.kv(-0.5, 1), 0.4610685044478945)
|
3794
|
+
# amos
|
3795
|
+
assert_allclose(special.jv(-1, 1+0j), -0.4400505857449335)
|
3796
|
+
assert_allclose(special.jv(-2, 1+0j), 0.1149034849319005)
|
3797
|
+
assert_allclose(special.yv(-1, 1+0j), 0.7812128213002887)
|
3798
|
+
assert_allclose(special.yv(-2, 1+0j), -1.650682606816255)
|
3799
|
+
|
3800
|
+
assert_allclose(special.iv(-1, 1+0j), 0.5651591039924851)
|
3801
|
+
assert_allclose(special.iv(-2, 1+0j), 0.1357476697670383)
|
3802
|
+
assert_allclose(special.kv(-1, 1+0j), 0.6019072301972347)
|
3803
|
+
assert_allclose(special.kv(-2, 1+0j), 1.624838898635178)
|
3804
|
+
|
3805
|
+
assert_allclose(special.jv(-0.5, 1+0j), 0.43109886801837607952)
|
3806
|
+
assert_allclose(special.jv(-0.5, 1+1j), 0.2628946385649065-0.827050182040562j)
|
3807
|
+
assert_allclose(special.yv(-0.5, 1+0j), 0.6713967071418031)
|
3808
|
+
assert_allclose(special.yv(-0.5, 1+1j), 0.967901282890131+0.0602046062142816j)
|
3809
|
+
|
3810
|
+
assert_allclose(special.iv(-0.5, 1+0j), 1.231200214592967)
|
3811
|
+
assert_allclose(special.iv(-0.5, 1+1j), 0.77070737376928+0.39891821043561j)
|
3812
|
+
assert_allclose(special.kv(-0.5, 1+0j), 0.4610685044478945)
|
3813
|
+
assert_allclose(special.kv(-0.5, 1+1j), 0.06868578341999-0.38157825981268j)
|
3814
|
+
|
3815
|
+
assert_allclose(special.jve(-0.5,1+0.3j), special.jv(-0.5, 1+0.3j)*exp(-0.3))
|
3816
|
+
assert_allclose(special.yve(-0.5,1+0.3j), special.yv(-0.5, 1+0.3j)*exp(-0.3))
|
3817
|
+
assert_allclose(special.ive(-0.5,0.3+1j), special.iv(-0.5, 0.3+1j)*exp(-0.3))
|
3818
|
+
assert_allclose(special.kve(-0.5,0.3+1j), special.kv(-0.5, 0.3+1j)*exp(0.3+1j))
|
3819
|
+
|
3820
|
+
assert_allclose(
|
3821
|
+
special.hankel1(-0.5, 1+1j),
|
3822
|
+
special.jv(-0.5, 1+1j) + 1j*special.yv(-0.5,1+1j)
|
3823
|
+
)
|
3824
|
+
assert_allclose(
|
3825
|
+
special.hankel2(-0.5, 1+1j),
|
3826
|
+
special.jv(-0.5, 1+1j) - 1j*special.yv(-0.5,1+1j)
|
3827
|
+
)
|
3828
|
+
|
3829
|
+
def test_ticket_854(self):
|
3830
|
+
"""Real-valued Bessel domains"""
|
3831
|
+
assert_(isnan(special.jv(0.5, -1)))
|
3832
|
+
assert_(isnan(special.iv(0.5, -1)))
|
3833
|
+
assert_(isnan(special.yv(0.5, -1)))
|
3834
|
+
assert_(isnan(special.yv(1, -1)))
|
3835
|
+
assert_(isnan(special.kv(0.5, -1)))
|
3836
|
+
assert_(isnan(special.kv(1, -1)))
|
3837
|
+
assert_(isnan(special.jve(0.5, -1)))
|
3838
|
+
assert_(isnan(special.ive(0.5, -1)))
|
3839
|
+
assert_(isnan(special.yve(0.5, -1)))
|
3840
|
+
assert_(isnan(special.yve(1, -1)))
|
3841
|
+
assert_(isnan(special.kve(0.5, -1)))
|
3842
|
+
assert_(isnan(special.kve(1, -1)))
|
3843
|
+
assert_(isnan(special.airye(-1)[0:2]).all(), special.airye(-1))
|
3844
|
+
assert_(not isnan(special.airye(-1)[2:4]).any(), special.airye(-1))
|
3845
|
+
|
3846
|
+
def test_gh_7909(self):
|
3847
|
+
assert_(special.kv(1.5, 0) == np.inf)
|
3848
|
+
assert_(special.kve(1.5, 0) == np.inf)
|
3849
|
+
|
3850
|
+
def test_ticket_503(self):
|
3851
|
+
"""Real-valued Bessel I overflow"""
|
3852
|
+
assert_allclose(special.iv(1, 700), 1.528500390233901e302)
|
3853
|
+
assert_allclose(special.iv(1000, 1120), 1.301564549405821e301)
|
3854
|
+
|
3855
|
+
def test_iv_hyperg_poles(self):
|
3856
|
+
assert_allclose(special.iv(-0.5, 1), 1.231200214592967)
|
3857
|
+
|
3858
|
+
def iv_series(self, v, z, n=200):
|
3859
|
+
k = arange(0, n).astype(double)
|
3860
|
+
r = (v+2*k)*log(.5*z) - special.gammaln(k+1) - special.gammaln(v+k+1)
|
3861
|
+
r[isnan(r)] = inf
|
3862
|
+
r = exp(r)
|
3863
|
+
err = abs(r).max() * finfo(double).eps * n + abs(r[-1])*10
|
3864
|
+
return r.sum(), err
|
3865
|
+
|
3866
|
+
def test_i0_series(self):
|
3867
|
+
for z in [1., 10., 200.5]:
|
3868
|
+
value, err = self.iv_series(0, z)
|
3869
|
+
assert_allclose(special.i0(z), value, atol=err, err_msg=z)
|
3870
|
+
|
3871
|
+
def test_i1_series(self):
|
3872
|
+
for z in [1., 10., 200.5]:
|
3873
|
+
value, err = self.iv_series(1, z)
|
3874
|
+
assert_allclose(special.i1(z), value, atol=err, err_msg=z)
|
3875
|
+
|
3876
|
+
def test_iv_series(self):
|
3877
|
+
for v in [-20., -10., -1., 0., 1., 12.49, 120.]:
|
3878
|
+
for z in [1., 10., 200.5, -1+2j]:
|
3879
|
+
value, err = self.iv_series(v, z)
|
3880
|
+
assert_allclose(special.iv(v, z), value, atol=err, err_msg=(v, z))
|
3881
|
+
|
3882
|
+
def test_i0(self):
|
3883
|
+
values = [[0.0, 1.0],
|
3884
|
+
[1e-10, 1.0],
|
3885
|
+
[0.1, 0.9071009258],
|
3886
|
+
[0.5, 0.6450352706],
|
3887
|
+
[1.0, 0.4657596077],
|
3888
|
+
[2.5, 0.2700464416],
|
3889
|
+
[5.0, 0.1835408126],
|
3890
|
+
[20.0, 0.0897803119],
|
3891
|
+
]
|
3892
|
+
for i, (x, v) in enumerate(values):
|
3893
|
+
cv = special.i0(x) * exp(-x)
|
3894
|
+
assert_almost_equal(cv, v, 8, err_msg=f'test #{i}')
|
3895
|
+
|
3896
|
+
def test_i0e(self):
|
3897
|
+
oize = special.i0e(.1)
|
3898
|
+
oizer = special.ive(0,.1)
|
3899
|
+
assert_almost_equal(oize,oizer,8)
|
3900
|
+
|
3901
|
+
def test_i1(self):
|
3902
|
+
values = [[0.0, 0.0],
|
3903
|
+
[1e-10, 0.4999999999500000e-10],
|
3904
|
+
[0.1, 0.0452984468],
|
3905
|
+
[0.5, 0.1564208032],
|
3906
|
+
[1.0, 0.2079104154],
|
3907
|
+
[5.0, 0.1639722669],
|
3908
|
+
[20.0, 0.0875062222],
|
3909
|
+
]
|
3910
|
+
for i, (x, v) in enumerate(values):
|
3911
|
+
cv = special.i1(x) * exp(-x)
|
3912
|
+
assert_almost_equal(cv, v, 8, err_msg=f'test #{i}')
|
3913
|
+
|
3914
|
+
def test_i1e(self):
|
3915
|
+
oi1e = special.i1e(.1)
|
3916
|
+
oi1er = special.ive(1,.1)
|
3917
|
+
assert_almost_equal(oi1e,oi1er,8)
|
3918
|
+
|
3919
|
+
def test_iti0k0(self):
|
3920
|
+
iti0 = array(special.iti0k0(5))
|
3921
|
+
assert_array_almost_equal(
|
3922
|
+
iti0,
|
3923
|
+
array([31.848667776169801, 1.5673873907283657]),
|
3924
|
+
5,
|
3925
|
+
)
|
3926
|
+
|
3927
|
+
def test_it2i0k0(self):
|
3928
|
+
it2k = special.it2i0k0(.1)
|
3929
|
+
assert_array_almost_equal(
|
3930
|
+
it2k,
|
3931
|
+
array([0.0012503906973464409, 3.3309450354686687]),
|
3932
|
+
6,
|
3933
|
+
)
|
3934
|
+
|
3935
|
+
def test_iv(self):
|
3936
|
+
iv1 = special.iv(0,.1)*exp(-.1)
|
3937
|
+
assert_almost_equal(iv1,0.90710092578230106,10)
|
3938
|
+
|
3939
|
+
def test_negv_ive(self):
|
3940
|
+
assert_equal(special.ive(3,2), special.ive(-3,2))
|
3941
|
+
|
3942
|
+
def test_ive(self):
|
3943
|
+
ive1 = special.ive(0,.1)
|
3944
|
+
iv1 = special.iv(0,.1)*exp(-.1)
|
3945
|
+
assert_almost_equal(ive1,iv1,10)
|
3946
|
+
|
3947
|
+
def test_ivp0(self):
|
3948
|
+
assert_almost_equal(special.iv(1,2), special.ivp(0,2), 10)
|
3949
|
+
|
3950
|
+
def test_ivp(self):
|
3951
|
+
y = (special.iv(0,2) + special.iv(2,2))/2
|
3952
|
+
x = special.ivp(1,2)
|
3953
|
+
assert_almost_equal(x,y,10)
|
3954
|
+
|
3955
|
+
|
3956
|
+
class TestLaguerre:
|
3957
|
+
def test_laguerre(self):
|
3958
|
+
lag0 = special.laguerre(0)
|
3959
|
+
lag1 = special.laguerre(1)
|
3960
|
+
lag2 = special.laguerre(2)
|
3961
|
+
lag3 = special.laguerre(3)
|
3962
|
+
lag4 = special.laguerre(4)
|
3963
|
+
lag5 = special.laguerre(5)
|
3964
|
+
assert_array_almost_equal(lag0.c,[1],13)
|
3965
|
+
assert_array_almost_equal(lag1.c,[-1,1],13)
|
3966
|
+
assert_array_almost_equal(lag2.c,array([1,-4,2])/2.0,13)
|
3967
|
+
assert_array_almost_equal(lag3.c,array([-1,9,-18,6])/6.0,13)
|
3968
|
+
assert_array_almost_equal(lag4.c,array([1,-16,72,-96,24])/24.0,13)
|
3969
|
+
assert_array_almost_equal(lag5.c,array([-1,25,-200,600,-600,120])/120.0,13)
|
3970
|
+
|
3971
|
+
def test_genlaguerre(self):
|
3972
|
+
k = 5*np.random.random() - 0.9
|
3973
|
+
lag0 = special.genlaguerre(0,k)
|
3974
|
+
lag1 = special.genlaguerre(1,k)
|
3975
|
+
lag2 = special.genlaguerre(2,k)
|
3976
|
+
lag3 = special.genlaguerre(3,k)
|
3977
|
+
assert_equal(lag0.c, [1])
|
3978
|
+
assert_equal(lag1.c, [-1, k + 1])
|
3979
|
+
assert_almost_equal(
|
3980
|
+
lag2.c,
|
3981
|
+
array([1,-2*(k+2),(k+1.)*(k+2.)])/2.0
|
3982
|
+
)
|
3983
|
+
assert_almost_equal(
|
3984
|
+
lag3.c,
|
3985
|
+
array([-1,3*(k+3),-3*(k+2)*(k+3),(k+1)*(k+2)*(k+3)])/6.0
|
3986
|
+
)
|
3987
|
+
|
3988
|
+
|
3989
|
+
class TestLambda:
|
3990
|
+
def test_lmbda(self):
|
3991
|
+
lam = special.lmbda(1,.1)
|
3992
|
+
lamr = (
|
3993
|
+
array([special.jn(0,.1), 2*special.jn(1,.1)/.1]),
|
3994
|
+
array([special.jvp(0,.1), -2*special.jv(1,.1)/.01 + 2*special.jvp(1,.1)/.1])
|
3995
|
+
)
|
3996
|
+
assert_array_almost_equal(lam,lamr,8)
|
3997
|
+
|
3998
|
+
|
3999
|
+
class TestLog1p:
|
4000
|
+
def test_log1p(self):
|
4001
|
+
l1p = (special.log1p(10), special.log1p(11), special.log1p(12))
|
4002
|
+
l1prl = (log(11), log(12), log(13))
|
4003
|
+
assert_array_almost_equal(l1p,l1prl,8)
|
4004
|
+
|
4005
|
+
def test_log1pmore(self):
|
4006
|
+
l1pm = (special.log1p(1), special.log1p(1.1), special.log1p(1.2))
|
4007
|
+
l1pmrl = (log(2),log(2.1),log(2.2))
|
4008
|
+
assert_array_almost_equal(l1pm,l1pmrl,8)
|
4009
|
+
|
4010
|
+
|
4011
|
+
class TestMathieu:
|
4012
|
+
|
4013
|
+
def test_mathieu_a(self):
|
4014
|
+
pass
|
4015
|
+
|
4016
|
+
def test_mathieu_even_coef(self):
|
4017
|
+
special.mathieu_even_coef(2,5)
|
4018
|
+
# Q not defined broken and cannot figure out proper reporting order
|
4019
|
+
|
4020
|
+
def test_mathieu_odd_coef(self):
|
4021
|
+
# same problem as above
|
4022
|
+
pass
|
4023
|
+
|
4024
|
+
|
4025
|
+
class TestFresnelIntegral:
|
4026
|
+
|
4027
|
+
def test_modfresnelp(self):
|
4028
|
+
pass
|
4029
|
+
|
4030
|
+
def test_modfresnelm(self):
|
4031
|
+
pass
|
4032
|
+
|
4033
|
+
|
4034
|
+
class TestOblCvSeq:
|
4035
|
+
def test_obl_cv_seq(self):
|
4036
|
+
obl = special.obl_cv_seq(0,3,1)
|
4037
|
+
assert_array_almost_equal(obl,array([-0.348602,
|
4038
|
+
1.393206,
|
4039
|
+
5.486800,
|
4040
|
+
11.492120]),5)
|
4041
|
+
|
4042
|
+
|
4043
|
+
class TestParabolicCylinder:
|
4044
|
+
def test_pbdn_seq(self):
|
4045
|
+
pb = special.pbdn_seq(1,.1)
|
4046
|
+
assert_array_almost_equal(pb,(array([0.9975,
|
4047
|
+
0.0998]),
|
4048
|
+
array([-0.0499,
|
4049
|
+
0.9925])),4)
|
4050
|
+
|
4051
|
+
def test_pbdv(self):
|
4052
|
+
special.pbdv(1,.2)
|
4053
|
+
1/2*(.2)*special.pbdv(1,.2)[0] - special.pbdv(0,.2)[0]
|
4054
|
+
|
4055
|
+
def test_pbdv_seq(self):
|
4056
|
+
pbn = special.pbdn_seq(1,.1)
|
4057
|
+
pbv = special.pbdv_seq(1,.1)
|
4058
|
+
assert_array_almost_equal(pbv,(real(pbn[0]),real(pbn[1])),4)
|
4059
|
+
|
4060
|
+
def test_pbdv_points(self):
|
4061
|
+
# simple case
|
4062
|
+
eta = np.linspace(-10, 10, 5)
|
4063
|
+
z = 2**(eta/2)*np.sqrt(np.pi)*special.rgamma(.5-.5*eta)
|
4064
|
+
assert_allclose(special.pbdv(eta, 0.)[0], z, rtol=1e-14, atol=1e-14)
|
4065
|
+
|
4066
|
+
# some points
|
4067
|
+
assert_allclose(special.pbdv(10.34, 20.44)[0], 1.3731383034455e-32, rtol=1e-12)
|
4068
|
+
assert_allclose(special.pbdv(-9.53, 3.44)[0], 3.166735001119246e-8, rtol=1e-12)
|
4069
|
+
|
4070
|
+
def test_pbdv_gradient(self):
|
4071
|
+
x = np.linspace(-4, 4, 8)[:,None]
|
4072
|
+
eta = np.linspace(-10, 10, 5)[None,:]
|
4073
|
+
|
4074
|
+
p = special.pbdv(eta, x)
|
4075
|
+
eps = 1e-7 + 1e-7*abs(x)
|
4076
|
+
dp = (special.pbdv(eta, x + eps)[0] - special.pbdv(eta, x - eps)[0]) / eps / 2.
|
4077
|
+
assert_allclose(p[1], dp, rtol=1e-6, atol=1e-6)
|
4078
|
+
|
4079
|
+
def test_pbvv_gradient(self):
|
4080
|
+
x = np.linspace(-4, 4, 8)[:,None]
|
4081
|
+
eta = np.linspace(-10, 10, 5)[None,:]
|
4082
|
+
|
4083
|
+
p = special.pbvv(eta, x)
|
4084
|
+
eps = 1e-7 + 1e-7*abs(x)
|
4085
|
+
dp = (special.pbvv(eta, x + eps)[0] - special.pbvv(eta, x - eps)[0]) / eps / 2.
|
4086
|
+
assert_allclose(p[1], dp, rtol=1e-6, atol=1e-6)
|
4087
|
+
|
4088
|
+
def test_pbvv_seq(self):
|
4089
|
+
res1, res2 = special.pbvv_seq(2, 3)
|
4090
|
+
assert_allclose(res1, np.array([2.976319645712036,
|
4091
|
+
1.358840996329579,
|
4092
|
+
0.5501016716383508]))
|
4093
|
+
assert_allclose(res2, np.array([3.105638472238475,
|
4094
|
+
0.9380581512176672,
|
4095
|
+
0.533688488872053]))
|
4096
|
+
|
4097
|
+
|
4098
|
+
class TestPolygamma:
|
4099
|
+
# from Table 6.2 (pg. 271) of A&S
|
4100
|
+
def test_polygamma(self):
|
4101
|
+
poly2 = special.polygamma(2,1)
|
4102
|
+
poly3 = special.polygamma(3,1)
|
4103
|
+
assert_almost_equal(poly2,-2.4041138063,10)
|
4104
|
+
assert_almost_equal(poly3,6.4939394023,10)
|
4105
|
+
|
4106
|
+
# Test polygamma(0, x) == psi(x)
|
4107
|
+
x = [2, 3, 1.1e14]
|
4108
|
+
assert_almost_equal(special.polygamma(0, x), special.psi(x))
|
4109
|
+
|
4110
|
+
# Test broadcasting
|
4111
|
+
n = [0, 1, 2]
|
4112
|
+
x = [0.5, 1.5, 2.5]
|
4113
|
+
expected = [-1.9635100260214238, 0.93480220054467933,
|
4114
|
+
-0.23620405164172739]
|
4115
|
+
assert_almost_equal(special.polygamma(n, x), expected)
|
4116
|
+
expected = np.vstack([expected]*2)
|
4117
|
+
assert_almost_equal(special.polygamma(n, np.vstack([x]*2)),
|
4118
|
+
expected)
|
4119
|
+
assert_almost_equal(special.polygamma(np.vstack([n]*2), x),
|
4120
|
+
expected)
|
4121
|
+
|
4122
|
+
|
4123
|
+
class TestProCvSeq:
|
4124
|
+
def test_pro_cv_seq(self):
|
4125
|
+
prol = special.pro_cv_seq(0,3,1)
|
4126
|
+
assert_array_almost_equal(prol,array([0.319000,
|
4127
|
+
2.593084,
|
4128
|
+
6.533471,
|
4129
|
+
12.514462]),5)
|
4130
|
+
|
4131
|
+
|
4132
|
+
class TestPsi:
|
4133
|
+
def test_psi(self):
|
4134
|
+
ps = special.psi(1)
|
4135
|
+
assert_almost_equal(ps,-0.57721566490153287,8)
|
4136
|
+
|
4137
|
+
|
4138
|
+
class TestRadian:
|
4139
|
+
def test_radian(self):
|
4140
|
+
rad = special.radian(90,0,0)
|
4141
|
+
assert_almost_equal(rad,pi/2.0,5)
|
4142
|
+
|
4143
|
+
def test_radianmore(self):
|
4144
|
+
rad1 = special.radian(90,1,60)
|
4145
|
+
assert_almost_equal(rad1,pi/2+0.0005816135199345904,5)
|
4146
|
+
|
4147
|
+
|
4148
|
+
class TestRiccati:
|
4149
|
+
def test_riccati_jn(self):
|
4150
|
+
N, x = 2, 0.2
|
4151
|
+
S = np.empty((N, N))
|
4152
|
+
for n in range(N):
|
4153
|
+
j = special.spherical_jn(n, x)
|
4154
|
+
jp = special.spherical_jn(n, x, derivative=True)
|
4155
|
+
S[0,n] = x*j
|
4156
|
+
S[1,n] = x*jp + j
|
4157
|
+
assert_array_almost_equal(S, special.riccati_jn(n, x), 8)
|
4158
|
+
|
4159
|
+
def test_riccati_yn(self):
|
4160
|
+
N, x = 2, 0.2
|
4161
|
+
C = np.empty((N, N))
|
4162
|
+
for n in range(N):
|
4163
|
+
y = special.spherical_yn(n, x)
|
4164
|
+
yp = special.spherical_yn(n, x, derivative=True)
|
4165
|
+
C[0,n] = x*y
|
4166
|
+
C[1,n] = x*yp + y
|
4167
|
+
assert_array_almost_equal(C, special.riccati_yn(n, x), 8)
|
4168
|
+
|
4169
|
+
|
4170
|
+
class TestSoftplus:
|
4171
|
+
def test_softplus(self):
|
4172
|
+
# Test cases for the softplus function. Selected based on Eq.(10) of:
|
4173
|
+
# Mächler, M. (2012). log1mexp-note.pdf. Rmpfr: R MPFR - Multiple Precision
|
4174
|
+
# Floating-Point Reliable. Retrieved from:
|
4175
|
+
# https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
|
4176
|
+
# Reference values computed with `mpmath`
|
4177
|
+
import numpy as np
|
4178
|
+
rng = np.random.default_rng(3298432985245)
|
4179
|
+
n = 3
|
4180
|
+
a1 = rng.uniform(-100, -37, size=n)
|
4181
|
+
a2 = rng.uniform(-37, 18, size=n)
|
4182
|
+
a3 = rng.uniform(18, 33.3, size=n)
|
4183
|
+
a4 = rng.uniform(33.33, 100, size=n)
|
4184
|
+
a = np.stack([a1, a2, a3, a4])
|
4185
|
+
|
4186
|
+
# from mpmath import mp
|
4187
|
+
# mp.dps = 100
|
4188
|
+
# @np.vectorize
|
4189
|
+
# def softplus(x):
|
4190
|
+
# return float(mp.log(mp.one + mp.exp(x)))
|
4191
|
+
# softplus(a).tolist()
|
4192
|
+
ref = [[1.692721323272333e-42, 7.42673911145206e-41, 8.504608846033205e-35],
|
4193
|
+
[1.8425343736349797, 9.488245799395577e-15, 7.225195764021444e-08],
|
4194
|
+
[31.253760266045106, 27.758244090327832, 29.995959179643634],
|
4195
|
+
[73.26040086468937, 76.24944728617226, 37.83955519155184]]
|
4196
|
+
|
4197
|
+
res = softplus(a)
|
4198
|
+
assert_allclose(res, ref, rtol=2e-15)
|
4199
|
+
|
4200
|
+
def test_softplus_with_kwargs(self):
|
4201
|
+
x = np.arange(5) - 2
|
4202
|
+
out = np.ones(5)
|
4203
|
+
ref = out.copy()
|
4204
|
+
where = x > 0
|
4205
|
+
|
4206
|
+
softplus(x, out=out, where=where)
|
4207
|
+
ref[where] = softplus(x[where])
|
4208
|
+
assert_allclose(out, ref)
|
4209
|
+
|
4210
|
+
|
4211
|
+
class TestRound:
|
4212
|
+
def test_round(self):
|
4213
|
+
rnd = list(map(int, (special.round(10.1),
|
4214
|
+
special.round(10.4),
|
4215
|
+
special.round(10.5),
|
4216
|
+
special.round(10.6))))
|
4217
|
+
|
4218
|
+
# Note: According to the documentation, scipy.special.round is
|
4219
|
+
# supposed to round to the nearest even number if the fractional
|
4220
|
+
# part is exactly 0.5. On some platforms, this does not appear
|
4221
|
+
# to work and thus this test may fail. However, this unit test is
|
4222
|
+
# correctly written.
|
4223
|
+
rndrl = (10,10,10,11)
|
4224
|
+
assert_array_equal(rnd,rndrl)
|
4225
|
+
|
4226
|
+
# sph_harm is deprecated and is implemented as a shim around sph_harm_y.
|
4227
|
+
# The following two tests are maintained to verify the correctness of the shim.
|
4228
|
+
|
4229
|
+
def test_sph_harm():
|
4230
|
+
# Tests derived from tables in
|
4231
|
+
# https://en.wikipedia.org/wiki/Table_of_spherical_harmonics
|
4232
|
+
sh = special.sph_harm
|
4233
|
+
pi = np.pi
|
4234
|
+
exp = np.exp
|
4235
|
+
sqrt = np.sqrt
|
4236
|
+
sin = np.sin
|
4237
|
+
cos = np.cos
|
4238
|
+
with suppress_warnings() as sup:
|
4239
|
+
sup.filter(category=DeprecationWarning)
|
4240
|
+
assert_array_almost_equal(sh(0,0,0,0),
|
4241
|
+
0.5/sqrt(pi))
|
4242
|
+
assert_array_almost_equal(sh(-2,2,0.,pi/4),
|
4243
|
+
0.25*sqrt(15./(2.*pi)) *
|
4244
|
+
(sin(pi/4))**2.)
|
4245
|
+
assert_array_almost_equal(sh(-2,2,0.,pi/2),
|
4246
|
+
0.25*sqrt(15./(2.*pi)))
|
4247
|
+
assert_array_almost_equal(sh(2,2,pi,pi/2),
|
4248
|
+
0.25*sqrt(15/(2.*pi)) *
|
4249
|
+
exp(0+2.*pi*1j)*sin(pi/2.)**2.)
|
4250
|
+
assert_array_almost_equal(sh(2,4,pi/4.,pi/3.),
|
4251
|
+
(3./8.)*sqrt(5./(2.*pi)) *
|
4252
|
+
exp(0+2.*pi/4.*1j) *
|
4253
|
+
sin(pi/3.)**2. *
|
4254
|
+
(7.*cos(pi/3.)**2.-1))
|
4255
|
+
assert_array_almost_equal(sh(4,4,pi/8.,pi/6.),
|
4256
|
+
(3./16.)*sqrt(35./(2.*pi)) *
|
4257
|
+
exp(0+4.*pi/8.*1j)*sin(pi/6.)**4.)
|
4258
|
+
|
4259
|
+
|
4260
|
+
def test_sph_harm_ufunc_loop_selection():
|
4261
|
+
# see https://github.com/scipy/scipy/issues/4895
|
4262
|
+
dt = np.dtype(np.complex128)
|
4263
|
+
with suppress_warnings() as sup:
|
4264
|
+
sup.filter(category=DeprecationWarning)
|
4265
|
+
assert_equal(special.sph_harm(0, 0, 0, 0).dtype, dt)
|
4266
|
+
assert_equal(special.sph_harm([0], 0, 0, 0).dtype, dt)
|
4267
|
+
assert_equal(special.sph_harm(0, [0], 0, 0).dtype, dt)
|
4268
|
+
assert_equal(special.sph_harm(0, 0, [0], 0).dtype, dt)
|
4269
|
+
assert_equal(special.sph_harm(0, 0, 0, [0]).dtype, dt)
|
4270
|
+
assert_equal(special.sph_harm([0], [0], [0], [0]).dtype, dt)
|
4271
|
+
|
4272
|
+
|
4273
|
+
class TestStruve:
|
4274
|
+
def _series(self, v, z, n=100):
|
4275
|
+
"""Compute Struve function & error estimate from its power series."""
|
4276
|
+
k = arange(0, n)
|
4277
|
+
r = (-1)**k * (.5*z)**(2*k+v+1)/special.gamma(k+1.5)/special.gamma(k+v+1.5)
|
4278
|
+
err = abs(r).max() * finfo(double).eps * n
|
4279
|
+
return r.sum(), err
|
4280
|
+
|
4281
|
+
def test_vs_series(self):
|
4282
|
+
"""Check Struve function versus its power series"""
|
4283
|
+
for v in [-20, -10, -7.99, -3.4, -1, 0, 1, 3.4, 12.49, 16]:
|
4284
|
+
for z in [1, 10, 19, 21, 30]:
|
4285
|
+
value, err = self._series(v, z)
|
4286
|
+
assert_allclose(special.struve(v, z), value, rtol=0, atol=err), (v, z)
|
4287
|
+
|
4288
|
+
def test_some_values(self):
|
4289
|
+
assert_allclose(special.struve(-7.99, 21), 0.0467547614113, rtol=1e-7)
|
4290
|
+
assert_allclose(special.struve(-8.01, 21), 0.0398716951023, rtol=1e-8)
|
4291
|
+
assert_allclose(special.struve(-3.0, 200), 0.0142134427432, rtol=1e-12)
|
4292
|
+
assert_allclose(special.struve(-8.0, -41), 0.0192469727846, rtol=1e-11)
|
4293
|
+
assert_equal(special.struve(-12, -41), -special.struve(-12, 41))
|
4294
|
+
assert_equal(special.struve(+12, -41), -special.struve(+12, 41))
|
4295
|
+
assert_equal(special.struve(-11, -41), +special.struve(-11, 41))
|
4296
|
+
assert_equal(special.struve(+11, -41), +special.struve(+11, 41))
|
4297
|
+
|
4298
|
+
assert_(isnan(special.struve(-7.1, -1)))
|
4299
|
+
assert_(isnan(special.struve(-10.1, -1)))
|
4300
|
+
|
4301
|
+
def test_regression_679(self):
|
4302
|
+
"""Regression test for #679"""
|
4303
|
+
assert_allclose(special.struve(-1.0, 20 - 1e-8),
|
4304
|
+
special.struve(-1.0, 20 + 1e-8))
|
4305
|
+
assert_allclose(special.struve(-2.0, 20 - 1e-8),
|
4306
|
+
special.struve(-2.0, 20 + 1e-8))
|
4307
|
+
assert_allclose(special.struve(-4.3, 20 - 1e-8),
|
4308
|
+
special.struve(-4.3, 20 + 1e-8))
|
4309
|
+
|
4310
|
+
|
4311
|
+
def test_chi2_smalldf():
|
4312
|
+
assert_almost_equal(special.chdtr(0.6,3), 0.957890536704110)
|
4313
|
+
|
4314
|
+
|
4315
|
+
def test_ch2_inf():
|
4316
|
+
assert_equal(special.chdtr(0.7,np.inf), 1.0)
|
4317
|
+
|
4318
|
+
|
4319
|
+
@pytest.mark.parametrize("x", [-np.inf, -1.0, -0.0, 0.0, np.inf, np.nan])
|
4320
|
+
def test_chi2_v_nan(x):
|
4321
|
+
assert np.isnan(special.chdtr(np.nan, x))
|
4322
|
+
|
4323
|
+
|
4324
|
+
@pytest.mark.parametrize("v", [-np.inf, -1.0, -0.0, 0.0, np.inf, np.nan])
|
4325
|
+
def test_chi2_x_nan(v):
|
4326
|
+
assert np.isnan(special.chdtr(v, np.nan))
|
4327
|
+
|
4328
|
+
|
4329
|
+
@pytest.mark.parametrize("x", [-np.inf, -1.0, -0.0, 0.0, np.inf, np.nan])
|
4330
|
+
def test_chi2c_v_nan(x):
|
4331
|
+
assert np.isnan(special.chdtrc(np.nan, x))
|
4332
|
+
|
4333
|
+
|
4334
|
+
@pytest.mark.parametrize("v", [-np.inf, -1.0, -0.0, 0.0, np.inf, np.nan])
|
4335
|
+
def test_chi2c_x_nan(v):
|
4336
|
+
assert np.isnan(special.chdtrc(v, np.nan))
|
4337
|
+
|
4338
|
+
|
4339
|
+
def test_chi2_edgecases_gh20972():
|
4340
|
+
# Tests that a variety of edgecases for chi square distribution functions
|
4341
|
+
# correctly return NaN when and only when they are supposed to, when
|
4342
|
+
# computed through different related ufuncs. See gh-20972.
|
4343
|
+
v = np.asarray([-0.01, 0, 0.01, 1, np.inf])[:, np.newaxis]
|
4344
|
+
x = np.asarray([-np.inf, -0.01, 0, 0.01, np.inf])
|
4345
|
+
|
4346
|
+
# Check that `gammainc` is NaN when it should be and finite otherwise
|
4347
|
+
ref = special.gammainc(v / 2, x / 2)
|
4348
|
+
mask = (x < 0) | (v < 0) | (x == 0) & (v == 0) | np.isinf(v) & np.isinf(x)
|
4349
|
+
assert np.all(np.isnan(ref[mask]))
|
4350
|
+
assert np.all(np.isfinite(ref[~mask]))
|
4351
|
+
|
4352
|
+
# Use `gammainc` as a reference for the rest
|
4353
|
+
assert_allclose(special.chdtr(v, x), ref)
|
4354
|
+
assert_allclose(special.gdtr(1, v / 2, x / 2), ref)
|
4355
|
+
assert_allclose(1 - special.gammaincc(v / 2, x / 2), ref)
|
4356
|
+
assert_allclose(1 - special.chdtrc(v, x), ref)
|
4357
|
+
assert_allclose(1 - special.gdtrc(1, v / 2, x / 2), ref)
|
4358
|
+
|
4359
|
+
|
4360
|
+
def test_chi2c_smalldf():
|
4361
|
+
assert_almost_equal(special.chdtrc(0.6,3), 1-0.957890536704110)
|
4362
|
+
|
4363
|
+
|
4364
|
+
def test_chi2_inv_smalldf():
|
4365
|
+
assert_almost_equal(special.chdtri(0.6,1-0.957890536704110), 3)
|
4366
|
+
|
4367
|
+
|
4368
|
+
def test_agm_simple():
|
4369
|
+
rtol = 1e-13
|
4370
|
+
|
4371
|
+
# Gauss's constant
|
4372
|
+
assert_allclose(1/special.agm(1, np.sqrt(2)), 0.834626841674073186,
|
4373
|
+
rtol=rtol)
|
4374
|
+
|
4375
|
+
# These values were computed using Wolfram Alpha, with the
|
4376
|
+
# function ArithmeticGeometricMean[a, b].
|
4377
|
+
agm13 = 1.863616783244897
|
4378
|
+
agm15 = 2.604008190530940
|
4379
|
+
agm35 = 3.936235503649555
|
4380
|
+
assert_allclose(special.agm([[1], [3]], [1, 3, 5]),
|
4381
|
+
[[1, agm13, agm15],
|
4382
|
+
[agm13, 3, agm35]], rtol=rtol)
|
4383
|
+
|
4384
|
+
# Computed by the iteration formula using mpmath,
|
4385
|
+
# with mpmath.mp.prec = 1000:
|
4386
|
+
agm12 = 1.4567910310469068
|
4387
|
+
assert_allclose(special.agm(1, 2), agm12, rtol=rtol)
|
4388
|
+
assert_allclose(special.agm(2, 1), agm12, rtol=rtol)
|
4389
|
+
assert_allclose(special.agm(-1, -2), -agm12, rtol=rtol)
|
4390
|
+
assert_allclose(special.agm(24, 6), 13.458171481725614, rtol=rtol)
|
4391
|
+
assert_allclose(special.agm(13, 123456789.5), 11111458.498599306,
|
4392
|
+
rtol=rtol)
|
4393
|
+
assert_allclose(special.agm(1e30, 1), 2.229223055945383e+28, rtol=rtol)
|
4394
|
+
assert_allclose(special.agm(1e-22, 1), 0.030182566420169886, rtol=rtol)
|
4395
|
+
assert_allclose(special.agm(1e150, 1e180), 2.229223055945383e+178,
|
4396
|
+
rtol=rtol)
|
4397
|
+
assert_allclose(special.agm(1e180, 1e-150), 2.0634722510162677e+177,
|
4398
|
+
rtol=rtol)
|
4399
|
+
assert_allclose(special.agm(1e-150, 1e-170), 3.3112619670463756e-152,
|
4400
|
+
rtol=rtol)
|
4401
|
+
fi = np.finfo(1.0)
|
4402
|
+
assert_allclose(special.agm(fi.tiny, fi.max), 1.9892072050015473e+305,
|
4403
|
+
rtol=rtol)
|
4404
|
+
assert_allclose(special.agm(0.75*fi.max, fi.max), 1.564904312298045e+308,
|
4405
|
+
rtol=rtol)
|
4406
|
+
assert_allclose(special.agm(fi.tiny, 3*fi.tiny), 4.1466849866735005e-308,
|
4407
|
+
rtol=rtol)
|
4408
|
+
|
4409
|
+
# zero, nan and inf cases.
|
4410
|
+
assert_equal(special.agm(0, 0), 0)
|
4411
|
+
assert_equal(special.agm(99, 0), 0)
|
4412
|
+
|
4413
|
+
assert_equal(special.agm(-1, 10), np.nan)
|
4414
|
+
assert_equal(special.agm(0, np.inf), np.nan)
|
4415
|
+
assert_equal(special.agm(np.inf, 0), np.nan)
|
4416
|
+
assert_equal(special.agm(0, -np.inf), np.nan)
|
4417
|
+
assert_equal(special.agm(-np.inf, 0), np.nan)
|
4418
|
+
assert_equal(special.agm(np.inf, -np.inf), np.nan)
|
4419
|
+
assert_equal(special.agm(-np.inf, np.inf), np.nan)
|
4420
|
+
assert_equal(special.agm(1, np.nan), np.nan)
|
4421
|
+
assert_equal(special.agm(np.nan, -1), np.nan)
|
4422
|
+
|
4423
|
+
assert_equal(special.agm(1, np.inf), np.inf)
|
4424
|
+
assert_equal(special.agm(np.inf, 1), np.inf)
|
4425
|
+
assert_equal(special.agm(-1, -np.inf), -np.inf)
|
4426
|
+
assert_equal(special.agm(-np.inf, -1), -np.inf)
|
4427
|
+
|
4428
|
+
|
4429
|
+
def test_legacy():
|
4430
|
+
# Legacy behavior: truncating arguments to integers
|
4431
|
+
with suppress_warnings() as sup:
|
4432
|
+
sup.filter(RuntimeWarning, "floating point number truncated to an integer")
|
4433
|
+
assert_equal(special.expn(1, 0.3), special.expn(1.8, 0.3))
|
4434
|
+
assert_equal(special.nbdtrc(1, 2, 0.3), special.nbdtrc(1.8, 2.8, 0.3))
|
4435
|
+
assert_equal(special.nbdtr(1, 2, 0.3), special.nbdtr(1.8, 2.8, 0.3))
|
4436
|
+
assert_equal(special.nbdtri(1, 2, 0.3), special.nbdtri(1.8, 2.8, 0.3))
|
4437
|
+
assert_equal(special.pdtri(1, 0.3), special.pdtri(1.8, 0.3))
|
4438
|
+
assert_equal(special.kn(1, 0.3), special.kn(1.8, 0.3))
|
4439
|
+
assert_equal(special.yn(1, 0.3), special.yn(1.8, 0.3))
|
4440
|
+
assert_equal(special.smirnov(1, 0.3), special.smirnov(1.8, 0.3))
|
4441
|
+
assert_equal(special.smirnovi(1, 0.3), special.smirnovi(1.8, 0.3))
|
4442
|
+
|
4443
|
+
|
4444
|
+
# This lock can be removed once errstate is made thread-safe (see gh-21956)
|
4445
|
+
@pytest.fixture
|
4446
|
+
def errstate_lock():
|
4447
|
+
import threading
|
4448
|
+
return threading.Lock()
|
4449
|
+
|
4450
|
+
|
4451
|
+
@with_special_errors
|
4452
|
+
def test_error_raising(errstate_lock):
|
4453
|
+
with errstate_lock:
|
4454
|
+
with special.errstate(all='raise'):
|
4455
|
+
assert_raises(special.SpecialFunctionError, special.iv, 1, 1e99j)
|
4456
|
+
|
4457
|
+
|
4458
|
+
def test_xlogy():
|
4459
|
+
def xfunc(x, y):
|
4460
|
+
with np.errstate(invalid='ignore'):
|
4461
|
+
if x == 0 and not np.isnan(y):
|
4462
|
+
return x
|
4463
|
+
else:
|
4464
|
+
return x*np.log(y)
|
4465
|
+
|
4466
|
+
z1 = np.asarray([(0,0), (0, np.nan), (0, np.inf), (1.0, 2.0)], dtype=float)
|
4467
|
+
z2 = np.r_[z1, [(0, 1j), (1, 1j)]]
|
4468
|
+
|
4469
|
+
w1 = np.vectorize(xfunc)(z1[:,0], z1[:,1])
|
4470
|
+
assert_func_equal(special.xlogy, w1, z1, rtol=1e-13, atol=1e-13)
|
4471
|
+
w2 = np.vectorize(xfunc)(z2[:,0], z2[:,1])
|
4472
|
+
assert_func_equal(special.xlogy, w2, z2, rtol=1e-13, atol=1e-13)
|
4473
|
+
|
4474
|
+
|
4475
|
+
def test_xlog1py():
|
4476
|
+
def xfunc(x, y):
|
4477
|
+
with np.errstate(invalid='ignore'):
|
4478
|
+
if x == 0 and not np.isnan(y):
|
4479
|
+
return x
|
4480
|
+
else:
|
4481
|
+
return x * np.log1p(y)
|
4482
|
+
|
4483
|
+
z1 = np.asarray([(0,0), (0, np.nan), (0, np.inf), (1.0, 2.0),
|
4484
|
+
(1, 1e-30)], dtype=float)
|
4485
|
+
w1 = np.vectorize(xfunc)(z1[:,0], z1[:,1])
|
4486
|
+
assert_func_equal(special.xlog1py, w1, z1, rtol=1e-13, atol=1e-13)
|
4487
|
+
|
4488
|
+
|
4489
|
+
def test_entr():
|
4490
|
+
def xfunc(x):
|
4491
|
+
if x < 0:
|
4492
|
+
return -np.inf
|
4493
|
+
else:
|
4494
|
+
return -special.xlogy(x, x)
|
4495
|
+
values = (0, 0.5, 1.0, np.inf)
|
4496
|
+
signs = [-1, 1]
|
4497
|
+
arr = []
|
4498
|
+
for sgn, v in itertools.product(signs, values):
|
4499
|
+
arr.append(sgn * v)
|
4500
|
+
z = np.array(arr, dtype=float)
|
4501
|
+
w = np.vectorize(xfunc, otypes=[np.float64])(z)
|
4502
|
+
assert_func_equal(special.entr, w, z, rtol=1e-13, atol=1e-13)
|
4503
|
+
|
4504
|
+
|
4505
|
+
def test_kl_div():
|
4506
|
+
def xfunc(x, y):
|
4507
|
+
if x < 0 or y < 0 or (y == 0 and x != 0):
|
4508
|
+
# extension of natural domain to preserve convexity
|
4509
|
+
return np.inf
|
4510
|
+
elif np.isposinf(x) or np.isposinf(y):
|
4511
|
+
# limits within the natural domain
|
4512
|
+
return np.inf
|
4513
|
+
elif x == 0:
|
4514
|
+
return y
|
4515
|
+
else:
|
4516
|
+
return special.xlogy(x, x/y) - x + y
|
4517
|
+
values = (0, 0.5, 1.0)
|
4518
|
+
signs = [-1, 1]
|
4519
|
+
arr = []
|
4520
|
+
for sgna, va, sgnb, vb in itertools.product(signs, values, signs, values):
|
4521
|
+
arr.append((sgna*va, sgnb*vb))
|
4522
|
+
z = np.array(arr, dtype=float)
|
4523
|
+
w = np.vectorize(xfunc, otypes=[np.float64])(z[:,0], z[:,1])
|
4524
|
+
assert_func_equal(special.kl_div, w, z, rtol=1e-13, atol=1e-13)
|
4525
|
+
|
4526
|
+
|
4527
|
+
def test_rel_entr():
|
4528
|
+
def xfunc(x, y):
|
4529
|
+
if x > 0 and y > 0:
|
4530
|
+
return special.xlogy(x, x/y)
|
4531
|
+
elif x == 0 and y >= 0:
|
4532
|
+
return 0
|
4533
|
+
else:
|
4534
|
+
return np.inf
|
4535
|
+
values = (0, 0.5, 1.0)
|
4536
|
+
signs = [-1, 1]
|
4537
|
+
arr = []
|
4538
|
+
for sgna, va, sgnb, vb in itertools.product(signs, values, signs, values):
|
4539
|
+
arr.append((sgna*va, sgnb*vb))
|
4540
|
+
z = np.array(arr, dtype=float)
|
4541
|
+
w = np.vectorize(xfunc, otypes=[np.float64])(z[:,0], z[:,1])
|
4542
|
+
assert_func_equal(special.rel_entr, w, z, rtol=1e-13, atol=1e-13)
|
4543
|
+
|
4544
|
+
|
4545
|
+
def test_rel_entr_gh_20710_near_zero():
|
4546
|
+
# Check accuracy of inputs which are very close
|
4547
|
+
inputs = np.array([
|
4548
|
+
# x, y
|
4549
|
+
(0.9456657713430001, 0.9456657713430094),
|
4550
|
+
(0.48066098564791515, 0.48066098564794774),
|
4551
|
+
(0.786048657854401, 0.7860486578542367),
|
4552
|
+
])
|
4553
|
+
# Known values produced using `x * mpmath.log(x / y)` with dps=30
|
4554
|
+
expected = [
|
4555
|
+
-9.325873406851269e-15,
|
4556
|
+
-3.258504577274724e-14,
|
4557
|
+
1.6431300764454033e-13,
|
4558
|
+
]
|
4559
|
+
x = inputs[:, 0]
|
4560
|
+
y = inputs[:, 1]
|
4561
|
+
assert_allclose(special.rel_entr(x, y), expected, rtol=1e-13, atol=0)
|
4562
|
+
|
4563
|
+
|
4564
|
+
def test_rel_entr_gh_20710_overflow():
|
4565
|
+
special.seterr(all='ignore')
|
4566
|
+
inputs = np.array([
|
4567
|
+
# x, y
|
4568
|
+
# Overflow
|
4569
|
+
(4, 2.22e-308),
|
4570
|
+
# Underflow
|
4571
|
+
(1e-200, 1e+200),
|
4572
|
+
# Subnormal
|
4573
|
+
(2.22e-308, 1e15),
|
4574
|
+
])
|
4575
|
+
# Known values produced using `x * mpmath.log(x / y)` with dps=30
|
4576
|
+
expected = [
|
4577
|
+
2839.139983229607,
|
4578
|
+
-9.210340371976183e-198,
|
4579
|
+
-1.6493212008074475e-305,
|
4580
|
+
]
|
4581
|
+
x = inputs[:, 0]
|
4582
|
+
y = inputs[:, 1]
|
4583
|
+
assert_allclose(special.rel_entr(x, y), expected, rtol=1e-13, atol=0)
|
4584
|
+
|
4585
|
+
|
4586
|
+
def test_huber():
|
4587
|
+
assert_equal(special.huber(-1, 1.5), np.inf)
|
4588
|
+
assert_allclose(special.huber(2, 1.5), 0.5 * np.square(1.5))
|
4589
|
+
assert_allclose(special.huber(2, 2.5), 2 * (2.5 - 0.5 * 2))
|
4590
|
+
|
4591
|
+
def xfunc(delta, r):
|
4592
|
+
if delta < 0:
|
4593
|
+
return np.inf
|
4594
|
+
elif np.abs(r) < delta:
|
4595
|
+
return 0.5 * np.square(r)
|
4596
|
+
else:
|
4597
|
+
return delta * (np.abs(r) - 0.5 * delta)
|
4598
|
+
|
4599
|
+
z = np.random.randn(10, 2)
|
4600
|
+
w = np.vectorize(xfunc, otypes=[np.float64])(z[:,0], z[:,1])
|
4601
|
+
assert_func_equal(special.huber, w, z, rtol=1e-13, atol=1e-13)
|
4602
|
+
|
4603
|
+
|
4604
|
+
def test_pseudo_huber():
|
4605
|
+
def xfunc(delta, r):
|
4606
|
+
if delta < 0:
|
4607
|
+
return np.inf
|
4608
|
+
elif (not delta) or (not r):
|
4609
|
+
return 0
|
4610
|
+
else:
|
4611
|
+
return delta**2 * (np.sqrt(1 + (r/delta)**2) - 1)
|
4612
|
+
|
4613
|
+
z = np.array(np.random.randn(10, 2).tolist() + [[0, 0.5], [0.5, 0]])
|
4614
|
+
w = np.vectorize(xfunc, otypes=[np.float64])(z[:,0], z[:,1])
|
4615
|
+
assert_func_equal(special.pseudo_huber, w, z, rtol=1e-13, atol=1e-13)
|
4616
|
+
|
4617
|
+
|
4618
|
+
def test_pseudo_huber_small_r():
|
4619
|
+
delta = 1.0
|
4620
|
+
r = 1e-18
|
4621
|
+
y = special.pseudo_huber(delta, r)
|
4622
|
+
# expected computed with mpmath:
|
4623
|
+
# import mpmath
|
4624
|
+
# mpmath.mp.dps = 200
|
4625
|
+
# r = mpmath.mpf(1e-18)
|
4626
|
+
# expected = float(mpmath.sqrt(1 + r**2) - 1)
|
4627
|
+
expected = 5.0000000000000005e-37
|
4628
|
+
assert_allclose(y, expected, rtol=1e-13)
|
4629
|
+
|
4630
|
+
|
4631
|
+
@pytest.mark.thread_unsafe
|
4632
|
+
def test_runtime_warning():
|
4633
|
+
with pytest.warns(RuntimeWarning,
|
4634
|
+
match=r'Too many predicted coefficients'):
|
4635
|
+
mathieu_odd_coef(1000, 1000)
|
4636
|
+
with pytest.warns(RuntimeWarning,
|
4637
|
+
match=r'Too many predicted coefficients'):
|
4638
|
+
mathieu_even_coef(1000, 1000)
|
4639
|
+
|
4640
|
+
|
4641
|
+
class TestStirling2:
|
4642
|
+
table = [
|
4643
|
+
[1],
|
4644
|
+
[0, 1],
|
4645
|
+
[0, 1, 1],
|
4646
|
+
[0, 1, 3, 1],
|
4647
|
+
[0, 1, 7, 6, 1],
|
4648
|
+
[0, 1, 15, 25, 10, 1],
|
4649
|
+
[0, 1, 31, 90, 65, 15, 1],
|
4650
|
+
[0, 1, 63, 301, 350, 140, 21, 1],
|
4651
|
+
[0, 1, 127, 966, 1701, 1050, 266, 28, 1],
|
4652
|
+
[0, 1, 255, 3025, 7770, 6951, 2646, 462, 36, 1],
|
4653
|
+
[0, 1, 511, 9330, 34105, 42525, 22827, 5880, 750, 45, 1],
|
4654
|
+
]
|
4655
|
+
|
4656
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4657
|
+
(True, assert_equal, {}),
|
4658
|
+
(False, assert_allclose, {'rtol': 1e-12})
|
4659
|
+
])
|
4660
|
+
def test_table_cases(self, is_exact, comp, kwargs):
|
4661
|
+
for n in range(1, len(self.table)):
|
4662
|
+
k_values = list(range(n+1))
|
4663
|
+
row = self.table[n]
|
4664
|
+
comp(row, stirling2([n], k_values, exact=is_exact), **kwargs)
|
4665
|
+
|
4666
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4667
|
+
(True, assert_equal, {}),
|
4668
|
+
(False, assert_allclose, {'rtol': 1e-12})
|
4669
|
+
])
|
4670
|
+
def test_valid_single_integer(self, is_exact, comp, kwargs):
|
4671
|
+
comp(stirling2(0, 0, exact=is_exact), self.table[0][0], **kwargs)
|
4672
|
+
comp(stirling2(4, 2, exact=is_exact), self.table[4][2], **kwargs)
|
4673
|
+
# a single 2-tuple of integers as arguments must return an int and not
|
4674
|
+
# an array whereas arrays of single values should return array
|
4675
|
+
comp(stirling2(5, 3, exact=is_exact), 25, **kwargs)
|
4676
|
+
comp(stirling2([5], [3], exact=is_exact), [25], **kwargs)
|
4677
|
+
|
4678
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4679
|
+
(True, assert_equal, {}),
|
4680
|
+
(False, assert_allclose, {'rtol': 1e-12})
|
4681
|
+
])
|
4682
|
+
def test_negative_integer(self, is_exact, comp, kwargs):
|
4683
|
+
# negative integers for n or k arguments return 0
|
4684
|
+
comp(stirling2(-1, -1, exact=is_exact), 0, **kwargs)
|
4685
|
+
comp(stirling2(-1, 2, exact=is_exact), 0, **kwargs)
|
4686
|
+
comp(stirling2(2, -1, exact=is_exact), 0, **kwargs)
|
4687
|
+
|
4688
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4689
|
+
(True, assert_equal, {}),
|
4690
|
+
(False, assert_allclose, {'rtol': 1e-12})
|
4691
|
+
])
|
4692
|
+
def test_array_inputs(self, is_exact, comp, kwargs):
|
4693
|
+
ans = [self.table[10][3], self.table[10][4]]
|
4694
|
+
comp(stirling2(asarray([10, 10]),
|
4695
|
+
asarray([3, 4]),
|
4696
|
+
exact=is_exact),
|
4697
|
+
ans)
|
4698
|
+
comp(stirling2([10, 10],
|
4699
|
+
asarray([3, 4]),
|
4700
|
+
exact=is_exact),
|
4701
|
+
ans)
|
4702
|
+
comp(stirling2(asarray([10, 10]),
|
4703
|
+
[3, 4],
|
4704
|
+
exact=is_exact),
|
4705
|
+
ans)
|
4706
|
+
|
4707
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4708
|
+
(True, assert_equal, {}),
|
4709
|
+
(False, assert_allclose, {'rtol': 1e-13})
|
4710
|
+
])
|
4711
|
+
def test_mixed_values(self, is_exact, comp, kwargs):
|
4712
|
+
# negative values-of either n or k-should return 0 for the entry
|
4713
|
+
ans = [0, 1, 3, 25, 1050, 5880, 9330]
|
4714
|
+
n = [-1, 0, 3, 5, 8, 10, 10]
|
4715
|
+
k = [-2, 0, 2, 3, 5, 7, 3]
|
4716
|
+
comp(stirling2(n, k, exact=is_exact), ans, **kwargs)
|
4717
|
+
|
4718
|
+
def test_correct_parity(self):
|
4719
|
+
"""Test parity follows well known identity.
|
4720
|
+
|
4721
|
+
en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind#Parity
|
4722
|
+
"""
|
4723
|
+
n, K = 100, np.arange(101)
|
4724
|
+
assert_equal(
|
4725
|
+
stirling2(n, K, exact=True) % 2,
|
4726
|
+
[math.comb(n - (k // 2) - 1, n - k) % 2 for k in K],
|
4727
|
+
)
|
4728
|
+
|
4729
|
+
def test_big_numbers(self):
|
4730
|
+
# via mpmath (bigger than 32bit)
|
4731
|
+
ans = asarray([48063331393110, 48004081105038305])
|
4732
|
+
n = [25, 30]
|
4733
|
+
k = [17, 4]
|
4734
|
+
assert array_equal(stirling2(n, k, exact=True), ans)
|
4735
|
+
# bigger than 64 bit
|
4736
|
+
ans = asarray([2801934359500572414253157841233849412,
|
4737
|
+
14245032222277144547280648984426251])
|
4738
|
+
n = [42, 43]
|
4739
|
+
k = [17, 23]
|
4740
|
+
assert array_equal(stirling2(n, k, exact=True), ans)
|
4741
|
+
|
4742
|
+
@pytest.mark.parametrize("N", [4.5, 3., 4+1j, "12", np.nan])
|
4743
|
+
@pytest.mark.parametrize("K", [3.5, 3, "2", None])
|
4744
|
+
@pytest.mark.parametrize("is_exact", [True, False])
|
4745
|
+
def test_unsupported_input_types(self, N, K, is_exact):
|
4746
|
+
# object, float, string, complex are not supported and raise TypeError
|
4747
|
+
with pytest.raises(TypeError):
|
4748
|
+
stirling2(N, K, exact=is_exact)
|
4749
|
+
|
4750
|
+
@pytest.mark.parametrize("is_exact", [True, False])
|
4751
|
+
def test_numpy_array_int_object_dtype(self, is_exact):
|
4752
|
+
# python integers with arbitrary precision are *not* allowed as
|
4753
|
+
# object type in numpy arrays are inconsistent from api perspective
|
4754
|
+
ans = asarray(self.table[4][1:])
|
4755
|
+
n = asarray([4, 4, 4, 4], dtype=object)
|
4756
|
+
k = asarray([1, 2, 3, 4], dtype=object)
|
4757
|
+
with pytest.raises(TypeError):
|
4758
|
+
array_equal(stirling2(n, k, exact=is_exact), ans)
|
4759
|
+
|
4760
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4761
|
+
(True, assert_equal, {}),
|
4762
|
+
(False, assert_allclose, {'rtol': 1e-13})
|
4763
|
+
])
|
4764
|
+
def test_numpy_array_unsigned_int_dtype(self, is_exact, comp, kwargs):
|
4765
|
+
# numpy unsigned integers are allowed as dtype in numpy arrays
|
4766
|
+
ans = asarray(self.table[4][1:])
|
4767
|
+
n = asarray([4, 4, 4, 4], dtype=np_ulong)
|
4768
|
+
k = asarray([1, 2, 3, 4], dtype=np_ulong)
|
4769
|
+
comp(stirling2(n, k, exact=False), ans, **kwargs)
|
4770
|
+
|
4771
|
+
@pytest.mark.parametrize("is_exact, comp, kwargs", [
|
4772
|
+
(True, assert_equal, {}),
|
4773
|
+
(False, assert_allclose, {'rtol': 1e-13})
|
4774
|
+
])
|
4775
|
+
def test_broadcasting_arrays_correctly(self, is_exact, comp, kwargs):
|
4776
|
+
# broadcasting is handled by stirling2
|
4777
|
+
# test leading 1s are replicated
|
4778
|
+
ans = asarray([[1, 15, 25, 10], [1, 7, 6, 1]]) # shape (2,4)
|
4779
|
+
n = asarray([[5, 5, 5, 5], [4, 4, 4, 4]]) # shape (2,4)
|
4780
|
+
k = asarray([1, 2, 3, 4]) # shape (4,)
|
4781
|
+
comp(stirling2(n, k, exact=is_exact), ans, **kwargs)
|
4782
|
+
# test that dims both mismatch broadcast correctly (5,1) & (6,)
|
4783
|
+
n = asarray([[4], [4], [4], [4], [4]])
|
4784
|
+
k = asarray([0, 1, 2, 3, 4, 5])
|
4785
|
+
ans = asarray([[0, 1, 7, 6, 1, 0] for _ in range(5)])
|
4786
|
+
comp(stirling2(n, k, exact=False), ans, **kwargs)
|
4787
|
+
|
4788
|
+
def test_temme_rel_max_error(self):
|
4789
|
+
# python integers with arbitrary precision are *not* allowed as
|
4790
|
+
# object type in numpy arrays are inconsistent from api perspective
|
4791
|
+
x = list(range(51, 101, 5))
|
4792
|
+
for n in x:
|
4793
|
+
k_entries = list(range(1, n+1))
|
4794
|
+
denom = stirling2([n], k_entries, exact=True)
|
4795
|
+
num = denom - stirling2([n], k_entries, exact=False)
|
4796
|
+
assert np.max(np.abs(num / denom)) < 2e-5
|
4797
|
+
|
4798
|
+
|
4799
|
+
class TestLegendreDeprecation:
|
4800
|
+
|
4801
|
+
def test_warn_lpn(self):
|
4802
|
+
msg = "`scipy.special.lpn` is deprecated..."
|
4803
|
+
with pytest.deprecated_call(match=msg):
|
4804
|
+
_ = lpn(1, 0)
|
4805
|
+
|
4806
|
+
@pytest.mark.parametrize("xlpmn", [lpmn, clpmn])
|
4807
|
+
def test_warn_xlpmn(self, xlpmn):
|
4808
|
+
message = f"`scipy.special.{xlpmn.__name__}` is deprecated..."
|
4809
|
+
with pytest.deprecated_call(match=message):
|
4810
|
+
_ = xlpmn(1, 1, 0)
|
4811
|
+
|
4812
|
+
def test_warn_sph_harm(self):
|
4813
|
+
msg = "`scipy.special.sph_harm` is deprecated..."
|
4814
|
+
with pytest.deprecated_call(match=msg):
|
4815
|
+
_ = special.sph_harm(1, 1, 0, 0)
|