scipy 1.16.2__cp314-cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_cyutility.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_ccallback_c.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_fpumode.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_test_ccallback.cp314t-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_call.cp314t-win_arm64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_test_deprecation_def.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_lib/_uarray/_uarray.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/_lib/messagestream.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/cluster/_hierarchy.cp314t-win_arm64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp314t-win_arm64.lib +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp314t-win_arm64.pyd +0 -0
- scipy/cluster/_vq.cp314t-win_arm64.lib +0 -0
- scipy/cluster/_vq.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/fftpack/convolve.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_dop.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_lsoda.cp314t-win_arm64.pyd +0 -0
- scipy/integrate/_ode.py +1395 -0
- scipy/integrate/_odepack.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_odepack.cp314t-win_arm64.pyd +0 -0
- scipy/integrate/_odepack_py.py +273 -0
- scipy/integrate/_quad_vec.py +674 -0
- scipy/integrate/_quadpack.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_quadpack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_test_multivariate.cp314t-win_arm64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_test_odeint_banded.cp314t-win_arm64.pyd +0 -0
- scipy/integrate/_vode.cp314t-win_arm64.lib +0 -0
- scipy/integrate/_vode.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_dfitpack.cp314t-win_arm64.pyd +0 -0
- scipy/interpolate/_dierckx.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_dierckx.cp314t-win_arm64.pyd +0 -0
- scipy/interpolate/_fitpack.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_fitpack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_interpnd.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_ppoly.cp314t-win_arm64.pyd +0 -0
- scipy/interpolate/_rbf.py +290 -0
- scipy/interpolate/_rbfinterp.py +550 -0
- scipy/interpolate/_rbfinterp_pythran.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp314t-win_arm64.pyd +0 -0
- scipy/interpolate/_rgi.py +764 -0
- scipy/interpolate/_rgi_cython.cp314t-win_arm64.lib +0 -0
- scipy/interpolate/_rgi_cython.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/io/_test_fortran.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/io/matlab/_mio5_utils.cp314t-win_arm64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp314t-win_arm64.lib +0 -0
- scipy/io/matlab/_mio_utils.cp314t-win_arm64.pyd +0 -0
- scipy/io/matlab/_miobase.py +435 -0
- scipy/io/matlab/_streams.cp314t-win_arm64.lib +0 -0
- scipy/io/matlab/_streams.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_cythonized_array_utils.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_interpolative.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +356 -0
- scipy/linalg/_decomp_lu.py +401 -0
- scipy/linalg/_decomp_lu_cython.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_lu_cython.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_decomp_update.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +417 -0
- scipy/linalg/_fblas.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_fblas.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_flapack.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_flapack.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_lapack_subroutines.h +1521 -0
- scipy/linalg/_linalg_pythran.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_linalg_pythran.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs.py +1050 -0
- scipy/linalg/_matfuncs_expm.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_expm.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +107 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/_solve_toeplitz.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/linalg/cython_blas.cp314t-win_arm64.pyd +0 -0
- scipy/linalg/cython_blas.pxd +169 -0
- scipy/linalg/cython_blas.pyx +1432 -0
- scipy/linalg/cython_lapack.cp314t-win_arm64.lib +0 -0
- scipy/linalg/cython_lapack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/ndimage/_ctest.cp314t-win_arm64.pyd +0 -0
- scipy/ndimage/_cytest.cp314t-win_arm64.lib +0 -0
- scipy/ndimage/_cytest.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/ndimage/_nd_image.cp314t-win_arm64.pyd +0 -0
- scipy/ndimage/_ndimage_api.py +16 -0
- scipy/ndimage/_ni_docstrings.py +214 -0
- scipy/ndimage/_ni_label.cp314t-win_arm64.lib +0 -0
- scipy/ndimage/_ni_label.cp314t-win_arm64.pyd +0 -0
- scipy/ndimage/_ni_support.py +139 -0
- scipy/ndimage/_rank_filter_1d.cp314t-win_arm64.lib +0 -0
- scipy/ndimage/_rank_filter_1d.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/odr/__odrpack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_bglu_dense.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_direct.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_group_columns.cp314t-win_arm64.pyd +0 -0
- scipy/optimize/_hessian_update_strategy.py +479 -0
- scipy/optimize/_highspy/__init__.py +0 -0
- scipy/optimize/_highspy/_core.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_core.cp314t-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_highspy/_highs_options.cp314t-win_arm64.pyd +0 -0
- scipy/optimize/_highspy/_highs_wrapper.py +338 -0
- scipy/optimize/_isotonic.py +157 -0
- scipy/optimize/_lbfgsb.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_lbfgsb.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_lsap.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_lsq/givens_elimination.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_minpack.cp314t-win_arm64.pyd +0 -0
- scipy/optimize/_minpack_py.py +1178 -0
- scipy/optimize/_moduleTNC.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_moduleTNC.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_pava_pybind.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_slsqplib.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_trlib/_trlib.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/_zeros.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/optimize/cython_optimize/_zeros.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/signal/_max_len_seq_inner.cp314t-win_arm64.pyd +0 -0
- scipy/signal/_peak_finding.py +1310 -0
- scipy/signal/_peak_finding_utils.cp314t-win_arm64.lib +0 -0
- scipy/signal/_peak_finding_utils.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/signal/_sigtools.cp314t-win_arm64.pyd +0 -0
- scipy/signal/_sosfilt.cp314t-win_arm64.lib +0 -0
- scipy/signal/_sosfilt.cp314t-win_arm64.pyd +0 -0
- scipy/signal/_spectral_py.py +2471 -0
- scipy/signal/_spline.cp314t-win_arm64.lib +0 -0
- scipy/signal/_spline.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/signal/_upfirdn_apply.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/_csparsetools.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/_sparsetools.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_flow.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_laplacian.py +563 -0
- scipy/sparse/csgraph/_matching.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_matching.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_reordering.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_shortest_path.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_tools.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp314t-win_arm64.lib +0 -0
- scipy/sparse/csgraph/_traversal.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp314t-win_arm64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp314t-win_arm64.lib +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_ckdtree.cp314t-win_arm64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_distance_pybind.cp314t-win_arm64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_distance_wrap.cp314t-win_arm64.pyd +0 -0
- scipy/spatial/_geometric_slerp.py +238 -0
- scipy/spatial/_hausdorff.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_hausdorff.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_qhull.cp314t-win_arm64.pyd +0 -0
- scipy/spatial/_qhull.pyi +213 -0
- scipy/spatial/_spherical_voronoi.py +341 -0
- scipy/spatial/_voronoi.cp314t-win_arm64.lib +0 -0
- scipy/spatial/_voronoi.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/spatial/transform/_rigid_transform.cp314t-win_arm64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp314t-win_arm64.lib +0 -0
- scipy/spatial/transform/_rotation.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/special/_comb.cp314t-win_arm64.pyd +0 -0
- scipy/special/_ellip_harm.py +214 -0
- scipy/special/_ellip_harm_2.cp314t-win_arm64.lib +0 -0
- scipy/special/_ellip_harm_2.cp314t-win_arm64.pyd +0 -0
- scipy/special/_gufuncs.cp314t-win_arm64.lib +0 -0
- scipy/special/_gufuncs.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/special/_specfun.cp314t-win_arm64.pyd +0 -0
- scipy/special/_special_ufuncs.cp314t-win_arm64.lib +0 -0
- scipy/special/_special_ufuncs.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/special/_test_internal.cp314t-win_arm64.pyd +0 -0
- scipy/special/_test_internal.pyi +9 -0
- scipy/special/_testutils.py +321 -0
- scipy/special/_ufuncs.cp314t-win_arm64.lib +0 -0
- scipy/special/_ufuncs.cp314t-win_arm64.pyd +0 -0
- scipy/special/_ufuncs.pyi +522 -0
- scipy/special/_ufuncs.pyx +13173 -0
- scipy/special/_ufuncs_cxx.cp314t-win_arm64.lib +0 -0
- scipy/special/_ufuncs_cxx.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/special/cython_special.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_ansari_swilk_statistics.cp314t-win_arm64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +692 -0
- scipy/stats/_biasedurn.cp314t-win_arm64.lib +0 -0
- scipy/stats/_biasedurn.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_levy_stable/levyst.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_qmc_cy.cp314t-win_arm64.pyd +0 -0
- scipy/stats/_qmc_cy.pyi +54 -0
- scipy/stats/_qmvnt.py +454 -0
- scipy/stats/_qmvnt_cy.cp314t-win_arm64.lib +0 -0
- scipy/stats/_qmvnt_cy.cp314t-win_arm64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/__init__.py +4 -0
- scipy/stats/_rcont/rcont.cp314t-win_arm64.lib +0 -0
- scipy/stats/_rcont/rcont.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_sobol.cp314t-win_arm64.pyd +0 -0
- scipy/stats/_sobol.pyi +54 -0
- scipy/stats/_sobol_direction_numbers.npz +0 -0
- scipy/stats/_stats.cp314t-win_arm64.lib +0 -0
- scipy/stats/_stats.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_stats_pythran.cp314t-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.cp314t-win_arm64.lib +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp314t-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,2266 @@
|
|
1
|
+
__all__ = ['interp1d', 'interp2d', 'lagrange', 'PPoly', 'BPoly', 'NdPPoly']
|
2
|
+
|
3
|
+
from math import prod
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
from numpy import array, asarray, intp, poly1d, searchsorted
|
7
|
+
|
8
|
+
import scipy.special as spec
|
9
|
+
from scipy._lib._util import copy_if_needed
|
10
|
+
from scipy.special import comb
|
11
|
+
|
12
|
+
from . import _fitpack_py
|
13
|
+
from ._polyint import _Interpolator1D
|
14
|
+
from . import _ppoly
|
15
|
+
from ._interpnd import _ndim_coords_from_arrays
|
16
|
+
from ._bsplines import make_interp_spline, BSpline
|
17
|
+
|
18
|
+
|
19
|
+
def lagrange(x, w):
|
20
|
+
r"""
|
21
|
+
Return a Lagrange interpolating polynomial.
|
22
|
+
|
23
|
+
Given two 1-D arrays `x` and `w,` returns the Lagrange interpolating
|
24
|
+
polynomial through the points ``(x, w)``.
|
25
|
+
|
26
|
+
Warning: This implementation is numerically unstable. Do not expect to
|
27
|
+
be able to use more than about 20 points even if they are chosen optimally.
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
x : array_like
|
32
|
+
`x` represents the x-coordinates of a set of datapoints.
|
33
|
+
w : array_like
|
34
|
+
`w` represents the y-coordinates of a set of datapoints, i.e., f(`x`).
|
35
|
+
|
36
|
+
Returns
|
37
|
+
-------
|
38
|
+
lagrange : `numpy.poly1d` instance
|
39
|
+
The Lagrange interpolating polynomial.
|
40
|
+
|
41
|
+
Notes
|
42
|
+
-----
|
43
|
+
The name of this function refers to the fact that the returned object represents
|
44
|
+
a Lagrange polynomial, the unique polynomial of lowest degree that interpolates
|
45
|
+
a given set of data [1]_. It computes the polynomial using Newton's divided
|
46
|
+
differences formula [2]_; that is, it works with Newton basis polynomials rather
|
47
|
+
than Lagrange basis polynomials. For numerical calculations, the barycentric form
|
48
|
+
of Lagrange interpolation (`scipy.interpolate.BarycentricInterpolator`) is
|
49
|
+
typically more appropriate.
|
50
|
+
|
51
|
+
References
|
52
|
+
----------
|
53
|
+
.. [1] Lagrange polynomial. *Wikipedia*.
|
54
|
+
https://en.wikipedia.org/wiki/Lagrange_polynomial
|
55
|
+
.. [2] Newton polynomial. *Wikipedia*.
|
56
|
+
https://en.wikipedia.org/wiki/Newton_polynomial
|
57
|
+
|
58
|
+
Examples
|
59
|
+
--------
|
60
|
+
Interpolate :math:`f(x) = x^3` by 3 points.
|
61
|
+
|
62
|
+
>>> import numpy as np
|
63
|
+
>>> from scipy.interpolate import lagrange
|
64
|
+
>>> x = np.array([0, 1, 2])
|
65
|
+
>>> y = x**3
|
66
|
+
>>> poly = lagrange(x, y)
|
67
|
+
|
68
|
+
Since there are only 3 points, the Lagrange polynomial has degree 2. Explicitly,
|
69
|
+
it is given by
|
70
|
+
|
71
|
+
.. math::
|
72
|
+
|
73
|
+
\begin{aligned}
|
74
|
+
L(x) &= 1\times \frac{x (x - 2)}{-1} + 8\times \frac{x (x-1)}{2} \\
|
75
|
+
&= x (-2 + 3x)
|
76
|
+
\end{aligned}
|
77
|
+
|
78
|
+
>>> from numpy.polynomial.polynomial import Polynomial
|
79
|
+
>>> Polynomial(poly.coef[::-1]).coef
|
80
|
+
array([ 0., -2., 3.])
|
81
|
+
|
82
|
+
>>> import matplotlib.pyplot as plt
|
83
|
+
>>> x_new = np.arange(0, 2.1, 0.1)
|
84
|
+
>>> plt.scatter(x, y, label='data')
|
85
|
+
>>> plt.plot(x_new, Polynomial(poly.coef[::-1])(x_new), label='Polynomial')
|
86
|
+
>>> plt.plot(x_new, 3*x_new**2 - 2*x_new + 0*x_new,
|
87
|
+
... label=r"$3 x^2 - 2 x$", linestyle='-.')
|
88
|
+
>>> plt.legend()
|
89
|
+
>>> plt.show()
|
90
|
+
|
91
|
+
"""
|
92
|
+
|
93
|
+
M = len(x)
|
94
|
+
p = poly1d(0.0)
|
95
|
+
for j in range(M):
|
96
|
+
pt = poly1d(w[j])
|
97
|
+
for k in range(M):
|
98
|
+
if k == j:
|
99
|
+
continue
|
100
|
+
fac = x[j]-x[k]
|
101
|
+
pt *= poly1d([1.0, -x[k]])/fac
|
102
|
+
p += pt
|
103
|
+
return p
|
104
|
+
|
105
|
+
|
106
|
+
# !! Need to find argument for keeping initialize. If it isn't
|
107
|
+
# !! found, get rid of it!
|
108
|
+
|
109
|
+
|
110
|
+
err_mesg = """\
|
111
|
+
`interp2d` has been removed in SciPy 1.14.0.
|
112
|
+
|
113
|
+
For legacy code, nearly bug-for-bug compatible replacements are
|
114
|
+
`RectBivariateSpline` on regular grids, and `bisplrep`/`bisplev` for
|
115
|
+
scattered 2D data.
|
116
|
+
|
117
|
+
In new code, for regular grids use `RegularGridInterpolator` instead.
|
118
|
+
For scattered data, prefer `LinearNDInterpolator` or
|
119
|
+
`CloughTocher2DInterpolator`.
|
120
|
+
|
121
|
+
For more details see
|
122
|
+
https://scipy.github.io/devdocs/tutorial/interpolate/interp_transition_guide.html
|
123
|
+
"""
|
124
|
+
|
125
|
+
class interp2d:
|
126
|
+
"""
|
127
|
+
interp2d(x, y, z, kind='linear', copy=True, bounds_error=False,
|
128
|
+
fill_value=None)
|
129
|
+
|
130
|
+
Class for 2D interpolation (deprecated and removed)
|
131
|
+
|
132
|
+
.. versionremoved:: 1.14.0
|
133
|
+
|
134
|
+
`interp2d` has been removed in SciPy 1.14.0.
|
135
|
+
|
136
|
+
For legacy code, nearly bug-for-bug compatible replacements are
|
137
|
+
`RectBivariateSpline` on regular grids, and `bisplrep`/`bisplev` for
|
138
|
+
scattered 2D data.
|
139
|
+
|
140
|
+
In new code, for regular grids use `RegularGridInterpolator` instead.
|
141
|
+
For scattered data, prefer `LinearNDInterpolator` or
|
142
|
+
`CloughTocher2DInterpolator`.
|
143
|
+
|
144
|
+
For more details see :ref:`interp-transition-guide`.
|
145
|
+
"""
|
146
|
+
def __init__(self, x, y, z, kind='linear', copy=True, bounds_error=False,
|
147
|
+
fill_value=None):
|
148
|
+
raise NotImplementedError(err_mesg)
|
149
|
+
|
150
|
+
|
151
|
+
def _check_broadcast_up_to(arr_from, shape_to, name):
|
152
|
+
"""Helper to check that arr_from broadcasts up to shape_to"""
|
153
|
+
shape_from = arr_from.shape
|
154
|
+
if len(shape_to) >= len(shape_from):
|
155
|
+
for t, f in zip(shape_to[::-1], shape_from[::-1]):
|
156
|
+
if f != 1 and f != t:
|
157
|
+
break
|
158
|
+
else: # all checks pass, do the upcasting that we need later
|
159
|
+
if arr_from.size != 1 and arr_from.shape != shape_to:
|
160
|
+
arr_from = np.ones(shape_to, arr_from.dtype) * arr_from
|
161
|
+
return arr_from.ravel()
|
162
|
+
# at least one check failed
|
163
|
+
raise ValueError(f'{name} argument must be able to broadcast up '
|
164
|
+
f'to shape {shape_to} but had shape {shape_from}')
|
165
|
+
|
166
|
+
|
167
|
+
def _do_extrapolate(fill_value):
|
168
|
+
"""Helper to check if fill_value == "extrapolate" without warnings"""
|
169
|
+
return (isinstance(fill_value, str) and
|
170
|
+
fill_value == 'extrapolate')
|
171
|
+
|
172
|
+
|
173
|
+
class interp1d(_Interpolator1D):
|
174
|
+
"""
|
175
|
+
Interpolate a 1-D function (legacy).
|
176
|
+
|
177
|
+
.. legacy:: class
|
178
|
+
|
179
|
+
For a guide to the intended replacements for `interp1d` see
|
180
|
+
:ref:`tutorial-interpolate_1Dsection`.
|
181
|
+
|
182
|
+
`x` and `y` are arrays of values used to approximate some function f:
|
183
|
+
``y = f(x)``. This class returns a function whose call method uses
|
184
|
+
interpolation to find the value of new points.
|
185
|
+
|
186
|
+
Parameters
|
187
|
+
----------
|
188
|
+
x : (npoints, ) array_like
|
189
|
+
A 1-D array of real values.
|
190
|
+
y : (..., npoints, ...) array_like
|
191
|
+
A N-D array of real values. The length of `y` along the interpolation
|
192
|
+
axis must be equal to the length of `x`. Use the ``axis`` parameter
|
193
|
+
to select correct axis. Unlike other interpolators, the default
|
194
|
+
interpolation axis is the last axis of `y`.
|
195
|
+
kind : str or int, optional
|
196
|
+
Specifies the kind of interpolation as a string or as an integer
|
197
|
+
specifying the order of the spline interpolator to use.
|
198
|
+
The string has to be one of 'linear', 'nearest', 'nearest-up', 'zero',
|
199
|
+
'slinear', 'quadratic', 'cubic', 'previous', or 'next'. 'zero',
|
200
|
+
'slinear', 'quadratic' and 'cubic' refer to a spline interpolation of
|
201
|
+
zeroth, first, second or third order; 'previous' and 'next' simply
|
202
|
+
return the previous or next value of the point; 'nearest-up' and
|
203
|
+
'nearest' differ when interpolating half-integers (e.g. 0.5, 1.5)
|
204
|
+
in that 'nearest-up' rounds up and 'nearest' rounds down. Default
|
205
|
+
is 'linear'.
|
206
|
+
axis : int, optional
|
207
|
+
Axis in the ``y`` array corresponding to the x-coordinate values. Unlike
|
208
|
+
other interpolators, defaults to ``axis=-1``.
|
209
|
+
copy : bool, optional
|
210
|
+
If ``True``, the class makes internal copies of x and y. If ``False``,
|
211
|
+
references to ``x`` and ``y`` are used if possible. The default is to copy.
|
212
|
+
bounds_error : bool, optional
|
213
|
+
If True, a ValueError is raised any time interpolation is attempted on
|
214
|
+
a value outside of the range of x (where extrapolation is
|
215
|
+
necessary). If False, out of bounds values are assigned `fill_value`.
|
216
|
+
By default, an error is raised unless ``fill_value="extrapolate"``.
|
217
|
+
fill_value : array-like or (array-like, array_like) or "extrapolate", optional
|
218
|
+
- if a ndarray (or float), this value will be used to fill in for
|
219
|
+
requested points outside of the data range. If not provided, then
|
220
|
+
the default is NaN. The array-like must broadcast properly to the
|
221
|
+
dimensions of the non-interpolation axes.
|
222
|
+
- If a two-element tuple, then the first element is used as a
|
223
|
+
fill value for ``x_new < x[0]`` and the second element is used for
|
224
|
+
``x_new > x[-1]``. Anything that is not a 2-element tuple (e.g.,
|
225
|
+
list or ndarray, regardless of shape) is taken to be a single
|
226
|
+
array-like argument meant to be used for both bounds as
|
227
|
+
``below, above = fill_value, fill_value``. Using a two-element tuple
|
228
|
+
or ndarray requires ``bounds_error=False``.
|
229
|
+
|
230
|
+
.. versionadded:: 0.17.0
|
231
|
+
- If "extrapolate", then points outside the data range will be
|
232
|
+
extrapolated.
|
233
|
+
|
234
|
+
.. versionadded:: 0.17.0
|
235
|
+
assume_sorted : bool, optional
|
236
|
+
If False, values of `x` can be in any order and they are sorted first.
|
237
|
+
If True, `x` has to be an array of monotonically increasing values.
|
238
|
+
|
239
|
+
Attributes
|
240
|
+
----------
|
241
|
+
fill_value
|
242
|
+
|
243
|
+
Methods
|
244
|
+
-------
|
245
|
+
__call__
|
246
|
+
|
247
|
+
See Also
|
248
|
+
--------
|
249
|
+
splrep, splev
|
250
|
+
Spline interpolation/smoothing based on FITPACK.
|
251
|
+
UnivariateSpline : An object-oriented wrapper of the FITPACK routines.
|
252
|
+
interp2d : 2-D interpolation
|
253
|
+
|
254
|
+
Notes
|
255
|
+
-----
|
256
|
+
Calling `interp1d` with NaNs present in input values results in
|
257
|
+
undefined behaviour.
|
258
|
+
|
259
|
+
Input values `x` and `y` must be convertible to `float` values like
|
260
|
+
`int` or `float`.
|
261
|
+
|
262
|
+
If the values in `x` are not unique, the resulting behavior is
|
263
|
+
undefined and specific to the choice of `kind`, i.e., changing
|
264
|
+
`kind` will change the behavior for duplicates.
|
265
|
+
|
266
|
+
|
267
|
+
Examples
|
268
|
+
--------
|
269
|
+
>>> import numpy as np
|
270
|
+
>>> import matplotlib.pyplot as plt
|
271
|
+
>>> from scipy import interpolate
|
272
|
+
>>> x = np.arange(0, 10)
|
273
|
+
>>> y = np.exp(-x/3.0)
|
274
|
+
>>> f = interpolate.interp1d(x, y)
|
275
|
+
|
276
|
+
>>> xnew = np.arange(0, 9, 0.1)
|
277
|
+
>>> ynew = f(xnew) # use interpolation function returned by `interp1d`
|
278
|
+
>>> plt.plot(x, y, 'o', xnew, ynew, '-')
|
279
|
+
>>> plt.show()
|
280
|
+
"""
|
281
|
+
|
282
|
+
def __init__(self, x, y, kind='linear', axis=-1,
|
283
|
+
copy=True, bounds_error=None, fill_value=np.nan,
|
284
|
+
assume_sorted=False):
|
285
|
+
""" Initialize a 1-D linear interpolation class."""
|
286
|
+
_Interpolator1D.__init__(self, x, y, axis=axis)
|
287
|
+
|
288
|
+
self.bounds_error = bounds_error # used by fill_value setter
|
289
|
+
|
290
|
+
# `copy` keyword semantics changed in NumPy 2.0, once that is
|
291
|
+
# the minimum version this can use `copy=None`.
|
292
|
+
self.copy = copy
|
293
|
+
if not copy:
|
294
|
+
self.copy = copy_if_needed
|
295
|
+
|
296
|
+
if kind in ['zero', 'slinear', 'quadratic', 'cubic']:
|
297
|
+
order = {'zero': 0, 'slinear': 1,
|
298
|
+
'quadratic': 2, 'cubic': 3}[kind]
|
299
|
+
kind = 'spline'
|
300
|
+
elif isinstance(kind, int):
|
301
|
+
order = kind
|
302
|
+
kind = 'spline'
|
303
|
+
elif kind not in ('linear', 'nearest', 'nearest-up', 'previous',
|
304
|
+
'next'):
|
305
|
+
raise NotImplementedError(f"{kind} is unsupported: Use fitpack "
|
306
|
+
"routines for other types.")
|
307
|
+
x = array(x, copy=self.copy)
|
308
|
+
y = array(y, copy=self.copy)
|
309
|
+
|
310
|
+
if not assume_sorted:
|
311
|
+
ind = np.argsort(x, kind="mergesort")
|
312
|
+
x = x[ind]
|
313
|
+
y = np.take(y, ind, axis=axis)
|
314
|
+
|
315
|
+
if x.ndim != 1:
|
316
|
+
raise ValueError("the x array must have exactly one dimension.")
|
317
|
+
if y.ndim == 0:
|
318
|
+
raise ValueError("the y array must have at least one dimension.")
|
319
|
+
|
320
|
+
# Force-cast y to a floating-point type, if it's not yet one
|
321
|
+
if not issubclass(y.dtype.type, np.inexact):
|
322
|
+
y = y.astype(np.float64)
|
323
|
+
|
324
|
+
# Backward compatibility
|
325
|
+
self.axis = axis % y.ndim
|
326
|
+
|
327
|
+
# Interpolation goes internally along the first axis
|
328
|
+
self.y = y
|
329
|
+
self._y = self._reshape_yi(self.y)
|
330
|
+
self.x = x
|
331
|
+
del y, x # clean up namespace to prevent misuse; use attributes
|
332
|
+
self._kind = kind
|
333
|
+
|
334
|
+
# Adjust to interpolation kind; store reference to *unbound*
|
335
|
+
# interpolation methods, in order to avoid circular references to self
|
336
|
+
# stored in the bound instance methods, and therefore delayed garbage
|
337
|
+
# collection. See: https://docs.python.org/reference/datamodel.html
|
338
|
+
if kind in ('linear', 'nearest', 'nearest-up', 'previous', 'next'):
|
339
|
+
# Make a "view" of the y array that is rotated to the interpolation
|
340
|
+
# axis.
|
341
|
+
minval = 1
|
342
|
+
if kind == 'nearest':
|
343
|
+
# Do division before addition to prevent possible integer
|
344
|
+
# overflow
|
345
|
+
self._side = 'left'
|
346
|
+
self.x_bds = self.x / 2.0
|
347
|
+
self.x_bds = self.x_bds[1:] + self.x_bds[:-1]
|
348
|
+
|
349
|
+
self._call = self.__class__._call_nearest
|
350
|
+
elif kind == 'nearest-up':
|
351
|
+
# Do division before addition to prevent possible integer
|
352
|
+
# overflow
|
353
|
+
self._side = 'right'
|
354
|
+
self.x_bds = self.x / 2.0
|
355
|
+
self.x_bds = self.x_bds[1:] + self.x_bds[:-1]
|
356
|
+
|
357
|
+
self._call = self.__class__._call_nearest
|
358
|
+
elif kind == 'previous':
|
359
|
+
# Side for np.searchsorted and index for clipping
|
360
|
+
self._side = 'left'
|
361
|
+
self._ind = 0
|
362
|
+
# Move x by one floating point value to the left
|
363
|
+
self._x_shift = np.nextafter(self.x, -np.inf)
|
364
|
+
self._call = self.__class__._call_previousnext
|
365
|
+
if _do_extrapolate(fill_value):
|
366
|
+
self._check_and_update_bounds_error_for_extrapolation()
|
367
|
+
# assume y is sorted by x ascending order here.
|
368
|
+
fill_value = (np.nan, np.take(self.y, -1, axis))
|
369
|
+
elif kind == 'next':
|
370
|
+
self._side = 'right'
|
371
|
+
self._ind = 1
|
372
|
+
# Move x by one floating point value to the right
|
373
|
+
self._x_shift = np.nextafter(self.x, np.inf)
|
374
|
+
self._call = self.__class__._call_previousnext
|
375
|
+
if _do_extrapolate(fill_value):
|
376
|
+
self._check_and_update_bounds_error_for_extrapolation()
|
377
|
+
# assume y is sorted by x ascending order here.
|
378
|
+
fill_value = (np.take(self.y, 0, axis), np.nan)
|
379
|
+
else:
|
380
|
+
# Check if we can delegate to numpy.interp (2x-10x faster).
|
381
|
+
np_dtypes = (np.dtype(np.float64), np.dtype(int))
|
382
|
+
cond = self.x.dtype in np_dtypes and self.y.dtype in np_dtypes
|
383
|
+
cond = cond and self.y.ndim == 1
|
384
|
+
cond = cond and not _do_extrapolate(fill_value)
|
385
|
+
|
386
|
+
if cond:
|
387
|
+
self._call = self.__class__._call_linear_np
|
388
|
+
else:
|
389
|
+
self._call = self.__class__._call_linear
|
390
|
+
else:
|
391
|
+
minval = order + 1
|
392
|
+
|
393
|
+
rewrite_nan = False
|
394
|
+
xx, yy = self.x, self._y
|
395
|
+
if order > 1:
|
396
|
+
# Quadratic or cubic spline. If input contains even a single
|
397
|
+
# nan, then the output is all nans. We cannot just feed data
|
398
|
+
# with nans to make_interp_spline because it calls LAPACK.
|
399
|
+
# So, we make up a bogus x and y with no nans and use it
|
400
|
+
# to get the correct shape of the output, which we then fill
|
401
|
+
# with nans.
|
402
|
+
# For slinear or zero order spline, we just pass nans through.
|
403
|
+
mask = np.isnan(self.x)
|
404
|
+
if mask.any():
|
405
|
+
sx = self.x[~mask]
|
406
|
+
if sx.size == 0:
|
407
|
+
raise ValueError("`x` array is all-nan")
|
408
|
+
xx = np.linspace(np.nanmin(self.x),
|
409
|
+
np.nanmax(self.x),
|
410
|
+
len(self.x))
|
411
|
+
rewrite_nan = True
|
412
|
+
if np.isnan(self._y).any():
|
413
|
+
yy = np.ones_like(self._y)
|
414
|
+
rewrite_nan = True
|
415
|
+
|
416
|
+
self._spline = make_interp_spline(xx, yy, k=order,
|
417
|
+
check_finite=False)
|
418
|
+
if rewrite_nan:
|
419
|
+
self._call = self.__class__._call_nan_spline
|
420
|
+
else:
|
421
|
+
self._call = self.__class__._call_spline
|
422
|
+
|
423
|
+
if len(self.x) < minval:
|
424
|
+
raise ValueError(f"x and y arrays must have at least {minval} entries")
|
425
|
+
|
426
|
+
self.fill_value = fill_value # calls the setter, can modify bounds_err
|
427
|
+
|
428
|
+
@property
|
429
|
+
def fill_value(self):
|
430
|
+
"""The fill value."""
|
431
|
+
# backwards compat: mimic a public attribute
|
432
|
+
return self._fill_value_orig
|
433
|
+
|
434
|
+
@fill_value.setter
|
435
|
+
def fill_value(self, fill_value):
|
436
|
+
# extrapolation only works for nearest neighbor and linear methods
|
437
|
+
if _do_extrapolate(fill_value):
|
438
|
+
self._check_and_update_bounds_error_for_extrapolation()
|
439
|
+
self._extrapolate = True
|
440
|
+
else:
|
441
|
+
broadcast_shape = (self.y.shape[:self.axis] +
|
442
|
+
self.y.shape[self.axis + 1:])
|
443
|
+
if len(broadcast_shape) == 0:
|
444
|
+
broadcast_shape = (1,)
|
445
|
+
# it's either a pair (_below_range, _above_range) or a single value
|
446
|
+
# for both above and below range
|
447
|
+
if isinstance(fill_value, tuple) and len(fill_value) == 2:
|
448
|
+
below_above = [np.asarray(fill_value[0]),
|
449
|
+
np.asarray(fill_value[1])]
|
450
|
+
names = ('fill_value (below)', 'fill_value (above)')
|
451
|
+
for ii in range(2):
|
452
|
+
below_above[ii] = _check_broadcast_up_to(
|
453
|
+
below_above[ii], broadcast_shape, names[ii])
|
454
|
+
else:
|
455
|
+
fill_value = np.asarray(fill_value)
|
456
|
+
below_above = [_check_broadcast_up_to(
|
457
|
+
fill_value, broadcast_shape, 'fill_value')] * 2
|
458
|
+
self._fill_value_below, self._fill_value_above = below_above
|
459
|
+
self._extrapolate = False
|
460
|
+
if self.bounds_error is None:
|
461
|
+
self.bounds_error = True
|
462
|
+
# backwards compat: fill_value was a public attr; make it writeable
|
463
|
+
self._fill_value_orig = fill_value
|
464
|
+
|
465
|
+
def _check_and_update_bounds_error_for_extrapolation(self):
|
466
|
+
if self.bounds_error:
|
467
|
+
raise ValueError("Cannot extrapolate and raise "
|
468
|
+
"at the same time.")
|
469
|
+
self.bounds_error = False
|
470
|
+
|
471
|
+
def _call_linear_np(self, x_new):
|
472
|
+
# Note that out-of-bounds values are taken care of in self._evaluate
|
473
|
+
return np.interp(x_new, self.x, self.y)
|
474
|
+
|
475
|
+
def _call_linear(self, x_new):
|
476
|
+
# 2. Find where in the original data, the values to interpolate
|
477
|
+
# would be inserted.
|
478
|
+
# Note: If x_new[n] == x[m], then m is returned by searchsorted.
|
479
|
+
x_new_indices = searchsorted(self.x, x_new)
|
480
|
+
|
481
|
+
# 3. Clip x_new_indices so that they are within the range of
|
482
|
+
# self.x indices and at least 1. Removes mis-interpolation
|
483
|
+
# of x_new[n] = x[0]
|
484
|
+
x_new_indices = x_new_indices.clip(1, len(self.x)-1).astype(int)
|
485
|
+
|
486
|
+
# 4. Calculate the slope of regions that each x_new value falls in.
|
487
|
+
lo = x_new_indices - 1
|
488
|
+
hi = x_new_indices
|
489
|
+
|
490
|
+
x_lo = self.x[lo]
|
491
|
+
x_hi = self.x[hi]
|
492
|
+
y_lo = self._y[lo]
|
493
|
+
y_hi = self._y[hi]
|
494
|
+
|
495
|
+
# Note that the following two expressions rely on the specifics of the
|
496
|
+
# broadcasting semantics.
|
497
|
+
slope = (y_hi - y_lo) / (x_hi - x_lo)[:, None]
|
498
|
+
|
499
|
+
# 5. Calculate the actual value for each entry in x_new.
|
500
|
+
y_new = slope*(x_new - x_lo)[:, None] + y_lo
|
501
|
+
|
502
|
+
return y_new
|
503
|
+
|
504
|
+
def _call_nearest(self, x_new):
|
505
|
+
""" Find nearest neighbor interpolated y_new = f(x_new)."""
|
506
|
+
|
507
|
+
# 2. Find where in the averaged data the values to interpolate
|
508
|
+
# would be inserted.
|
509
|
+
# Note: use side='left' (right) to searchsorted() to define the
|
510
|
+
# halfway point to be nearest to the left (right) neighbor
|
511
|
+
x_new_indices = searchsorted(self.x_bds, x_new, side=self._side)
|
512
|
+
|
513
|
+
# 3. Clip x_new_indices so that they are within the range of x indices.
|
514
|
+
x_new_indices = x_new_indices.clip(0, len(self.x)-1).astype(intp)
|
515
|
+
|
516
|
+
# 4. Calculate the actual value for each entry in x_new.
|
517
|
+
y_new = self._y[x_new_indices]
|
518
|
+
|
519
|
+
return y_new
|
520
|
+
|
521
|
+
def _call_previousnext(self, x_new):
|
522
|
+
"""Use previous/next neighbor of x_new, y_new = f(x_new)."""
|
523
|
+
|
524
|
+
# 1. Get index of left/right value
|
525
|
+
x_new_indices = searchsorted(self._x_shift, x_new, side=self._side)
|
526
|
+
|
527
|
+
# 2. Clip x_new_indices so that they are within the range of x indices.
|
528
|
+
x_new_indices = x_new_indices.clip(1-self._ind,
|
529
|
+
len(self.x)-self._ind).astype(intp)
|
530
|
+
|
531
|
+
# 3. Calculate the actual value for each entry in x_new.
|
532
|
+
y_new = self._y[x_new_indices+self._ind-1]
|
533
|
+
|
534
|
+
return y_new
|
535
|
+
|
536
|
+
def _call_spline(self, x_new):
|
537
|
+
return self._spline(x_new)
|
538
|
+
|
539
|
+
def _call_nan_spline(self, x_new):
|
540
|
+
out = self._spline(x_new)
|
541
|
+
out[...] = np.nan
|
542
|
+
return out
|
543
|
+
|
544
|
+
def _evaluate(self, x_new):
|
545
|
+
# 1. Handle values in x_new that are outside of x. Throw error,
|
546
|
+
# or return a list of mask array indicating the outofbounds values.
|
547
|
+
# The behavior is set by the bounds_error variable.
|
548
|
+
x_new = asarray(x_new)
|
549
|
+
y_new = self._call(self, x_new)
|
550
|
+
if not self._extrapolate:
|
551
|
+
below_bounds, above_bounds = self._check_bounds(x_new)
|
552
|
+
if len(y_new) > 0:
|
553
|
+
# Note fill_value must be broadcast up to the proper size
|
554
|
+
# and flattened to work here
|
555
|
+
y_new[below_bounds] = self._fill_value_below
|
556
|
+
y_new[above_bounds] = self._fill_value_above
|
557
|
+
return y_new
|
558
|
+
|
559
|
+
def _check_bounds(self, x_new):
|
560
|
+
"""Check the inputs for being in the bounds of the interpolated data.
|
561
|
+
|
562
|
+
Parameters
|
563
|
+
----------
|
564
|
+
x_new : array
|
565
|
+
|
566
|
+
Returns
|
567
|
+
-------
|
568
|
+
out_of_bounds : bool array
|
569
|
+
The mask on x_new of values that are out of the bounds.
|
570
|
+
"""
|
571
|
+
|
572
|
+
# If self.bounds_error is True, we raise an error if any x_new values
|
573
|
+
# fall outside the range of x. Otherwise, we return an array indicating
|
574
|
+
# which values are outside the boundary region.
|
575
|
+
below_bounds = x_new < self.x[0]
|
576
|
+
above_bounds = x_new > self.x[-1]
|
577
|
+
|
578
|
+
if self.bounds_error and below_bounds.any():
|
579
|
+
below_bounds_value = x_new[np.argmax(below_bounds)]
|
580
|
+
raise ValueError(f"A value ({below_bounds_value}) in x_new is below "
|
581
|
+
f"the interpolation range's minimum value ({self.x[0]}).")
|
582
|
+
if self.bounds_error and above_bounds.any():
|
583
|
+
above_bounds_value = x_new[np.argmax(above_bounds)]
|
584
|
+
raise ValueError(f"A value ({above_bounds_value}) in x_new is above "
|
585
|
+
f"the interpolation range's maximum value ({self.x[-1]}).")
|
586
|
+
|
587
|
+
# !! Should we emit a warning if some values are out of bounds?
|
588
|
+
# !! matlab does not.
|
589
|
+
return below_bounds, above_bounds
|
590
|
+
|
591
|
+
|
592
|
+
class _PPolyBase:
|
593
|
+
"""Base class for piecewise polynomials."""
|
594
|
+
__slots__ = ('c', 'x', 'extrapolate', 'axis')
|
595
|
+
|
596
|
+
def __init__(self, c, x, extrapolate=None, axis=0):
|
597
|
+
self.c = np.asarray(c)
|
598
|
+
self.x = np.ascontiguousarray(x, dtype=np.float64)
|
599
|
+
|
600
|
+
if extrapolate is None:
|
601
|
+
extrapolate = True
|
602
|
+
elif extrapolate != 'periodic':
|
603
|
+
extrapolate = bool(extrapolate)
|
604
|
+
self.extrapolate = extrapolate
|
605
|
+
|
606
|
+
if self.c.ndim < 2:
|
607
|
+
raise ValueError("Coefficients array must be at least "
|
608
|
+
"2-dimensional.")
|
609
|
+
|
610
|
+
if not (0 <= axis < self.c.ndim - 1):
|
611
|
+
raise ValueError(f"axis={axis} must be between 0 and {self.c.ndim-1}")
|
612
|
+
|
613
|
+
self.axis = axis
|
614
|
+
if axis != 0:
|
615
|
+
# move the interpolation axis to be the first one in self.c
|
616
|
+
# More specifically, the target shape for self.c is (k, m, ...),
|
617
|
+
# and axis !=0 means that we have c.shape (..., k, m, ...)
|
618
|
+
# ^
|
619
|
+
# axis
|
620
|
+
# So we roll two of them.
|
621
|
+
self.c = np.moveaxis(self.c, axis+1, 0)
|
622
|
+
self.c = np.moveaxis(self.c, axis+1, 0)
|
623
|
+
|
624
|
+
if self.x.ndim != 1:
|
625
|
+
raise ValueError("x must be 1-dimensional")
|
626
|
+
if self.x.size < 2:
|
627
|
+
raise ValueError("at least 2 breakpoints are needed")
|
628
|
+
if self.c.ndim < 2:
|
629
|
+
raise ValueError("c must have at least 2 dimensions")
|
630
|
+
if self.c.shape[0] == 0:
|
631
|
+
raise ValueError("polynomial must be at least of order 0")
|
632
|
+
if self.c.shape[1] != self.x.size-1:
|
633
|
+
raise ValueError("number of coefficients != len(x)-1")
|
634
|
+
dx = np.diff(self.x)
|
635
|
+
if not (np.all(dx >= 0) or np.all(dx <= 0)):
|
636
|
+
raise ValueError("`x` must be strictly increasing or decreasing.")
|
637
|
+
|
638
|
+
dtype = self._get_dtype(self.c.dtype)
|
639
|
+
self.c = np.ascontiguousarray(self.c, dtype=dtype)
|
640
|
+
|
641
|
+
def _get_dtype(self, dtype):
|
642
|
+
if np.issubdtype(dtype, np.complexfloating) \
|
643
|
+
or np.issubdtype(self.c.dtype, np.complexfloating):
|
644
|
+
return np.complex128
|
645
|
+
else:
|
646
|
+
return np.float64
|
647
|
+
|
648
|
+
@classmethod
|
649
|
+
def construct_fast(cls, c, x, extrapolate=None, axis=0):
|
650
|
+
"""
|
651
|
+
Construct the piecewise polynomial without making checks.
|
652
|
+
|
653
|
+
Takes the same parameters as the constructor. Input arguments
|
654
|
+
``c`` and ``x`` must be arrays of the correct shape and type. The
|
655
|
+
``c`` array can only be of dtypes float and complex, and ``x``
|
656
|
+
array must have dtype float.
|
657
|
+
"""
|
658
|
+
self = object.__new__(cls)
|
659
|
+
self.c = c
|
660
|
+
self.x = x
|
661
|
+
self.axis = axis
|
662
|
+
if extrapolate is None:
|
663
|
+
extrapolate = True
|
664
|
+
self.extrapolate = extrapolate
|
665
|
+
return self
|
666
|
+
|
667
|
+
def _ensure_c_contiguous(self):
|
668
|
+
"""
|
669
|
+
c and x may be modified by the user. The Cython code expects
|
670
|
+
that they are C contiguous.
|
671
|
+
"""
|
672
|
+
if not self.x.flags.c_contiguous:
|
673
|
+
self.x = self.x.copy()
|
674
|
+
if not self.c.flags.c_contiguous:
|
675
|
+
self.c = self.c.copy()
|
676
|
+
|
677
|
+
def extend(self, c, x):
|
678
|
+
"""
|
679
|
+
Add additional breakpoints and coefficients to the polynomial.
|
680
|
+
|
681
|
+
Parameters
|
682
|
+
----------
|
683
|
+
c : ndarray, size (k, m, ...)
|
684
|
+
Additional coefficients for polynomials in intervals. Note that
|
685
|
+
the first additional interval will be formed using one of the
|
686
|
+
``self.x`` end points.
|
687
|
+
x : ndarray, size (m,)
|
688
|
+
Additional breakpoints. Must be sorted in the same order as
|
689
|
+
``self.x`` and either to the right or to the left of the current
|
690
|
+
breakpoints.
|
691
|
+
|
692
|
+
Notes
|
693
|
+
-----
|
694
|
+
This method is not thread safe and must not be executed concurrently
|
695
|
+
with other methods available in this class. Doing so may cause
|
696
|
+
unexpected errors or numerical output mismatches.
|
697
|
+
"""
|
698
|
+
|
699
|
+
c = np.asarray(c)
|
700
|
+
x = np.asarray(x)
|
701
|
+
|
702
|
+
if c.ndim < 2:
|
703
|
+
raise ValueError("invalid dimensions for c")
|
704
|
+
if x.ndim != 1:
|
705
|
+
raise ValueError("invalid dimensions for x")
|
706
|
+
if x.shape[0] != c.shape[1]:
|
707
|
+
raise ValueError(f"Shapes of x {x.shape} and c {c.shape} are incompatible")
|
708
|
+
if c.shape[2:] != self.c.shape[2:] or c.ndim != self.c.ndim:
|
709
|
+
raise ValueError(
|
710
|
+
f"Shapes of c {c.shape} and self.c {self.c.shape} are incompatible"
|
711
|
+
)
|
712
|
+
|
713
|
+
if c.size == 0:
|
714
|
+
return
|
715
|
+
|
716
|
+
dx = np.diff(x)
|
717
|
+
if not (np.all(dx >= 0) or np.all(dx <= 0)):
|
718
|
+
raise ValueError("`x` is not sorted.")
|
719
|
+
|
720
|
+
if self.x[-1] >= self.x[0]:
|
721
|
+
if not x[-1] >= x[0]:
|
722
|
+
raise ValueError("`x` is in the different order "
|
723
|
+
"than `self.x`.")
|
724
|
+
|
725
|
+
if x[0] >= self.x[-1]:
|
726
|
+
action = 'append'
|
727
|
+
elif x[-1] <= self.x[0]:
|
728
|
+
action = 'prepend'
|
729
|
+
else:
|
730
|
+
raise ValueError("`x` is neither on the left or on the right "
|
731
|
+
"from `self.x`.")
|
732
|
+
else:
|
733
|
+
if not x[-1] <= x[0]:
|
734
|
+
raise ValueError("`x` is in the different order "
|
735
|
+
"than `self.x`.")
|
736
|
+
|
737
|
+
if x[0] <= self.x[-1]:
|
738
|
+
action = 'append'
|
739
|
+
elif x[-1] >= self.x[0]:
|
740
|
+
action = 'prepend'
|
741
|
+
else:
|
742
|
+
raise ValueError("`x` is neither on the left or on the right "
|
743
|
+
"from `self.x`.")
|
744
|
+
|
745
|
+
dtype = self._get_dtype(c.dtype)
|
746
|
+
|
747
|
+
k2 = max(c.shape[0], self.c.shape[0])
|
748
|
+
c2 = np.zeros((k2, self.c.shape[1] + c.shape[1]) + self.c.shape[2:],
|
749
|
+
dtype=dtype)
|
750
|
+
|
751
|
+
if action == 'append':
|
752
|
+
c2[k2-self.c.shape[0]:, :self.c.shape[1]] = self.c
|
753
|
+
c2[k2-c.shape[0]:, self.c.shape[1]:] = c
|
754
|
+
self.x = np.r_[self.x, x]
|
755
|
+
elif action == 'prepend':
|
756
|
+
c2[k2-self.c.shape[0]:, :c.shape[1]] = c
|
757
|
+
c2[k2-c.shape[0]:, c.shape[1]:] = self.c
|
758
|
+
self.x = np.r_[x, self.x]
|
759
|
+
|
760
|
+
self.c = c2
|
761
|
+
|
762
|
+
def __call__(self, x, nu=0, extrapolate=None):
|
763
|
+
"""
|
764
|
+
Evaluate the piecewise polynomial or its derivative.
|
765
|
+
|
766
|
+
Parameters
|
767
|
+
----------
|
768
|
+
x : array_like
|
769
|
+
Points to evaluate the interpolant at.
|
770
|
+
nu : int, optional
|
771
|
+
Order of derivative to evaluate. Must be non-negative.
|
772
|
+
extrapolate : {bool, 'periodic', None}, optional
|
773
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
774
|
+
based on first and last intervals, or to return NaNs.
|
775
|
+
If 'periodic', periodic extrapolation is used.
|
776
|
+
If None (default), use `self.extrapolate`.
|
777
|
+
|
778
|
+
Returns
|
779
|
+
-------
|
780
|
+
y : array_like
|
781
|
+
Interpolated values. Shape is determined by replacing
|
782
|
+
the interpolation axis in the original array with the shape of x.
|
783
|
+
|
784
|
+
Notes
|
785
|
+
-----
|
786
|
+
Derivatives are evaluated piecewise for each polynomial
|
787
|
+
segment, even if the polynomial is not differentiable at the
|
788
|
+
breakpoints. The polynomial intervals are considered half-open,
|
789
|
+
``[a, b)``, except for the last interval which is closed
|
790
|
+
``[a, b]``.
|
791
|
+
"""
|
792
|
+
if extrapolate is None:
|
793
|
+
extrapolate = self.extrapolate
|
794
|
+
x = np.asarray(x)
|
795
|
+
x_shape, x_ndim = x.shape, x.ndim
|
796
|
+
x = np.ascontiguousarray(x.ravel(), dtype=np.float64)
|
797
|
+
|
798
|
+
# With periodic extrapolation we map x to the segment
|
799
|
+
# [self.x[0], self.x[-1]].
|
800
|
+
if extrapolate == 'periodic':
|
801
|
+
x = self.x[0] + (x - self.x[0]) % (self.x[-1] - self.x[0])
|
802
|
+
extrapolate = False
|
803
|
+
|
804
|
+
out = np.empty((len(x), prod(self.c.shape[2:])), dtype=self.c.dtype)
|
805
|
+
self._ensure_c_contiguous()
|
806
|
+
self._evaluate(x, nu, extrapolate, out)
|
807
|
+
out = out.reshape(x_shape + self.c.shape[2:])
|
808
|
+
if self.axis != 0:
|
809
|
+
# transpose to move the calculated values to the interpolation axis
|
810
|
+
l = list(range(out.ndim))
|
811
|
+
l = l[x_ndim:x_ndim+self.axis] + l[:x_ndim] + l[x_ndim+self.axis:]
|
812
|
+
out = out.transpose(l)
|
813
|
+
return out
|
814
|
+
|
815
|
+
|
816
|
+
class PPoly(_PPolyBase):
|
817
|
+
"""Piecewise polynomial in the power basis.
|
818
|
+
|
819
|
+
The polynomial between ``x[i]`` and ``x[i + 1]`` is written in the
|
820
|
+
local power basis::
|
821
|
+
|
822
|
+
S = sum(c[m, i] * (xp - x[i])**(k-m) for m in range(k+1))
|
823
|
+
|
824
|
+
where ``k`` is the degree of the polynomial.
|
825
|
+
|
826
|
+
Parameters
|
827
|
+
----------
|
828
|
+
c : ndarray, shape (k, m, ...)
|
829
|
+
Polynomial coefficients, order `k` and `m` intervals.
|
830
|
+
x : ndarray, shape (m+1,)
|
831
|
+
Polynomial breakpoints. Must be sorted in either increasing or
|
832
|
+
decreasing order.
|
833
|
+
extrapolate : bool or 'periodic', optional
|
834
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
835
|
+
based on first and last intervals, or to return NaNs. If 'periodic',
|
836
|
+
periodic extrapolation is used. Default is True.
|
837
|
+
axis : int, optional
|
838
|
+
Interpolation axis. Default is zero.
|
839
|
+
|
840
|
+
Attributes
|
841
|
+
----------
|
842
|
+
x : ndarray
|
843
|
+
Breakpoints.
|
844
|
+
c : ndarray
|
845
|
+
Coefficients of the polynomials. They are reshaped
|
846
|
+
to a 3-D array with the last dimension representing
|
847
|
+
the trailing dimensions of the original coefficient array.
|
848
|
+
axis : int
|
849
|
+
Interpolation axis.
|
850
|
+
|
851
|
+
Methods
|
852
|
+
-------
|
853
|
+
__call__
|
854
|
+
derivative
|
855
|
+
antiderivative
|
856
|
+
integrate
|
857
|
+
solve
|
858
|
+
roots
|
859
|
+
extend
|
860
|
+
from_spline
|
861
|
+
from_bernstein_basis
|
862
|
+
construct_fast
|
863
|
+
|
864
|
+
See also
|
865
|
+
--------
|
866
|
+
BPoly : piecewise polynomials in the Bernstein basis
|
867
|
+
|
868
|
+
Notes
|
869
|
+
-----
|
870
|
+
High-order polynomials in the power basis can be numerically
|
871
|
+
unstable. Precision problems can start to appear for orders
|
872
|
+
larger than 20-30.
|
873
|
+
"""
|
874
|
+
|
875
|
+
def _evaluate(self, x, nu, extrapolate, out):
|
876
|
+
_ppoly.evaluate(self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
877
|
+
self.x, x, nu, bool(extrapolate), out)
|
878
|
+
|
879
|
+
def derivative(self, nu=1):
|
880
|
+
"""
|
881
|
+
Construct a new piecewise polynomial representing the derivative.
|
882
|
+
|
883
|
+
Parameters
|
884
|
+
----------
|
885
|
+
nu : int, optional
|
886
|
+
Order of derivative to evaluate. Default is 1, i.e., compute the
|
887
|
+
first derivative. If negative, the antiderivative is returned.
|
888
|
+
|
889
|
+
Returns
|
890
|
+
-------
|
891
|
+
pp : PPoly
|
892
|
+
Piecewise polynomial of order k2 = k - n representing the derivative
|
893
|
+
of this polynomial.
|
894
|
+
|
895
|
+
Notes
|
896
|
+
-----
|
897
|
+
Derivatives are evaluated piecewise for each polynomial
|
898
|
+
segment, even if the polynomial is not differentiable at the
|
899
|
+
breakpoints. The polynomial intervals are considered half-open,
|
900
|
+
``[a, b)``, except for the last interval which is closed
|
901
|
+
``[a, b]``.
|
902
|
+
"""
|
903
|
+
if nu < 0:
|
904
|
+
return self.antiderivative(-nu)
|
905
|
+
|
906
|
+
# reduce order
|
907
|
+
if nu == 0:
|
908
|
+
c2 = self.c.copy()
|
909
|
+
else:
|
910
|
+
c2 = self.c[:-nu, :].copy()
|
911
|
+
|
912
|
+
if c2.shape[0] == 0:
|
913
|
+
# derivative of order 0 is zero
|
914
|
+
c2 = np.zeros((1,) + c2.shape[1:], dtype=c2.dtype)
|
915
|
+
|
916
|
+
# multiply by the correct rising factorials
|
917
|
+
factor = spec.poch(np.arange(c2.shape[0], 0, -1), nu)
|
918
|
+
c2 *= factor[(slice(None),) + (None,)*(c2.ndim-1)]
|
919
|
+
|
920
|
+
# construct a compatible polynomial
|
921
|
+
return self.construct_fast(c2, self.x, self.extrapolate, self.axis)
|
922
|
+
|
923
|
+
def antiderivative(self, nu=1):
|
924
|
+
"""
|
925
|
+
Construct a new piecewise polynomial representing the antiderivative.
|
926
|
+
|
927
|
+
Antiderivative is also the indefinite integral of the function,
|
928
|
+
and derivative is its inverse operation.
|
929
|
+
|
930
|
+
Parameters
|
931
|
+
----------
|
932
|
+
nu : int, optional
|
933
|
+
Order of antiderivative to evaluate. Default is 1, i.e., compute
|
934
|
+
the first integral. If negative, the derivative is returned.
|
935
|
+
|
936
|
+
Returns
|
937
|
+
-------
|
938
|
+
pp : PPoly
|
939
|
+
Piecewise polynomial of order k2 = k + n representing
|
940
|
+
the antiderivative of this polynomial.
|
941
|
+
|
942
|
+
Notes
|
943
|
+
-----
|
944
|
+
The antiderivative returned by this function is continuous and
|
945
|
+
continuously differentiable to order n-1, up to floating point
|
946
|
+
rounding error.
|
947
|
+
|
948
|
+
If antiderivative is computed and ``self.extrapolate='periodic'``,
|
949
|
+
it will be set to False for the returned instance. This is done because
|
950
|
+
the antiderivative is no longer periodic and its correct evaluation
|
951
|
+
outside of the initially given x interval is difficult.
|
952
|
+
"""
|
953
|
+
if nu <= 0:
|
954
|
+
return self.derivative(-nu)
|
955
|
+
|
956
|
+
c = np.zeros((self.c.shape[0] + nu, self.c.shape[1]) + self.c.shape[2:],
|
957
|
+
dtype=self.c.dtype)
|
958
|
+
c[:-nu] = self.c
|
959
|
+
|
960
|
+
# divide by the correct rising factorials
|
961
|
+
factor = spec.poch(np.arange(self.c.shape[0], 0, -1), nu)
|
962
|
+
c[:-nu] /= factor[(slice(None),) + (None,)*(c.ndim-1)]
|
963
|
+
|
964
|
+
# fix continuity of added degrees of freedom
|
965
|
+
self._ensure_c_contiguous()
|
966
|
+
_ppoly.fix_continuity(c.reshape(c.shape[0], c.shape[1], -1),
|
967
|
+
self.x, nu - 1)
|
968
|
+
|
969
|
+
if self.extrapolate == 'periodic':
|
970
|
+
extrapolate = False
|
971
|
+
else:
|
972
|
+
extrapolate = self.extrapolate
|
973
|
+
|
974
|
+
# construct a compatible polynomial
|
975
|
+
return self.construct_fast(c, self.x, extrapolate, self.axis)
|
976
|
+
|
977
|
+
def integrate(self, a, b, extrapolate=None):
|
978
|
+
"""
|
979
|
+
Compute a definite integral over a piecewise polynomial.
|
980
|
+
|
981
|
+
Parameters
|
982
|
+
----------
|
983
|
+
a : float
|
984
|
+
Lower integration bound
|
985
|
+
b : float
|
986
|
+
Upper integration bound
|
987
|
+
extrapolate : {bool, 'periodic', None}, optional
|
988
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
989
|
+
based on first and last intervals, or to return NaNs.
|
990
|
+
If 'periodic', periodic extrapolation is used.
|
991
|
+
If None (default), use `self.extrapolate`.
|
992
|
+
|
993
|
+
Returns
|
994
|
+
-------
|
995
|
+
ig : array_like
|
996
|
+
Definite integral of the piecewise polynomial over [a, b]
|
997
|
+
"""
|
998
|
+
if extrapolate is None:
|
999
|
+
extrapolate = self.extrapolate
|
1000
|
+
|
1001
|
+
# Swap integration bounds if needed
|
1002
|
+
sign = 1
|
1003
|
+
if b < a:
|
1004
|
+
a, b = b, a
|
1005
|
+
sign = -1
|
1006
|
+
|
1007
|
+
range_int = np.empty((prod(self.c.shape[2:]),), dtype=self.c.dtype)
|
1008
|
+
self._ensure_c_contiguous()
|
1009
|
+
|
1010
|
+
# Compute the integral.
|
1011
|
+
if extrapolate == 'periodic':
|
1012
|
+
# Split the integral into the part over period (can be several
|
1013
|
+
# of them) and the remaining part.
|
1014
|
+
|
1015
|
+
xs, xe = self.x[0], self.x[-1]
|
1016
|
+
period = xe - xs
|
1017
|
+
interval = b - a
|
1018
|
+
n_periods, left = divmod(interval, period)
|
1019
|
+
|
1020
|
+
if n_periods > 0:
|
1021
|
+
_ppoly.integrate(
|
1022
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1023
|
+
self.x, xs, xe, False, out=range_int)
|
1024
|
+
range_int *= n_periods
|
1025
|
+
else:
|
1026
|
+
range_int.fill(0)
|
1027
|
+
|
1028
|
+
# Map a to [xs, xe], b is always a + left.
|
1029
|
+
a = xs + (a - xs) % period
|
1030
|
+
b = a + left
|
1031
|
+
|
1032
|
+
# If b <= xe then we need to integrate over [a, b], otherwise
|
1033
|
+
# over [a, xe] and from xs to what is remained.
|
1034
|
+
remainder_int = np.empty_like(range_int)
|
1035
|
+
if b <= xe:
|
1036
|
+
_ppoly.integrate(
|
1037
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1038
|
+
self.x, a, b, False, out=remainder_int)
|
1039
|
+
range_int += remainder_int
|
1040
|
+
else:
|
1041
|
+
_ppoly.integrate(
|
1042
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1043
|
+
self.x, a, xe, False, out=remainder_int)
|
1044
|
+
range_int += remainder_int
|
1045
|
+
|
1046
|
+
_ppoly.integrate(
|
1047
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1048
|
+
self.x, xs, xs + left + a - xe, False, out=remainder_int)
|
1049
|
+
range_int += remainder_int
|
1050
|
+
else:
|
1051
|
+
_ppoly.integrate(
|
1052
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1053
|
+
self.x, a, b, bool(extrapolate), out=range_int)
|
1054
|
+
|
1055
|
+
# Return
|
1056
|
+
range_int *= sign
|
1057
|
+
return range_int.reshape(self.c.shape[2:])
|
1058
|
+
|
1059
|
+
def solve(self, y=0., discontinuity=True, extrapolate=None):
|
1060
|
+
"""
|
1061
|
+
Find real solutions of the equation ``pp(x) == y``.
|
1062
|
+
|
1063
|
+
Parameters
|
1064
|
+
----------
|
1065
|
+
y : float, optional
|
1066
|
+
Right-hand side. Default is zero.
|
1067
|
+
discontinuity : bool, optional
|
1068
|
+
Whether to report sign changes across discontinuities at
|
1069
|
+
breakpoints as roots.
|
1070
|
+
extrapolate : {bool, 'periodic', None}, optional
|
1071
|
+
If bool, determines whether to return roots from the polynomial
|
1072
|
+
extrapolated based on first and last intervals, 'periodic' works
|
1073
|
+
the same as False. If None (default), use `self.extrapolate`.
|
1074
|
+
|
1075
|
+
Returns
|
1076
|
+
-------
|
1077
|
+
roots : ndarray
|
1078
|
+
Roots of the polynomial(s).
|
1079
|
+
|
1080
|
+
If the PPoly object describes multiple polynomials, the
|
1081
|
+
return value is an object array whose each element is an
|
1082
|
+
ndarray containing the roots.
|
1083
|
+
|
1084
|
+
Notes
|
1085
|
+
-----
|
1086
|
+
This routine works only on real-valued polynomials.
|
1087
|
+
|
1088
|
+
If the piecewise polynomial contains sections that are
|
1089
|
+
identically zero, the root list will contain the start point
|
1090
|
+
of the corresponding interval, followed by a ``nan`` value.
|
1091
|
+
|
1092
|
+
If the polynomial is discontinuous across a breakpoint, and
|
1093
|
+
there is a sign change across the breakpoint, this is reported
|
1094
|
+
if the `discont` parameter is True.
|
1095
|
+
|
1096
|
+
Examples
|
1097
|
+
--------
|
1098
|
+
|
1099
|
+
Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
|
1100
|
+
``[-2, 1], [1, 2]``:
|
1101
|
+
|
1102
|
+
>>> import numpy as np
|
1103
|
+
>>> from scipy.interpolate import PPoly
|
1104
|
+
>>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
|
1105
|
+
>>> pp.solve()
|
1106
|
+
array([-1., 1.])
|
1107
|
+
"""
|
1108
|
+
if extrapolate is None:
|
1109
|
+
extrapolate = self.extrapolate
|
1110
|
+
|
1111
|
+
self._ensure_c_contiguous()
|
1112
|
+
|
1113
|
+
if np.issubdtype(self.c.dtype, np.complexfloating):
|
1114
|
+
raise ValueError("Root finding is only for "
|
1115
|
+
"real-valued polynomials")
|
1116
|
+
|
1117
|
+
y = float(y)
|
1118
|
+
r = _ppoly.real_roots(self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1119
|
+
self.x, y, bool(discontinuity),
|
1120
|
+
bool(extrapolate))
|
1121
|
+
if self.c.ndim == 2:
|
1122
|
+
return r[0]
|
1123
|
+
else:
|
1124
|
+
r2 = np.empty(prod(self.c.shape[2:]), dtype=object)
|
1125
|
+
# this for-loop is equivalent to ``r2[...] = r``, but that's broken
|
1126
|
+
# in NumPy 1.6.0
|
1127
|
+
for ii, root in enumerate(r):
|
1128
|
+
r2[ii] = root
|
1129
|
+
|
1130
|
+
return r2.reshape(self.c.shape[2:])
|
1131
|
+
|
1132
|
+
def roots(self, discontinuity=True, extrapolate=None):
|
1133
|
+
"""
|
1134
|
+
Find real roots of the piecewise polynomial.
|
1135
|
+
|
1136
|
+
Parameters
|
1137
|
+
----------
|
1138
|
+
discontinuity : bool, optional
|
1139
|
+
Whether to report sign changes across discontinuities at
|
1140
|
+
breakpoints as roots.
|
1141
|
+
extrapolate : {bool, 'periodic', None}, optional
|
1142
|
+
If bool, determines whether to return roots from the polynomial
|
1143
|
+
extrapolated based on first and last intervals, 'periodic' works
|
1144
|
+
the same as False. If None (default), use `self.extrapolate`.
|
1145
|
+
|
1146
|
+
Returns
|
1147
|
+
-------
|
1148
|
+
roots : ndarray
|
1149
|
+
Roots of the polynomial(s).
|
1150
|
+
|
1151
|
+
If the PPoly object describes multiple polynomials, the
|
1152
|
+
return value is an object array whose each element is an
|
1153
|
+
ndarray containing the roots.
|
1154
|
+
|
1155
|
+
See Also
|
1156
|
+
--------
|
1157
|
+
PPoly.solve
|
1158
|
+
"""
|
1159
|
+
return self.solve(0, discontinuity, extrapolate)
|
1160
|
+
|
1161
|
+
@classmethod
|
1162
|
+
def from_spline(cls, tck, extrapolate=None):
|
1163
|
+
"""
|
1164
|
+
Construct a piecewise polynomial from a spline
|
1165
|
+
|
1166
|
+
Parameters
|
1167
|
+
----------
|
1168
|
+
tck
|
1169
|
+
A spline, as returned by `splrep` or a BSpline object.
|
1170
|
+
extrapolate : bool or 'periodic', optional
|
1171
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
1172
|
+
based on first and last intervals, or to return NaNs.
|
1173
|
+
If 'periodic', periodic extrapolation is used. Default is True.
|
1174
|
+
|
1175
|
+
Examples
|
1176
|
+
--------
|
1177
|
+
Construct an interpolating spline and convert it to a `PPoly` instance
|
1178
|
+
|
1179
|
+
>>> import numpy as np
|
1180
|
+
>>> from scipy.interpolate import splrep, PPoly
|
1181
|
+
>>> x = np.linspace(0, 1, 11)
|
1182
|
+
>>> y = np.sin(2*np.pi*x)
|
1183
|
+
>>> tck = splrep(x, y, s=0)
|
1184
|
+
>>> p = PPoly.from_spline(tck)
|
1185
|
+
>>> isinstance(p, PPoly)
|
1186
|
+
True
|
1187
|
+
|
1188
|
+
Note that this function only supports 1D splines out of the box.
|
1189
|
+
|
1190
|
+
If the ``tck`` object represents a parametric spline (e.g. constructed
|
1191
|
+
by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
|
1192
|
+
over the dimensions manually.
|
1193
|
+
|
1194
|
+
>>> from scipy.interpolate import splprep, splev
|
1195
|
+
>>> t = np.linspace(0, 1, 11)
|
1196
|
+
>>> x = np.sin(2*np.pi*t)
|
1197
|
+
>>> y = np.cos(2*np.pi*t)
|
1198
|
+
>>> (t, c, k), u = splprep([x, y], s=0)
|
1199
|
+
|
1200
|
+
Note that ``c`` is a list of two arrays of length 11.
|
1201
|
+
|
1202
|
+
>>> unew = np.arange(0, 1.01, 0.01)
|
1203
|
+
>>> out = splev(unew, (t, c, k))
|
1204
|
+
|
1205
|
+
To convert this spline to the power basis, we convert each
|
1206
|
+
component of the list of b-spline coefficients, ``c``, into the
|
1207
|
+
corresponding cubic polynomial.
|
1208
|
+
|
1209
|
+
>>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
|
1210
|
+
>>> polys[0].c.shape
|
1211
|
+
(4, 14)
|
1212
|
+
|
1213
|
+
Note that the coefficients of the polynomials `polys` are in the
|
1214
|
+
power basis and their dimensions reflect just that: here 4 is the order
|
1215
|
+
(degree+1), and 14 is the number of intervals---which is nothing but
|
1216
|
+
the length of the knot array of the original `tck` minus one.
|
1217
|
+
|
1218
|
+
Optionally, we can stack the components into a single `PPoly` along
|
1219
|
+
the third dimension:
|
1220
|
+
|
1221
|
+
>>> cc = np.dstack([p.c for p in polys]) # has shape = (4, 14, 2)
|
1222
|
+
>>> poly = PPoly(cc, polys[0].x)
|
1223
|
+
>>> np.allclose(poly(unew).T, # note the transpose to match `splev`
|
1224
|
+
... out, atol=1e-15)
|
1225
|
+
True
|
1226
|
+
|
1227
|
+
"""
|
1228
|
+
if isinstance(tck, BSpline):
|
1229
|
+
t, c, k = tck.tck
|
1230
|
+
if extrapolate is None:
|
1231
|
+
extrapolate = tck.extrapolate
|
1232
|
+
else:
|
1233
|
+
t, c, k = tck
|
1234
|
+
|
1235
|
+
cvals = np.empty((k + 1, len(t)-1), dtype=c.dtype)
|
1236
|
+
for m in range(k, -1, -1):
|
1237
|
+
y = _fitpack_py.splev(t[:-1], tck, der=m)
|
1238
|
+
cvals[k - m, :] = y/spec.gamma(m+1)
|
1239
|
+
|
1240
|
+
return cls.construct_fast(cvals, t, extrapolate)
|
1241
|
+
|
1242
|
+
@classmethod
|
1243
|
+
def from_bernstein_basis(cls, bp, extrapolate=None):
|
1244
|
+
"""
|
1245
|
+
Construct a piecewise polynomial in the power basis
|
1246
|
+
from a polynomial in Bernstein basis.
|
1247
|
+
|
1248
|
+
Parameters
|
1249
|
+
----------
|
1250
|
+
bp : BPoly
|
1251
|
+
A Bernstein basis polynomial, as created by BPoly
|
1252
|
+
extrapolate : bool or 'periodic', optional
|
1253
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
1254
|
+
based on first and last intervals, or to return NaNs.
|
1255
|
+
If 'periodic', periodic extrapolation is used. Default is True.
|
1256
|
+
"""
|
1257
|
+
if not isinstance(bp, BPoly):
|
1258
|
+
raise TypeError(f".from_bernstein_basis only accepts BPoly instances. "
|
1259
|
+
f"Got {type(bp)} instead.")
|
1260
|
+
|
1261
|
+
dx = np.diff(bp.x)
|
1262
|
+
k = bp.c.shape[0] - 1 # polynomial order
|
1263
|
+
|
1264
|
+
rest = (None,)*(bp.c.ndim-2)
|
1265
|
+
|
1266
|
+
c = np.zeros_like(bp.c)
|
1267
|
+
for a in range(k+1):
|
1268
|
+
factor = (-1)**a * comb(k, a) * bp.c[a]
|
1269
|
+
for s in range(a, k+1):
|
1270
|
+
val = comb(k-a, s-a) * (-1)**s
|
1271
|
+
c[k-s] += factor * val / dx[(slice(None),)+rest]**s
|
1272
|
+
|
1273
|
+
if extrapolate is None:
|
1274
|
+
extrapolate = bp.extrapolate
|
1275
|
+
|
1276
|
+
return cls.construct_fast(c, bp.x, extrapolate, bp.axis)
|
1277
|
+
|
1278
|
+
|
1279
|
+
class BPoly(_PPolyBase):
|
1280
|
+
"""Piecewise polynomial in the Bernstein basis.
|
1281
|
+
|
1282
|
+
The polynomial between ``x[i]`` and ``x[i + 1]`` is written in the
|
1283
|
+
Bernstein polynomial basis::
|
1284
|
+
|
1285
|
+
S = sum(c[a, i] * b(a, k; x) for a in range(k+1)),
|
1286
|
+
|
1287
|
+
where ``k`` is the degree of the polynomial, and::
|
1288
|
+
|
1289
|
+
b(a, k; x) = binom(k, a) * t**a * (1 - t)**(k - a),
|
1290
|
+
|
1291
|
+
with ``t = (x - x[i]) / (x[i+1] - x[i])`` and ``binom`` is the binomial
|
1292
|
+
coefficient.
|
1293
|
+
|
1294
|
+
Parameters
|
1295
|
+
----------
|
1296
|
+
c : ndarray, shape (k, m, ...)
|
1297
|
+
Polynomial coefficients, order `k` and `m` intervals
|
1298
|
+
x : ndarray, shape (m+1,)
|
1299
|
+
Polynomial breakpoints. Must be sorted in either increasing or
|
1300
|
+
decreasing order.
|
1301
|
+
extrapolate : bool, optional
|
1302
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
1303
|
+
based on first and last intervals, or to return NaNs. If 'periodic',
|
1304
|
+
periodic extrapolation is used. Default is True.
|
1305
|
+
axis : int, optional
|
1306
|
+
Interpolation axis. Default is zero.
|
1307
|
+
|
1308
|
+
Attributes
|
1309
|
+
----------
|
1310
|
+
x : ndarray
|
1311
|
+
Breakpoints.
|
1312
|
+
c : ndarray
|
1313
|
+
Coefficients of the polynomials. They are reshaped
|
1314
|
+
to a 3-D array with the last dimension representing
|
1315
|
+
the trailing dimensions of the original coefficient array.
|
1316
|
+
axis : int
|
1317
|
+
Interpolation axis.
|
1318
|
+
|
1319
|
+
Methods
|
1320
|
+
-------
|
1321
|
+
__call__
|
1322
|
+
extend
|
1323
|
+
derivative
|
1324
|
+
antiderivative
|
1325
|
+
integrate
|
1326
|
+
construct_fast
|
1327
|
+
from_power_basis
|
1328
|
+
from_derivatives
|
1329
|
+
|
1330
|
+
See also
|
1331
|
+
--------
|
1332
|
+
PPoly : piecewise polynomials in the power basis
|
1333
|
+
|
1334
|
+
Notes
|
1335
|
+
-----
|
1336
|
+
Properties of Bernstein polynomials are well documented in the literature,
|
1337
|
+
see for example [1]_ [2]_ [3]_.
|
1338
|
+
|
1339
|
+
References
|
1340
|
+
----------
|
1341
|
+
.. [1] https://en.wikipedia.org/wiki/Bernstein_polynomial
|
1342
|
+
|
1343
|
+
.. [2] Kenneth I. Joy, Bernstein polynomials,
|
1344
|
+
http://www.idav.ucdavis.edu/education/CAGDNotes/Bernstein-Polynomials.pdf
|
1345
|
+
|
1346
|
+
.. [3] E. H. Doha, A. H. Bhrawy, and M. A. Saker, Boundary Value Problems,
|
1347
|
+
vol 2011, article ID 829546, :doi:`10.1155/2011/829543`.
|
1348
|
+
|
1349
|
+
Examples
|
1350
|
+
--------
|
1351
|
+
>>> from scipy.interpolate import BPoly
|
1352
|
+
>>> x = [0, 1]
|
1353
|
+
>>> c = [[1], [2], [3]]
|
1354
|
+
>>> bp = BPoly(c, x)
|
1355
|
+
|
1356
|
+
This creates a 2nd order polynomial
|
1357
|
+
|
1358
|
+
.. math::
|
1359
|
+
|
1360
|
+
B(x) = 1 \\times b_{0, 2}(x) + 2 \\times b_{1, 2}(x) + 3
|
1361
|
+
\\times b_{2, 2}(x) \\\\
|
1362
|
+
= 1 \\times (1-x)^2 + 2 \\times 2 x (1 - x) + 3 \\times x^2
|
1363
|
+
|
1364
|
+
""" # noqa: E501
|
1365
|
+
|
1366
|
+
def _evaluate(self, x, nu, extrapolate, out):
|
1367
|
+
_ppoly.evaluate_bernstein(
|
1368
|
+
self.c.reshape(self.c.shape[0], self.c.shape[1], -1),
|
1369
|
+
self.x, x, nu, bool(extrapolate), out)
|
1370
|
+
|
1371
|
+
def derivative(self, nu=1):
|
1372
|
+
"""
|
1373
|
+
Construct a new piecewise polynomial representing the derivative.
|
1374
|
+
|
1375
|
+
Parameters
|
1376
|
+
----------
|
1377
|
+
nu : int, optional
|
1378
|
+
Order of derivative to evaluate. Default is 1, i.e., compute the
|
1379
|
+
first derivative. If negative, the antiderivative is returned.
|
1380
|
+
|
1381
|
+
Returns
|
1382
|
+
-------
|
1383
|
+
bp : BPoly
|
1384
|
+
Piecewise polynomial of order k - nu representing the derivative of
|
1385
|
+
this polynomial.
|
1386
|
+
|
1387
|
+
"""
|
1388
|
+
if nu < 0:
|
1389
|
+
return self.antiderivative(-nu)
|
1390
|
+
|
1391
|
+
if nu > 1:
|
1392
|
+
bp = self
|
1393
|
+
for k in range(nu):
|
1394
|
+
bp = bp.derivative()
|
1395
|
+
return bp
|
1396
|
+
|
1397
|
+
# reduce order
|
1398
|
+
if nu == 0:
|
1399
|
+
c2 = self.c.copy()
|
1400
|
+
else:
|
1401
|
+
# For a polynomial
|
1402
|
+
# B(x) = \sum_{a=0}^{k} c_a b_{a, k}(x),
|
1403
|
+
# we use the fact that
|
1404
|
+
# b'_{a, k} = k ( b_{a-1, k-1} - b_{a, k-1} ),
|
1405
|
+
# which leads to
|
1406
|
+
# B'(x) = \sum_{a=0}^{k-1} (c_{a+1} - c_a) b_{a, k-1}
|
1407
|
+
#
|
1408
|
+
# finally, for an interval [y, y + dy] with dy != 1,
|
1409
|
+
# we need to correct for an extra power of dy
|
1410
|
+
|
1411
|
+
rest = (None,)*(self.c.ndim-2)
|
1412
|
+
|
1413
|
+
k = self.c.shape[0] - 1
|
1414
|
+
dx = np.diff(self.x)[(None, slice(None))+rest]
|
1415
|
+
c2 = k * np.diff(self.c, axis=0) / dx
|
1416
|
+
|
1417
|
+
if c2.shape[0] == 0:
|
1418
|
+
# derivative of order 0 is zero
|
1419
|
+
c2 = np.zeros((1,) + c2.shape[1:], dtype=c2.dtype)
|
1420
|
+
|
1421
|
+
# construct a compatible polynomial
|
1422
|
+
return self.construct_fast(c2, self.x, self.extrapolate, self.axis)
|
1423
|
+
|
1424
|
+
def antiderivative(self, nu=1):
|
1425
|
+
"""
|
1426
|
+
Construct a new piecewise polynomial representing the antiderivative.
|
1427
|
+
|
1428
|
+
Parameters
|
1429
|
+
----------
|
1430
|
+
nu : int, optional
|
1431
|
+
Order of antiderivative to evaluate. Default is 1, i.e., compute
|
1432
|
+
the first integral. If negative, the derivative is returned.
|
1433
|
+
|
1434
|
+
Returns
|
1435
|
+
-------
|
1436
|
+
bp : BPoly
|
1437
|
+
Piecewise polynomial of order k + nu representing the
|
1438
|
+
antiderivative of this polynomial.
|
1439
|
+
|
1440
|
+
Notes
|
1441
|
+
-----
|
1442
|
+
If antiderivative is computed and ``self.extrapolate='periodic'``,
|
1443
|
+
it will be set to False for the returned instance. This is done because
|
1444
|
+
the antiderivative is no longer periodic and its correct evaluation
|
1445
|
+
outside of the initially given x interval is difficult.
|
1446
|
+
"""
|
1447
|
+
if nu <= 0:
|
1448
|
+
return self.derivative(-nu)
|
1449
|
+
|
1450
|
+
if nu > 1:
|
1451
|
+
bp = self
|
1452
|
+
for k in range(nu):
|
1453
|
+
bp = bp.antiderivative()
|
1454
|
+
return bp
|
1455
|
+
|
1456
|
+
# Construct the indefinite integrals on individual intervals
|
1457
|
+
c, x = self.c, self.x
|
1458
|
+
k = c.shape[0]
|
1459
|
+
c2 = np.zeros((k+1,) + c.shape[1:], dtype=c.dtype)
|
1460
|
+
|
1461
|
+
c2[1:, ...] = np.cumsum(c, axis=0) / k
|
1462
|
+
delta = x[1:] - x[:-1]
|
1463
|
+
c2 *= delta[(None, slice(None)) + (None,)*(c.ndim-2)]
|
1464
|
+
|
1465
|
+
# Now fix continuity: on the very first interval, take the integration
|
1466
|
+
# constant to be zero; on an interval [x_j, x_{j+1}) with j>0,
|
1467
|
+
# the integration constant is then equal to the jump of the `bp` at x_j.
|
1468
|
+
# The latter is given by the coefficient of B_{n+1, n+1}
|
1469
|
+
# *on the previous interval* (other B. polynomials are zero at the
|
1470
|
+
# breakpoint). Finally, use the fact that BPs form a partition of unity.
|
1471
|
+
c2[:,1:] += np.cumsum(c2[k, :], axis=0)[:-1]
|
1472
|
+
|
1473
|
+
if self.extrapolate == 'periodic':
|
1474
|
+
extrapolate = False
|
1475
|
+
else:
|
1476
|
+
extrapolate = self.extrapolate
|
1477
|
+
|
1478
|
+
return self.construct_fast(c2, x, extrapolate, axis=self.axis)
|
1479
|
+
|
1480
|
+
def integrate(self, a, b, extrapolate=None):
|
1481
|
+
"""
|
1482
|
+
Compute a definite integral over a piecewise polynomial.
|
1483
|
+
|
1484
|
+
Parameters
|
1485
|
+
----------
|
1486
|
+
a : float
|
1487
|
+
Lower integration bound
|
1488
|
+
b : float
|
1489
|
+
Upper integration bound
|
1490
|
+
extrapolate : {bool, 'periodic', None}, optional
|
1491
|
+
Whether to extrapolate to out-of-bounds points based on first
|
1492
|
+
and last intervals, or to return NaNs. If 'periodic', periodic
|
1493
|
+
extrapolation is used. If None (default), use `self.extrapolate`.
|
1494
|
+
|
1495
|
+
Returns
|
1496
|
+
-------
|
1497
|
+
array_like
|
1498
|
+
Definite integral of the piecewise polynomial over [a, b]
|
1499
|
+
|
1500
|
+
"""
|
1501
|
+
# XXX: can probably use instead the fact that
|
1502
|
+
# \int_0^{1} B_{j, n}(x) \dx = 1/(n+1)
|
1503
|
+
ib = self.antiderivative()
|
1504
|
+
if extrapolate is None:
|
1505
|
+
extrapolate = self.extrapolate
|
1506
|
+
|
1507
|
+
# ib.extrapolate shouldn't be 'periodic', it is converted to
|
1508
|
+
# False for 'periodic. in antiderivative() call.
|
1509
|
+
if extrapolate != 'periodic':
|
1510
|
+
ib.extrapolate = extrapolate
|
1511
|
+
|
1512
|
+
if extrapolate == 'periodic':
|
1513
|
+
# Split the integral into the part over period (can be several
|
1514
|
+
# of them) and the remaining part.
|
1515
|
+
|
1516
|
+
# For simplicity and clarity convert to a <= b case.
|
1517
|
+
if a <= b:
|
1518
|
+
sign = 1
|
1519
|
+
else:
|
1520
|
+
a, b = b, a
|
1521
|
+
sign = -1
|
1522
|
+
|
1523
|
+
xs, xe = self.x[0], self.x[-1]
|
1524
|
+
period = xe - xs
|
1525
|
+
interval = b - a
|
1526
|
+
n_periods, left = divmod(interval, period)
|
1527
|
+
res = n_periods * (ib(xe) - ib(xs))
|
1528
|
+
|
1529
|
+
# Map a and b to [xs, xe].
|
1530
|
+
a = xs + (a - xs) % period
|
1531
|
+
b = a + left
|
1532
|
+
|
1533
|
+
# If b <= xe then we need to integrate over [a, b], otherwise
|
1534
|
+
# over [a, xe] and from xs to what is remained.
|
1535
|
+
if b <= xe:
|
1536
|
+
res += ib(b) - ib(a)
|
1537
|
+
else:
|
1538
|
+
res += ib(xe) - ib(a) + ib(xs + left + a - xe) - ib(xs)
|
1539
|
+
|
1540
|
+
return sign * res
|
1541
|
+
else:
|
1542
|
+
return ib(b) - ib(a)
|
1543
|
+
|
1544
|
+
def extend(self, c, x):
|
1545
|
+
k = max(self.c.shape[0], c.shape[0])
|
1546
|
+
self.c = self._raise_degree(self.c, k - self.c.shape[0])
|
1547
|
+
c = self._raise_degree(c, k - c.shape[0])
|
1548
|
+
return _PPolyBase.extend(self, c, x)
|
1549
|
+
extend.__doc__ = _PPolyBase.extend.__doc__
|
1550
|
+
|
1551
|
+
@classmethod
|
1552
|
+
def from_power_basis(cls, pp, extrapolate=None):
|
1553
|
+
"""
|
1554
|
+
Construct a piecewise polynomial in Bernstein basis
|
1555
|
+
from a power basis polynomial.
|
1556
|
+
|
1557
|
+
Parameters
|
1558
|
+
----------
|
1559
|
+
pp : PPoly
|
1560
|
+
A piecewise polynomial in the power basis
|
1561
|
+
extrapolate : bool or 'periodic', optional
|
1562
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
1563
|
+
based on first and last intervals, or to return NaNs.
|
1564
|
+
If 'periodic', periodic extrapolation is used. Default is True.
|
1565
|
+
"""
|
1566
|
+
if not isinstance(pp, PPoly):
|
1567
|
+
raise TypeError(f".from_power_basis only accepts PPoly instances. "
|
1568
|
+
f"Got {type(pp)} instead.")
|
1569
|
+
|
1570
|
+
dx = np.diff(pp.x)
|
1571
|
+
k = pp.c.shape[0] - 1 # polynomial order
|
1572
|
+
|
1573
|
+
rest = (None,)*(pp.c.ndim-2)
|
1574
|
+
|
1575
|
+
c = np.zeros_like(pp.c)
|
1576
|
+
for a in range(k+1):
|
1577
|
+
factor = pp.c[a] / comb(k, k-a) * dx[(slice(None),)+rest]**(k-a)
|
1578
|
+
for j in range(k-a, k+1):
|
1579
|
+
c[j] += factor * comb(j, k-a)
|
1580
|
+
|
1581
|
+
if extrapolate is None:
|
1582
|
+
extrapolate = pp.extrapolate
|
1583
|
+
|
1584
|
+
return cls.construct_fast(c, pp.x, extrapolate, pp.axis)
|
1585
|
+
|
1586
|
+
@classmethod
|
1587
|
+
def from_derivatives(cls, xi, yi, orders=None, extrapolate=None):
|
1588
|
+
"""Construct a piecewise polynomial in the Bernstein basis,
|
1589
|
+
compatible with the specified values and derivatives at breakpoints.
|
1590
|
+
|
1591
|
+
Parameters
|
1592
|
+
----------
|
1593
|
+
xi : array_like
|
1594
|
+
sorted 1-D array of x-coordinates
|
1595
|
+
yi : array_like or list of array_likes
|
1596
|
+
``yi[i][j]`` is the ``j``\\ th derivative known at ``xi[i]``
|
1597
|
+
orders : None or int or array_like of ints. Default: None.
|
1598
|
+
Specifies the degree of local polynomials. If not None, some
|
1599
|
+
derivatives are ignored.
|
1600
|
+
extrapolate : bool or 'periodic', optional
|
1601
|
+
If bool, determines whether to extrapolate to out-of-bounds points
|
1602
|
+
based on first and last intervals, or to return NaNs.
|
1603
|
+
If 'periodic', periodic extrapolation is used. Default is True.
|
1604
|
+
|
1605
|
+
Notes
|
1606
|
+
-----
|
1607
|
+
If ``k`` derivatives are specified at a breakpoint ``x``, the
|
1608
|
+
constructed polynomial is exactly ``k`` times continuously
|
1609
|
+
differentiable at ``x``, unless the ``order`` is provided explicitly.
|
1610
|
+
In the latter case, the smoothness of the polynomial at
|
1611
|
+
the breakpoint is controlled by the ``order``.
|
1612
|
+
|
1613
|
+
Deduces the number of derivatives to match at each end
|
1614
|
+
from ``order`` and the number of derivatives available. If
|
1615
|
+
possible it uses the same number of derivatives from
|
1616
|
+
each end; if the number is odd it tries to take the
|
1617
|
+
extra one from y2. In any case if not enough derivatives
|
1618
|
+
are available at one end or another it draws enough to
|
1619
|
+
make up the total from the other end.
|
1620
|
+
|
1621
|
+
If the order is too high and not enough derivatives are available,
|
1622
|
+
an exception is raised.
|
1623
|
+
|
1624
|
+
Examples
|
1625
|
+
--------
|
1626
|
+
|
1627
|
+
>>> from scipy.interpolate import BPoly
|
1628
|
+
>>> BPoly.from_derivatives([0, 1], [[1, 2], [3, 4]])
|
1629
|
+
|
1630
|
+
Creates a polynomial `f(x)` of degree 3, defined on ``[0, 1]``
|
1631
|
+
such that `f(0) = 1, df/dx(0) = 2, f(1) = 3, df/dx(1) = 4`
|
1632
|
+
|
1633
|
+
>>> BPoly.from_derivatives([0, 1, 2], [[0, 1], [0], [2]])
|
1634
|
+
|
1635
|
+
Creates a piecewise polynomial `f(x)`, such that
|
1636
|
+
`f(0) = f(1) = 0`, `f(2) = 2`, and `df/dx(0) = 1`.
|
1637
|
+
Based on the number of derivatives provided, the order of the
|
1638
|
+
local polynomials is 2 on ``[0, 1]`` and 1 on ``[1, 2]``.
|
1639
|
+
Notice that no restriction is imposed on the derivatives at
|
1640
|
+
``x = 1`` and ``x = 2``.
|
1641
|
+
|
1642
|
+
Indeed, the explicit form of the polynomial is::
|
1643
|
+
|
1644
|
+
f(x) = | x * (1 - x), 0 <= x < 1
|
1645
|
+
| 2 * (x - 1), 1 <= x <= 2
|
1646
|
+
|
1647
|
+
So that f'(1-0) = -1 and f'(1+0) = 2
|
1648
|
+
|
1649
|
+
"""
|
1650
|
+
xi = np.asarray(xi)
|
1651
|
+
if len(xi) != len(yi):
|
1652
|
+
raise ValueError("xi and yi need to have the same length")
|
1653
|
+
if np.any(xi[1:] - xi[:1] <= 0):
|
1654
|
+
raise ValueError("x coordinates are not in increasing order")
|
1655
|
+
|
1656
|
+
# number of intervals
|
1657
|
+
m = len(xi) - 1
|
1658
|
+
|
1659
|
+
# global poly order is k-1, local orders are <=k and can vary
|
1660
|
+
try:
|
1661
|
+
k = max(len(yi[i]) + len(yi[i+1]) for i in range(m))
|
1662
|
+
except TypeError as e:
|
1663
|
+
raise ValueError(
|
1664
|
+
"Using a 1-D array for y? Please .reshape(-1, 1)."
|
1665
|
+
) from e
|
1666
|
+
|
1667
|
+
if orders is None:
|
1668
|
+
orders = [None] * m
|
1669
|
+
else:
|
1670
|
+
if isinstance(orders, int | np.integer):
|
1671
|
+
orders = [orders] * m
|
1672
|
+
k = max(k, max(orders))
|
1673
|
+
|
1674
|
+
if any(o <= 0 for o in orders):
|
1675
|
+
raise ValueError("Orders must be positive.")
|
1676
|
+
|
1677
|
+
c = []
|
1678
|
+
for i in range(m):
|
1679
|
+
y1, y2 = yi[i], yi[i+1]
|
1680
|
+
if orders[i] is None:
|
1681
|
+
n1, n2 = len(y1), len(y2)
|
1682
|
+
else:
|
1683
|
+
n = orders[i]+1
|
1684
|
+
n1 = min(n//2, len(y1))
|
1685
|
+
n2 = min(n - n1, len(y2))
|
1686
|
+
n1 = min(n - n2, len(y2))
|
1687
|
+
if n1 + n2 != n:
|
1688
|
+
mesg = (
|
1689
|
+
f"Point {xi[i]} has {len(y1)} derivatives, point {xi[i+1]} has "
|
1690
|
+
f"{len(y2)} derivatives, but order {orders[i]} requested"
|
1691
|
+
)
|
1692
|
+
raise ValueError(mesg)
|
1693
|
+
|
1694
|
+
if not (n1 <= len(y1) and n2 <= len(y2)):
|
1695
|
+
raise ValueError("`order` input incompatible with"
|
1696
|
+
" length y1 or y2.")
|
1697
|
+
|
1698
|
+
b = BPoly._construct_from_derivatives(xi[i], xi[i+1],
|
1699
|
+
y1[:n1], y2[:n2])
|
1700
|
+
if len(b) < k:
|
1701
|
+
b = BPoly._raise_degree(b, k - len(b))
|
1702
|
+
c.append(b)
|
1703
|
+
|
1704
|
+
c = np.asarray(c)
|
1705
|
+
return cls(c.swapaxes(0, 1), xi, extrapolate)
|
1706
|
+
|
1707
|
+
@staticmethod
|
1708
|
+
def _construct_from_derivatives(xa, xb, ya, yb):
|
1709
|
+
r"""Compute the coefficients of a polynomial in the Bernstein basis
|
1710
|
+
given the values and derivatives at the edges.
|
1711
|
+
|
1712
|
+
Return the coefficients of a polynomial in the Bernstein basis
|
1713
|
+
defined on ``[xa, xb]`` and having the values and derivatives at the
|
1714
|
+
endpoints `xa` and `xb` as specified by `ya` and `yb`.
|
1715
|
+
The polynomial constructed is of the minimal possible degree, i.e.,
|
1716
|
+
if the lengths of `ya` and `yb` are `na` and `nb`, the degree
|
1717
|
+
of the polynomial is ``na + nb - 1``.
|
1718
|
+
|
1719
|
+
Parameters
|
1720
|
+
----------
|
1721
|
+
xa : float
|
1722
|
+
Left-hand end point of the interval
|
1723
|
+
xb : float
|
1724
|
+
Right-hand end point of the interval
|
1725
|
+
ya : array_like
|
1726
|
+
Derivatives at `xa`. ``ya[0]`` is the value of the function, and
|
1727
|
+
``ya[i]`` for ``i > 0`` is the value of the ``i``\ th derivative.
|
1728
|
+
yb : array_like
|
1729
|
+
Derivatives at `xb`.
|
1730
|
+
|
1731
|
+
Returns
|
1732
|
+
-------
|
1733
|
+
array
|
1734
|
+
coefficient array of a polynomial having specified derivatives
|
1735
|
+
|
1736
|
+
Notes
|
1737
|
+
-----
|
1738
|
+
This uses several facts from life of Bernstein basis functions.
|
1739
|
+
First of all,
|
1740
|
+
|
1741
|
+
.. math:: b'_{a, n} = n (b_{a-1, n-1} - b_{a, n-1})
|
1742
|
+
|
1743
|
+
If B(x) is a linear combination of the form
|
1744
|
+
|
1745
|
+
.. math:: B(x) = \sum_{a=0}^{n} c_a b_{a, n},
|
1746
|
+
|
1747
|
+
then :math: B'(x) = n \sum_{a=0}^{n-1} (c_{a+1} - c_{a}) b_{a, n-1}.
|
1748
|
+
Iterating the latter one, one finds for the q-th derivative
|
1749
|
+
|
1750
|
+
.. math:: B^{q}(x) = n!/(n-q)! \sum_{a=0}^{n-q} Q_a b_{a, n-q},
|
1751
|
+
|
1752
|
+
with
|
1753
|
+
|
1754
|
+
.. math:: Q_a = \sum_{j=0}^{q} (-)^{j+q} comb(q, j) c_{j+a}
|
1755
|
+
|
1756
|
+
This way, only `a=0` contributes to :math: `B^{q}(x = xa)`, and
|
1757
|
+
`c_q` are found one by one by iterating `q = 0, ..., na`.
|
1758
|
+
|
1759
|
+
At ``x = xb`` it's the same with ``a = n - q``.
|
1760
|
+
|
1761
|
+
"""
|
1762
|
+
ya, yb = np.asarray(ya), np.asarray(yb)
|
1763
|
+
if ya.shape[1:] != yb.shape[1:]:
|
1764
|
+
raise ValueError(
|
1765
|
+
f"Shapes of ya {ya.shape} and yb {yb.shape} are incompatible"
|
1766
|
+
)
|
1767
|
+
|
1768
|
+
dta, dtb = ya.dtype, yb.dtype
|
1769
|
+
if (np.issubdtype(dta, np.complexfloating) or
|
1770
|
+
np.issubdtype(dtb, np.complexfloating)):
|
1771
|
+
dt = np.complex128
|
1772
|
+
else:
|
1773
|
+
dt = np.float64
|
1774
|
+
|
1775
|
+
na, nb = len(ya), len(yb)
|
1776
|
+
n = na + nb
|
1777
|
+
|
1778
|
+
c = np.empty((na+nb,) + ya.shape[1:], dtype=dt)
|
1779
|
+
|
1780
|
+
# compute coefficients of a polynomial degree na+nb-1
|
1781
|
+
# walk left-to-right
|
1782
|
+
for q in range(0, na):
|
1783
|
+
c[q] = ya[q] / spec.poch(n - q, q) * (xb - xa)**q
|
1784
|
+
for j in range(0, q):
|
1785
|
+
c[q] -= (-1)**(j+q) * comb(q, j) * c[j]
|
1786
|
+
|
1787
|
+
# now walk right-to-left
|
1788
|
+
for q in range(0, nb):
|
1789
|
+
c[-q-1] = yb[q] / spec.poch(n - q, q) * (-1)**q * (xb - xa)**q
|
1790
|
+
for j in range(0, q):
|
1791
|
+
c[-q-1] -= (-1)**(j+1) * comb(q, j+1) * c[-q+j]
|
1792
|
+
|
1793
|
+
return c
|
1794
|
+
|
1795
|
+
@staticmethod
|
1796
|
+
def _raise_degree(c, d):
|
1797
|
+
r"""Raise a degree of a polynomial in the Bernstein basis.
|
1798
|
+
|
1799
|
+
Given the coefficients of a polynomial degree `k`, return (the
|
1800
|
+
coefficients of) the equivalent polynomial of degree `k+d`.
|
1801
|
+
|
1802
|
+
Parameters
|
1803
|
+
----------
|
1804
|
+
c : array_like
|
1805
|
+
coefficient array, 1-D
|
1806
|
+
d : integer
|
1807
|
+
|
1808
|
+
Returns
|
1809
|
+
-------
|
1810
|
+
array
|
1811
|
+
coefficient array, 1-D array of length `c.shape[0] + d`
|
1812
|
+
|
1813
|
+
Notes
|
1814
|
+
-----
|
1815
|
+
This uses the fact that a Bernstein polynomial `b_{a, k}` can be
|
1816
|
+
identically represented as a linear combination of polynomials of
|
1817
|
+
a higher degree `k+d`:
|
1818
|
+
|
1819
|
+
.. math:: b_{a, k} = comb(k, a) \sum_{j=0}^{d} b_{a+j, k+d} \
|
1820
|
+
comb(d, j) / comb(k+d, a+j)
|
1821
|
+
|
1822
|
+
"""
|
1823
|
+
if d == 0:
|
1824
|
+
return c
|
1825
|
+
|
1826
|
+
k = c.shape[0] - 1
|
1827
|
+
out = np.zeros((c.shape[0] + d,) + c.shape[1:], dtype=c.dtype)
|
1828
|
+
|
1829
|
+
for a in range(c.shape[0]):
|
1830
|
+
f = c[a] * comb(k, a)
|
1831
|
+
for j in range(d+1):
|
1832
|
+
out[a+j] += f * comb(d, j) / comb(k+d, a+j)
|
1833
|
+
return out
|
1834
|
+
|
1835
|
+
|
1836
|
+
class NdPPoly:
|
1837
|
+
"""
|
1838
|
+
Piecewise tensor product polynomial
|
1839
|
+
|
1840
|
+
The value at point ``xp = (x', y', z', ...)`` is evaluated by first
|
1841
|
+
computing the interval indices `i` such that::
|
1842
|
+
|
1843
|
+
x[0][i[0]] <= x' < x[0][i[0]+1]
|
1844
|
+
x[1][i[1]] <= y' < x[1][i[1]+1]
|
1845
|
+
...
|
1846
|
+
|
1847
|
+
and then computing::
|
1848
|
+
|
1849
|
+
S = sum(c[k0-m0-1,...,kn-mn-1,i[0],...,i[n]]
|
1850
|
+
* (xp[0] - x[0][i[0]])**m0
|
1851
|
+
* ...
|
1852
|
+
* (xp[n] - x[n][i[n]])**mn
|
1853
|
+
for m0 in range(k[0]+1)
|
1854
|
+
...
|
1855
|
+
for mn in range(k[n]+1))
|
1856
|
+
|
1857
|
+
where ``k[j]`` is the degree of the polynomial in dimension j. This
|
1858
|
+
representation is the piecewise multivariate power basis.
|
1859
|
+
|
1860
|
+
Parameters
|
1861
|
+
----------
|
1862
|
+
c : ndarray, shape (k0, ..., kn, m0, ..., mn, ...)
|
1863
|
+
Polynomial coefficients, with polynomial order `kj` and
|
1864
|
+
`mj+1` intervals for each dimension `j`.
|
1865
|
+
x : ndim-tuple of ndarrays, shapes (mj+1,)
|
1866
|
+
Polynomial breakpoints for each dimension. These must be
|
1867
|
+
sorted in increasing order.
|
1868
|
+
extrapolate : bool, optional
|
1869
|
+
Whether to extrapolate to out-of-bounds points based on first
|
1870
|
+
and last intervals, or to return NaNs. Default: True.
|
1871
|
+
|
1872
|
+
Attributes
|
1873
|
+
----------
|
1874
|
+
x : tuple of ndarrays
|
1875
|
+
Breakpoints.
|
1876
|
+
c : ndarray
|
1877
|
+
Coefficients of the polynomials.
|
1878
|
+
|
1879
|
+
Methods
|
1880
|
+
-------
|
1881
|
+
__call__
|
1882
|
+
derivative
|
1883
|
+
antiderivative
|
1884
|
+
integrate
|
1885
|
+
integrate_1d
|
1886
|
+
construct_fast
|
1887
|
+
|
1888
|
+
See also
|
1889
|
+
--------
|
1890
|
+
PPoly : piecewise polynomials in 1D
|
1891
|
+
|
1892
|
+
Notes
|
1893
|
+
-----
|
1894
|
+
High-order polynomials in the power basis can be numerically
|
1895
|
+
unstable.
|
1896
|
+
|
1897
|
+
"""
|
1898
|
+
|
1899
|
+
def __init__(self, c, x, extrapolate=None):
|
1900
|
+
self.x = tuple(np.ascontiguousarray(v, dtype=np.float64) for v in x)
|
1901
|
+
self.c = np.asarray(c)
|
1902
|
+
if extrapolate is None:
|
1903
|
+
extrapolate = True
|
1904
|
+
self.extrapolate = bool(extrapolate)
|
1905
|
+
|
1906
|
+
ndim = len(self.x)
|
1907
|
+
if any(v.ndim != 1 for v in self.x):
|
1908
|
+
raise ValueError("x arrays must all be 1-dimensional")
|
1909
|
+
if any(v.size < 2 for v in self.x):
|
1910
|
+
raise ValueError("x arrays must all contain at least 2 points")
|
1911
|
+
if c.ndim < 2*ndim:
|
1912
|
+
raise ValueError("c must have at least 2*len(x) dimensions")
|
1913
|
+
if any(np.any(v[1:] - v[:-1] < 0) for v in self.x):
|
1914
|
+
raise ValueError("x-coordinates are not in increasing order")
|
1915
|
+
if any(a != b.size - 1 for a, b in zip(c.shape[ndim:2*ndim], self.x)):
|
1916
|
+
raise ValueError("x and c do not agree on the number of intervals")
|
1917
|
+
|
1918
|
+
dtype = self._get_dtype(self.c.dtype)
|
1919
|
+
self.c = np.ascontiguousarray(self.c, dtype=dtype)
|
1920
|
+
|
1921
|
+
@classmethod
|
1922
|
+
def construct_fast(cls, c, x, extrapolate=None):
|
1923
|
+
"""
|
1924
|
+
Construct the piecewise polynomial without making checks.
|
1925
|
+
|
1926
|
+
Takes the same parameters as the constructor. Input arguments
|
1927
|
+
``c`` and ``x`` must be arrays of the correct shape and type. The
|
1928
|
+
``c`` array can only be of dtypes float and complex, and ``x``
|
1929
|
+
array must have dtype float.
|
1930
|
+
|
1931
|
+
"""
|
1932
|
+
self = object.__new__(cls)
|
1933
|
+
self.c = c
|
1934
|
+
self.x = x
|
1935
|
+
if extrapolate is None:
|
1936
|
+
extrapolate = True
|
1937
|
+
self.extrapolate = extrapolate
|
1938
|
+
return self
|
1939
|
+
|
1940
|
+
def _get_dtype(self, dtype):
|
1941
|
+
if np.issubdtype(dtype, np.complexfloating) \
|
1942
|
+
or np.issubdtype(self.c.dtype, np.complexfloating):
|
1943
|
+
return np.complex128
|
1944
|
+
else:
|
1945
|
+
return np.float64
|
1946
|
+
|
1947
|
+
def _ensure_c_contiguous(self):
|
1948
|
+
if not self.c.flags.c_contiguous:
|
1949
|
+
self.c = self.c.copy()
|
1950
|
+
if not isinstance(self.x, tuple):
|
1951
|
+
self.x = tuple(self.x)
|
1952
|
+
|
1953
|
+
def __call__(self, x, nu=None, extrapolate=None):
|
1954
|
+
"""
|
1955
|
+
Evaluate the piecewise polynomial or its derivative
|
1956
|
+
|
1957
|
+
Parameters
|
1958
|
+
----------
|
1959
|
+
x : array-like
|
1960
|
+
Points to evaluate the interpolant at.
|
1961
|
+
nu : tuple, optional
|
1962
|
+
Orders of derivatives to evaluate. Each must be non-negative.
|
1963
|
+
extrapolate : bool, optional
|
1964
|
+
Whether to extrapolate to out-of-bounds points based on first
|
1965
|
+
and last intervals, or to return NaNs.
|
1966
|
+
|
1967
|
+
Returns
|
1968
|
+
-------
|
1969
|
+
y : array-like
|
1970
|
+
Interpolated values. Shape is determined by replacing
|
1971
|
+
the interpolation axis in the original array with the shape of x.
|
1972
|
+
|
1973
|
+
Notes
|
1974
|
+
-----
|
1975
|
+
Derivatives are evaluated piecewise for each polynomial
|
1976
|
+
segment, even if the polynomial is not differentiable at the
|
1977
|
+
breakpoints. The polynomial intervals are considered half-open,
|
1978
|
+
``[a, b)``, except for the last interval which is closed
|
1979
|
+
``[a, b]``.
|
1980
|
+
|
1981
|
+
"""
|
1982
|
+
if extrapolate is None:
|
1983
|
+
extrapolate = self.extrapolate
|
1984
|
+
else:
|
1985
|
+
extrapolate = bool(extrapolate)
|
1986
|
+
|
1987
|
+
ndim = len(self.x)
|
1988
|
+
|
1989
|
+
x = _ndim_coords_from_arrays(x)
|
1990
|
+
x_shape = x.shape
|
1991
|
+
x = np.ascontiguousarray(x.reshape(-1, x.shape[-1]), dtype=np.float64)
|
1992
|
+
|
1993
|
+
if nu is None:
|
1994
|
+
nu = np.zeros((ndim,), dtype=np.intc)
|
1995
|
+
else:
|
1996
|
+
nu = np.asarray(nu, dtype=np.intc)
|
1997
|
+
if nu.ndim != 1 or nu.shape[0] != ndim:
|
1998
|
+
raise ValueError("invalid number of derivative orders nu")
|
1999
|
+
|
2000
|
+
dim1 = prod(self.c.shape[:ndim])
|
2001
|
+
dim2 = prod(self.c.shape[ndim:2*ndim])
|
2002
|
+
dim3 = prod(self.c.shape[2*ndim:])
|
2003
|
+
ks = np.array(self.c.shape[:ndim], dtype=np.intc)
|
2004
|
+
|
2005
|
+
out = np.empty((x.shape[0], dim3), dtype=self.c.dtype)
|
2006
|
+
self._ensure_c_contiguous()
|
2007
|
+
|
2008
|
+
_ppoly.evaluate_nd(self.c.reshape(dim1, dim2, dim3),
|
2009
|
+
self.x,
|
2010
|
+
ks,
|
2011
|
+
x,
|
2012
|
+
nu,
|
2013
|
+
bool(extrapolate),
|
2014
|
+
out)
|
2015
|
+
|
2016
|
+
return out.reshape(x_shape[:-1] + self.c.shape[2*ndim:])
|
2017
|
+
|
2018
|
+
def _derivative_inplace(self, nu, axis):
|
2019
|
+
"""
|
2020
|
+
Compute 1-D derivative along a selected dimension in-place
|
2021
|
+
May result to non-contiguous c array.
|
2022
|
+
"""
|
2023
|
+
if nu < 0:
|
2024
|
+
return self._antiderivative_inplace(-nu, axis)
|
2025
|
+
|
2026
|
+
ndim = len(self.x)
|
2027
|
+
axis = axis % ndim
|
2028
|
+
|
2029
|
+
# reduce order
|
2030
|
+
if nu == 0:
|
2031
|
+
# noop
|
2032
|
+
return
|
2033
|
+
else:
|
2034
|
+
sl = [slice(None)]*ndim
|
2035
|
+
sl[axis] = slice(None, -nu, None)
|
2036
|
+
c2 = self.c[tuple(sl)]
|
2037
|
+
|
2038
|
+
if c2.shape[axis] == 0:
|
2039
|
+
# derivative of order 0 is zero
|
2040
|
+
shp = list(c2.shape)
|
2041
|
+
shp[axis] = 1
|
2042
|
+
c2 = np.zeros(shp, dtype=c2.dtype)
|
2043
|
+
|
2044
|
+
# multiply by the correct rising factorials
|
2045
|
+
factor = spec.poch(np.arange(c2.shape[axis], 0, -1), nu)
|
2046
|
+
sl = [None]*c2.ndim
|
2047
|
+
sl[axis] = slice(None)
|
2048
|
+
c2 *= factor[tuple(sl)]
|
2049
|
+
|
2050
|
+
self.c = c2
|
2051
|
+
|
2052
|
+
def _antiderivative_inplace(self, nu, axis):
|
2053
|
+
"""
|
2054
|
+
Compute 1-D antiderivative along a selected dimension
|
2055
|
+
May result to non-contiguous c array.
|
2056
|
+
"""
|
2057
|
+
if nu <= 0:
|
2058
|
+
return self._derivative_inplace(-nu, axis)
|
2059
|
+
|
2060
|
+
ndim = len(self.x)
|
2061
|
+
axis = axis % ndim
|
2062
|
+
|
2063
|
+
perm = list(range(ndim))
|
2064
|
+
perm[0], perm[axis] = perm[axis], perm[0]
|
2065
|
+
perm = perm + list(range(ndim, self.c.ndim))
|
2066
|
+
|
2067
|
+
c = self.c.transpose(perm)
|
2068
|
+
|
2069
|
+
c2 = np.zeros((c.shape[0] + nu,) + c.shape[1:],
|
2070
|
+
dtype=c.dtype)
|
2071
|
+
c2[:-nu] = c
|
2072
|
+
|
2073
|
+
# divide by the correct rising factorials
|
2074
|
+
factor = spec.poch(np.arange(c.shape[0], 0, -1), nu)
|
2075
|
+
c2[:-nu] /= factor[(slice(None),) + (None,)*(c.ndim-1)]
|
2076
|
+
|
2077
|
+
# fix continuity of added degrees of freedom
|
2078
|
+
perm2 = list(range(c2.ndim))
|
2079
|
+
perm2[1], perm2[ndim+axis] = perm2[ndim+axis], perm2[1]
|
2080
|
+
|
2081
|
+
c2 = c2.transpose(perm2)
|
2082
|
+
c2 = c2.copy()
|
2083
|
+
_ppoly.fix_continuity(c2.reshape(c2.shape[0], c2.shape[1], -1),
|
2084
|
+
self.x[axis], nu-1)
|
2085
|
+
|
2086
|
+
c2 = c2.transpose(perm2)
|
2087
|
+
c2 = c2.transpose(perm)
|
2088
|
+
|
2089
|
+
# Done
|
2090
|
+
self.c = c2
|
2091
|
+
|
2092
|
+
def derivative(self, nu):
|
2093
|
+
"""
|
2094
|
+
Construct a new piecewise polynomial representing the derivative.
|
2095
|
+
|
2096
|
+
Parameters
|
2097
|
+
----------
|
2098
|
+
nu : ndim-tuple of int
|
2099
|
+
Order of derivatives to evaluate for each dimension.
|
2100
|
+
If negative, the antiderivative is returned.
|
2101
|
+
|
2102
|
+
Returns
|
2103
|
+
-------
|
2104
|
+
pp : NdPPoly
|
2105
|
+
Piecewise polynomial of orders (k[0] - nu[0], ..., k[n] - nu[n])
|
2106
|
+
representing the derivative of this polynomial.
|
2107
|
+
|
2108
|
+
Notes
|
2109
|
+
-----
|
2110
|
+
Derivatives are evaluated piecewise for each polynomial
|
2111
|
+
segment, even if the polynomial is not differentiable at the
|
2112
|
+
breakpoints. The polynomial intervals in each dimension are
|
2113
|
+
considered half-open, ``[a, b)``, except for the last interval
|
2114
|
+
which is closed ``[a, b]``.
|
2115
|
+
|
2116
|
+
"""
|
2117
|
+
p = self.construct_fast(self.c.copy(), self.x, self.extrapolate)
|
2118
|
+
|
2119
|
+
for axis, n in enumerate(nu):
|
2120
|
+
p._derivative_inplace(n, axis)
|
2121
|
+
|
2122
|
+
p._ensure_c_contiguous()
|
2123
|
+
return p
|
2124
|
+
|
2125
|
+
def antiderivative(self, nu):
|
2126
|
+
"""
|
2127
|
+
Construct a new piecewise polynomial representing the antiderivative.
|
2128
|
+
|
2129
|
+
Antiderivative is also the indefinite integral of the function,
|
2130
|
+
and derivative is its inverse operation.
|
2131
|
+
|
2132
|
+
Parameters
|
2133
|
+
----------
|
2134
|
+
nu : ndim-tuple of int
|
2135
|
+
Order of derivatives to evaluate for each dimension.
|
2136
|
+
If negative, the derivative is returned.
|
2137
|
+
|
2138
|
+
Returns
|
2139
|
+
-------
|
2140
|
+
pp : PPoly
|
2141
|
+
Piecewise polynomial of order k2 = k + n representing
|
2142
|
+
the antiderivative of this polynomial.
|
2143
|
+
|
2144
|
+
Notes
|
2145
|
+
-----
|
2146
|
+
The antiderivative returned by this function is continuous and
|
2147
|
+
continuously differentiable to order n-1, up to floating point
|
2148
|
+
rounding error.
|
2149
|
+
|
2150
|
+
"""
|
2151
|
+
p = self.construct_fast(self.c.copy(), self.x, self.extrapolate)
|
2152
|
+
|
2153
|
+
for axis, n in enumerate(nu):
|
2154
|
+
p._antiderivative_inplace(n, axis)
|
2155
|
+
|
2156
|
+
p._ensure_c_contiguous()
|
2157
|
+
return p
|
2158
|
+
|
2159
|
+
def integrate_1d(self, a, b, axis, extrapolate=None):
|
2160
|
+
r"""
|
2161
|
+
Compute NdPPoly representation for one dimensional definite integral
|
2162
|
+
|
2163
|
+
The result is a piecewise polynomial representing the integral:
|
2164
|
+
|
2165
|
+
.. math::
|
2166
|
+
|
2167
|
+
p(y, z, ...) = \int_a^b dx\, p(x, y, z, ...)
|
2168
|
+
|
2169
|
+
where the dimension integrated over is specified with the
|
2170
|
+
`axis` parameter.
|
2171
|
+
|
2172
|
+
Parameters
|
2173
|
+
----------
|
2174
|
+
a, b : float
|
2175
|
+
Lower and upper bound for integration.
|
2176
|
+
axis : int
|
2177
|
+
Dimension over which to compute the 1-D integrals
|
2178
|
+
extrapolate : bool, optional
|
2179
|
+
Whether to extrapolate to out-of-bounds points based on first
|
2180
|
+
and last intervals, or to return NaNs.
|
2181
|
+
|
2182
|
+
Returns
|
2183
|
+
-------
|
2184
|
+
ig : NdPPoly or array-like
|
2185
|
+
Definite integral of the piecewise polynomial over [a, b].
|
2186
|
+
If the polynomial was 1D, an array is returned,
|
2187
|
+
otherwise, an NdPPoly object.
|
2188
|
+
|
2189
|
+
"""
|
2190
|
+
if extrapolate is None:
|
2191
|
+
extrapolate = self.extrapolate
|
2192
|
+
else:
|
2193
|
+
extrapolate = bool(extrapolate)
|
2194
|
+
|
2195
|
+
ndim = len(self.x)
|
2196
|
+
axis = int(axis) % ndim
|
2197
|
+
|
2198
|
+
# reuse 1-D integration routines
|
2199
|
+
c = self.c
|
2200
|
+
swap = list(range(c.ndim))
|
2201
|
+
swap.insert(0, swap[axis])
|
2202
|
+
del swap[axis + 1]
|
2203
|
+
swap.insert(1, swap[ndim + axis])
|
2204
|
+
del swap[ndim + axis + 1]
|
2205
|
+
|
2206
|
+
c = c.transpose(swap)
|
2207
|
+
p = PPoly.construct_fast(c.reshape(c.shape[0], c.shape[1], -1),
|
2208
|
+
self.x[axis],
|
2209
|
+
extrapolate=extrapolate)
|
2210
|
+
out = p.integrate(a, b, extrapolate=extrapolate)
|
2211
|
+
|
2212
|
+
# Construct result
|
2213
|
+
if ndim == 1:
|
2214
|
+
return out.reshape(c.shape[2:])
|
2215
|
+
else:
|
2216
|
+
c = out.reshape(c.shape[2:])
|
2217
|
+
x = self.x[:axis] + self.x[axis+1:]
|
2218
|
+
return self.construct_fast(c, x, extrapolate=extrapolate)
|
2219
|
+
|
2220
|
+
def integrate(self, ranges, extrapolate=None):
|
2221
|
+
"""
|
2222
|
+
Compute a definite integral over a piecewise polynomial.
|
2223
|
+
|
2224
|
+
Parameters
|
2225
|
+
----------
|
2226
|
+
ranges : ndim-tuple of 2-tuples float
|
2227
|
+
Sequence of lower and upper bounds for each dimension,
|
2228
|
+
``[(a[0], b[0]), ..., (a[ndim-1], b[ndim-1])]``
|
2229
|
+
extrapolate : bool, optional
|
2230
|
+
Whether to extrapolate to out-of-bounds points based on first
|
2231
|
+
and last intervals, or to return NaNs.
|
2232
|
+
|
2233
|
+
Returns
|
2234
|
+
-------
|
2235
|
+
ig : array_like
|
2236
|
+
Definite integral of the piecewise polynomial over
|
2237
|
+
[a[0], b[0]] x ... x [a[ndim-1], b[ndim-1]]
|
2238
|
+
|
2239
|
+
"""
|
2240
|
+
|
2241
|
+
ndim = len(self.x)
|
2242
|
+
|
2243
|
+
if extrapolate is None:
|
2244
|
+
extrapolate = self.extrapolate
|
2245
|
+
else:
|
2246
|
+
extrapolate = bool(extrapolate)
|
2247
|
+
|
2248
|
+
if not hasattr(ranges, '__len__') or len(ranges) != ndim:
|
2249
|
+
raise ValueError("Range not a sequence of correct length")
|
2250
|
+
|
2251
|
+
self._ensure_c_contiguous()
|
2252
|
+
|
2253
|
+
# Reuse 1D integration routine
|
2254
|
+
c = self.c
|
2255
|
+
for n, (a, b) in enumerate(ranges):
|
2256
|
+
swap = list(range(c.ndim))
|
2257
|
+
swap.insert(1, swap[ndim - n])
|
2258
|
+
del swap[ndim - n + 1]
|
2259
|
+
|
2260
|
+
c = c.transpose(swap)
|
2261
|
+
|
2262
|
+
p = PPoly.construct_fast(c, self.x[n], extrapolate=extrapolate)
|
2263
|
+
out = p.integrate(a, b, extrapolate=extrapolate)
|
2264
|
+
c = out.reshape(c.shape[2:])
|
2265
|
+
|
2266
|
+
return c
|