scipy 1.15.3__cp311-cp311-win_amd64.whl → 1.16.0rc2__cp311-cp311-win_amd64.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 +8 -8
- scipy/__init__.py +3 -6
- scipy/_cyutility.cp311-win_amd64.dll.a +0 -0
- scipy/_cyutility.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_array_api.py +486 -161
- scipy/_lib/_array_api_compat_vendor.py +9 -0
- scipy/_lib/_bunch.py +4 -0
- scipy/_lib/_ccallback_c.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_ccallback_c.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_docscrape.py +1 -1
- scipy/_lib/_elementwise_iterative_method.py +15 -26
- scipy/_lib/_fpumode.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_fpumode.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_ccallback.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_test_ccallback.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_test_deprecation_call.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_test_deprecation_call.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_test_deprecation_def.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_test_deprecation_def.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_testutils.py +6 -2
- scipy/_lib/_uarray/_uarray.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/_uarray/_uarray.cp311-win_amd64.pyd +0 -0
- scipy/_lib/_util.py +222 -125
- scipy/_lib/array_api_compat/__init__.py +4 -4
- scipy/_lib/array_api_compat/_internal.py +19 -6
- scipy/_lib/array_api_compat/common/__init__.py +1 -1
- scipy/_lib/array_api_compat/common/_aliases.py +365 -193
- scipy/_lib/array_api_compat/common/_fft.py +94 -64
- scipy/_lib/array_api_compat/common/_helpers.py +413 -180
- scipy/_lib/array_api_compat/common/_linalg.py +116 -40
- scipy/_lib/array_api_compat/common/_typing.py +179 -10
- scipy/_lib/array_api_compat/cupy/__init__.py +1 -4
- scipy/_lib/array_api_compat/cupy/_aliases.py +61 -41
- scipy/_lib/array_api_compat/cupy/_info.py +16 -6
- scipy/_lib/array_api_compat/cupy/_typing.py +24 -39
- scipy/_lib/array_api_compat/dask/array/__init__.py +6 -3
- scipy/_lib/array_api_compat/dask/array/_aliases.py +267 -108
- scipy/_lib/array_api_compat/dask/array/_info.py +105 -34
- scipy/_lib/array_api_compat/dask/array/fft.py +5 -8
- scipy/_lib/array_api_compat/dask/array/linalg.py +21 -22
- scipy/_lib/array_api_compat/numpy/__init__.py +13 -15
- scipy/_lib/array_api_compat/numpy/_aliases.py +98 -49
- scipy/_lib/array_api_compat/numpy/_info.py +36 -16
- scipy/_lib/array_api_compat/numpy/_typing.py +27 -43
- scipy/_lib/array_api_compat/numpy/fft.py +11 -5
- scipy/_lib/array_api_compat/numpy/linalg.py +75 -22
- scipy/_lib/array_api_compat/torch/__init__.py +3 -5
- scipy/_lib/array_api_compat/torch/_aliases.py +262 -159
- scipy/_lib/array_api_compat/torch/_info.py +27 -16
- scipy/_lib/array_api_compat/torch/_typing.py +3 -0
- scipy/_lib/array_api_compat/torch/fft.py +17 -18
- scipy/_lib/array_api_compat/torch/linalg.py +16 -16
- scipy/_lib/array_api_extra/__init__.py +26 -3
- 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/decorator.py +2 -2
- scipy/_lib/doccer.py +1 -7
- scipy/_lib/messagestream.cp311-win_amd64.dll.a +0 -0
- scipy/_lib/messagestream.cp311-win_amd64.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/test__util.py +105 -121
- scipy/_lib/tests/test_array_api.py +166 -35
- scipy/_lib/tests/test_bunch.py +7 -0
- scipy/_lib/tests/test_ccallback.py +2 -10
- scipy/_lib/tests/test_public_api.py +13 -0
- scipy/cluster/_hierarchy.cp311-win_amd64.dll.a +0 -0
- scipy/cluster/_hierarchy.cp311-win_amd64.pyd +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp311-win_amd64.dll.a +0 -0
- scipy/cluster/_optimal_leaf_ordering.cp311-win_amd64.pyd +0 -0
- scipy/cluster/_vq.cp311-win_amd64.dll.a +0 -0
- scipy/cluster/_vq.cp311-win_amd64.pyd +0 -0
- scipy/cluster/hierarchy.py +393 -223
- scipy/cluster/tests/test_hierarchy.py +273 -335
- scipy/cluster/tests/test_vq.py +45 -61
- scipy/cluster/vq.py +39 -35
- scipy/conftest.py +263 -157
- scipy/constants/_constants.py +4 -1
- scipy/constants/tests/test_codata.py +2 -2
- scipy/constants/tests/test_constants.py +11 -18
- scipy/datasets/_download_all.py +15 -1
- scipy/datasets/_fetchers.py +7 -1
- scipy/datasets/_utils.py +1 -1
- scipy/differentiate/_differentiate.py +25 -25
- scipy/differentiate/tests/test_differentiate.py +24 -25
- scipy/fft/_basic.py +20 -0
- scipy/fft/_helper.py +3 -34
- scipy/fft/_pocketfft/helper.py +29 -1
- scipy/fft/_pocketfft/pypocketfft.cp311-win_amd64.dll.a +0 -0
- scipy/fft/_pocketfft/pypocketfft.cp311-win_amd64.pyd +0 -0
- scipy/fft/_pocketfft/tests/test_basic.py +2 -4
- scipy/fft/_pocketfft/tests/test_real_transforms.py +4 -4
- scipy/fft/_realtransforms.py +13 -0
- scipy/fft/tests/test_basic.py +27 -25
- scipy/fft/tests/test_fftlog.py +16 -7
- scipy/fft/tests/test_helper.py +18 -34
- scipy/fft/tests/test_real_transforms.py +8 -10
- scipy/fftpack/convolve.cp311-win_amd64.dll.a +0 -0
- scipy/fftpack/convolve.cp311-win_amd64.pyd +0 -0
- scipy/fftpack/tests/test_basic.py +2 -4
- scipy/fftpack/tests/test_real_transforms.py +8 -9
- scipy/integrate/_bvp.py +9 -3
- scipy/integrate/_cubature.py +3 -2
- scipy/integrate/_dop.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_dop.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_lsoda.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_lsoda.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_ode.py +9 -2
- scipy/integrate/_odepack.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_odepack.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_quad_vec.py +21 -29
- scipy/integrate/_quadpack.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_quadpack.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_quadpack_py.py +11 -7
- scipy/integrate/_quadrature.py +3 -3
- scipy/integrate/_rules/_base.py +2 -2
- scipy/integrate/_tanhsinh.py +48 -47
- scipy/integrate/_test_multivariate.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_test_multivariate.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_test_odeint_banded.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_test_odeint_banded.cp311-win_amd64.pyd +0 -0
- scipy/integrate/_vode.cp311-win_amd64.dll.a +0 -0
- scipy/integrate/_vode.cp311-win_amd64.pyd +0 -0
- scipy/integrate/tests/test__quad_vec.py +0 -6
- scipy/integrate/tests/test_banded_ode_solvers.py +85 -0
- scipy/integrate/tests/test_cubature.py +21 -35
- scipy/integrate/tests/test_quadrature.py +6 -8
- scipy/integrate/tests/test_tanhsinh.py +56 -48
- scipy/interpolate/__init__.py +70 -58
- scipy/interpolate/_bary_rational.py +22 -22
- scipy/interpolate/_bsplines.py +119 -66
- scipy/interpolate/_cubic.py +65 -50
- scipy/interpolate/_dfitpack.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_dfitpack.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_dierckx.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_dierckx.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_fitpack.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_fitpack.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_fitpack2.py +9 -6
- scipy/interpolate/_fitpack_impl.py +32 -26
- scipy/interpolate/_fitpack_repro.py +23 -19
- scipy/interpolate/_interpnd.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_interpnd.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_interpolate.py +30 -12
- scipy/interpolate/_ndbspline.py +13 -18
- scipy/interpolate/_ndgriddata.py +5 -8
- scipy/interpolate/_polyint.py +95 -31
- scipy/interpolate/_ppoly.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_ppoly.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_rbf.py +2 -2
- scipy/interpolate/_rbfinterp.py +1 -1
- scipy/interpolate/_rbfinterp_pythran.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_rbfinterp_pythran.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/_rgi.py +31 -26
- scipy/interpolate/_rgi_cython.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_rgi_cython.cp311-win_amd64.pyd +0 -0
- scipy/interpolate/dfitpack.py +0 -20
- scipy/interpolate/interpnd.py +1 -2
- scipy/interpolate/tests/test_bary_rational.py +2 -2
- scipy/interpolate/tests/test_bsplines.py +97 -1
- scipy/interpolate/tests/test_fitpack2.py +39 -1
- scipy/interpolate/tests/test_interpnd.py +32 -20
- scipy/interpolate/tests/test_interpolate.py +48 -4
- scipy/interpolate/tests/test_rgi.py +2 -1
- scipy/io/_fast_matrix_market/__init__.py +2 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp311-win_amd64.dll.a +0 -0
- scipy/io/_fast_matrix_market/_fmm_core.cp311-win_amd64.pyd +0 -0
- scipy/io/_harwell_boeing/_fortran_format_parser.py +19 -16
- scipy/io/_harwell_boeing/hb.py +7 -11
- scipy/io/_idl.py +5 -7
- scipy/io/_netcdf.py +15 -5
- scipy/io/_test_fortran.cp311-win_amd64.dll.a +0 -0
- scipy/io/_test_fortran.cp311-win_amd64.pyd +0 -0
- scipy/io/arff/tests/test_arffread.py +3 -3
- scipy/io/matlab/__init__.py +5 -3
- scipy/io/matlab/_mio.py +4 -1
- scipy/io/matlab/_mio5.py +19 -13
- scipy/io/matlab/_mio5_utils.cp311-win_amd64.dll.a +0 -0
- scipy/io/matlab/_mio5_utils.cp311-win_amd64.pyd +0 -0
- scipy/io/matlab/_mio_utils.cp311-win_amd64.dll.a +0 -0
- scipy/io/matlab/_mio_utils.cp311-win_amd64.pyd +0 -0
- scipy/io/matlab/_miobase.py +4 -1
- scipy/io/matlab/_streams.cp311-win_amd64.dll.a +0 -0
- scipy/io/matlab/_streams.cp311-win_amd64.pyd +0 -0
- scipy/io/matlab/tests/test_mio.py +46 -18
- scipy/io/matlab/tests/test_mio_funcs.py +1 -1
- scipy/io/tests/test_mmio.py +7 -1
- scipy/io/tests/test_wavfile.py +41 -0
- scipy/io/wavfile.py +57 -10
- scipy/linalg/_basic.py +113 -86
- scipy/linalg/_cythonized_array_utils.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_cythonized_array_utils.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_decomp.py +22 -9
- scipy/linalg/_decomp_cholesky.py +28 -13
- scipy/linalg/_decomp_cossin.py +45 -30
- scipy/linalg/_decomp_interpolative.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_interpolative.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_decomp_ldl.py +4 -1
- scipy/linalg/_decomp_lu.py +18 -6
- scipy/linalg/_decomp_lu_cython.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_lu_cython.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_decomp_polar.py +2 -0
- scipy/linalg/_decomp_qr.py +6 -2
- scipy/linalg/_decomp_qz.py +3 -0
- scipy/linalg/_decomp_schur.py +3 -1
- scipy/linalg/_decomp_svd.py +13 -2
- scipy/linalg/_decomp_update.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_decomp_update.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_expm_frechet.py +4 -0
- scipy/linalg/_fblas.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_fblas.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_flapack.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_flapack.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_linalg_pythran.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_linalg_pythran.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs.py +187 -4
- scipy/linalg/_matfuncs_expm.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_expm.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +1 -99
- scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_matfuncs_sqrtm_triu.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_procrustes.py +2 -0
- scipy/linalg/_sketches.py +17 -6
- scipy/linalg/_solve_toeplitz.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/_solve_toeplitz.cp311-win_amd64.pyd +0 -0
- scipy/linalg/_solvers.py +7 -2
- scipy/linalg/_special_matrices.py +26 -36
- scipy/linalg/cython_blas.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/cython_blas.cp311-win_amd64.pyd +0 -0
- scipy/linalg/cython_lapack.cp311-win_amd64.dll.a +0 -0
- scipy/linalg/cython_lapack.cp311-win_amd64.pyd +0 -0
- scipy/linalg/lapack.py +22 -2
- scipy/linalg/tests/_cython_examples/meson.build +7 -0
- scipy/linalg/tests/test_basic.py +31 -16
- scipy/linalg/tests/test_batch.py +588 -0
- scipy/linalg/tests/test_cythonized_array_utils.py +0 -2
- scipy/linalg/tests/test_decomp.py +40 -3
- scipy/linalg/tests/test_decomp_cossin.py +14 -0
- scipy/linalg/tests/test_decomp_ldl.py +1 -1
- scipy/linalg/tests/test_lapack.py +115 -7
- scipy/linalg/tests/test_matfuncs.py +157 -102
- scipy/linalg/tests/test_procrustes.py +0 -7
- scipy/linalg/tests/test_solve_toeplitz.py +1 -1
- scipy/linalg/tests/test_special_matrices.py +1 -5
- scipy/ndimage/__init__.py +1 -0
- scipy/ndimage/_ctest.cp311-win_amd64.dll.a +0 -0
- scipy/ndimage/_ctest.cp311-win_amd64.pyd +0 -0
- scipy/ndimage/_cytest.cp311-win_amd64.dll.a +0 -0
- scipy/ndimage/_cytest.cp311-win_amd64.pyd +0 -0
- scipy/ndimage/_delegators.py +8 -2
- scipy/ndimage/_filters.py +453 -5
- scipy/ndimage/_interpolation.py +36 -6
- scipy/ndimage/_measurements.py +4 -2
- scipy/ndimage/_morphology.py +5 -0
- scipy/ndimage/_nd_image.cp311-win_amd64.dll.a +0 -0
- scipy/ndimage/_nd_image.cp311-win_amd64.pyd +0 -0
- scipy/ndimage/_ni_docstrings.py +5 -1
- scipy/ndimage/_ni_label.cp311-win_amd64.dll.a +0 -0
- scipy/ndimage/_ni_label.cp311-win_amd64.pyd +0 -0
- scipy/ndimage/_ni_support.py +1 -5
- scipy/ndimage/_rank_filter_1d.cp311-win_amd64.dll.a +0 -0
- scipy/ndimage/_rank_filter_1d.cp311-win_amd64.pyd +0 -0
- scipy/ndimage/_support_alternative_backends.py +18 -6
- scipy/ndimage/tests/test_filters.py +370 -259
- scipy/ndimage/tests/test_fourier.py +7 -9
- scipy/ndimage/tests/test_interpolation.py +68 -61
- scipy/ndimage/tests/test_measurements.py +18 -35
- scipy/ndimage/tests/test_morphology.py +143 -131
- scipy/ndimage/tests/test_splines.py +1 -3
- scipy/odr/__odrpack.cp311-win_amd64.dll.a +0 -0
- scipy/odr/__odrpack.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_basinhopping.py +13 -7
- scipy/optimize/_bglu_dense.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_bglu_dense.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_bracket.py +17 -24
- scipy/optimize/_chandrupatla.py +9 -10
- scipy/optimize/_cobyla_py.py +104 -123
- scipy/optimize/_constraints.py +14 -10
- scipy/optimize/_differentiable_functions.py +371 -230
- scipy/optimize/_differentialevolution.py +4 -3
- scipy/optimize/_direct.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_direct.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_dual_annealing.py +1 -1
- scipy/optimize/_elementwise.py +1 -4
- scipy/optimize/_group_columns.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_group_columns.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_highspy/_core.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_highspy/_core.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_highspy/_highs_options.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_highspy/_highs_options.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_lbfgsb.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_lbfgsb.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_lbfgsb_py.py +57 -16
- scipy/optimize/_linprog_doc.py +2 -2
- scipy/optimize/_linprog_highs.py +2 -2
- scipy/optimize/_linprog_ip.py +25 -10
- scipy/optimize/_linprog_util.py +14 -16
- scipy/optimize/_lsap.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_lsap.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_lsq/common.py +3 -3
- scipy/optimize/_lsq/dogbox.py +16 -2
- scipy/optimize/_lsq/givens_elimination.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_lsq/givens_elimination.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_lsq/least_squares.py +198 -126
- scipy/optimize/_lsq/lsq_linear.py +6 -6
- scipy/optimize/_lsq/trf.py +35 -8
- scipy/optimize/_milp.py +3 -1
- scipy/optimize/_minimize.py +105 -36
- scipy/optimize/_minpack.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_minpack.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_minpack_py.py +21 -14
- scipy/optimize/_moduleTNC.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_moduleTNC.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_nnls.py +20 -21
- scipy/optimize/_nonlin.py +34 -3
- scipy/optimize/_numdiff.py +288 -110
- scipy/optimize/_optimize.py +86 -48
- scipy/optimize/_pava_pybind.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_pava_pybind.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_remove_redundancy.py +5 -5
- scipy/optimize/_root_scalar.py +1 -1
- scipy/optimize/_shgo.py +6 -0
- scipy/optimize/_shgo_lib/_complex.py +1 -1
- scipy/optimize/_slsqp_py.py +216 -124
- scipy/optimize/_slsqplib.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_slsqplib.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_spectral.py +1 -1
- scipy/optimize/_tnc.py +8 -1
- scipy/optimize/_trlib/_trlib.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_trlib/_trlib.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_trustregion.py +20 -6
- scipy/optimize/_trustregion_constr/canonical_constraint.py +7 -7
- scipy/optimize/_trustregion_constr/equality_constrained_sqp.py +1 -1
- scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py +11 -3
- scipy/optimize/_trustregion_constr/projections.py +12 -8
- scipy/optimize/_trustregion_constr/qp_subproblem.py +9 -9
- scipy/optimize/_trustregion_constr/tests/test_projections.py +7 -7
- scipy/optimize/_trustregion_constr/tests/test_qp_subproblem.py +77 -77
- scipy/optimize/_trustregion_constr/tr_interior_point.py +5 -5
- scipy/optimize/_trustregion_exact.py +0 -1
- scipy/optimize/_zeros.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_zeros.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_zeros_py.py +97 -17
- scipy/optimize/cython_optimize/_zeros.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/cython_optimize/_zeros.cp311-win_amd64.pyd +0 -0
- scipy/optimize/slsqp.py +0 -1
- scipy/optimize/tests/test__basinhopping.py +1 -1
- scipy/optimize/tests/test__differential_evolution.py +4 -4
- scipy/optimize/tests/test__linprog_clean_inputs.py +5 -3
- scipy/optimize/tests/test__numdiff.py +66 -22
- scipy/optimize/tests/test__remove_redundancy.py +2 -2
- scipy/optimize/tests/test__shgo.py +9 -1
- scipy/optimize/tests/test_bracket.py +36 -46
- scipy/optimize/tests/test_chandrupatla.py +133 -135
- scipy/optimize/tests/test_cobyla.py +74 -45
- scipy/optimize/tests/test_constraints.py +1 -1
- scipy/optimize/tests/test_differentiable_functions.py +226 -6
- scipy/optimize/tests/test_lbfgsb_hessinv.py +22 -0
- scipy/optimize/tests/test_least_squares.py +125 -13
- scipy/optimize/tests/test_linear_assignment.py +3 -3
- scipy/optimize/tests/test_linprog.py +3 -3
- scipy/optimize/tests/test_lsq_linear.py +6 -6
- scipy/optimize/tests/test_minimize_constrained.py +2 -2
- scipy/optimize/tests/test_minpack.py +4 -4
- scipy/optimize/tests/test_nnls.py +43 -3
- scipy/optimize/tests/test_nonlin.py +36 -0
- scipy/optimize/tests/test_optimize.py +95 -17
- scipy/optimize/tests/test_slsqp.py +36 -4
- scipy/optimize/tests/test_zeros.py +34 -1
- scipy/signal/__init__.py +12 -23
- scipy/signal/_delegators.py +568 -0
- scipy/signal/_filter_design.py +459 -241
- scipy/signal/_fir_filter_design.py +262 -90
- scipy/signal/_lti_conversion.py +3 -2
- scipy/signal/_ltisys.py +118 -91
- scipy/signal/_max_len_seq_inner.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_max_len_seq_inner.cp311-win_amd64.pyd +0 -0
- scipy/signal/_peak_finding_utils.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_peak_finding_utils.cp311-win_amd64.pyd +0 -0
- scipy/signal/_polyutils.py +172 -0
- scipy/signal/_short_time_fft.py +519 -70
- scipy/signal/_signal_api.py +30 -0
- scipy/signal/_signaltools.py +719 -399
- scipy/signal/_sigtools.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_sigtools.cp311-win_amd64.pyd +0 -0
- scipy/signal/_sosfilt.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_sosfilt.cp311-win_amd64.pyd +0 -0
- scipy/signal/_spectral_py.py +230 -50
- scipy/signal/_spline.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_spline.cp311-win_amd64.pyd +0 -0
- scipy/signal/_spline_filters.py +108 -68
- scipy/signal/_support_alternative_backends.py +73 -0
- scipy/signal/_upfirdn.py +4 -1
- scipy/signal/_upfirdn_apply.cp311-win_amd64.dll.a +0 -0
- scipy/signal/_upfirdn_apply.cp311-win_amd64.pyd +0 -0
- scipy/signal/_waveforms.py +2 -11
- scipy/signal/_wavelets.py +1 -1
- scipy/signal/fir_filter_design.py +1 -0
- scipy/signal/spline.py +4 -11
- scipy/signal/tests/_scipy_spectral_test_shim.py +2 -171
- scipy/signal/tests/test_bsplines.py +114 -79
- scipy/signal/tests/test_cont2discrete.py +9 -2
- scipy/signal/tests/test_filter_design.py +721 -481
- scipy/signal/tests/test_fir_filter_design.py +332 -140
- scipy/signal/tests/test_savitzky_golay.py +4 -3
- scipy/signal/tests/test_short_time_fft.py +221 -3
- scipy/signal/tests/test_signaltools.py +2144 -1348
- scipy/signal/tests/test_spectral.py +50 -6
- scipy/signal/tests/test_splines.py +161 -96
- scipy/signal/tests/test_upfirdn.py +84 -50
- scipy/signal/tests/test_waveforms.py +20 -0
- scipy/signal/tests/test_windows.py +607 -466
- scipy/signal/windows/_windows.py +287 -148
- scipy/sparse/__init__.py +23 -4
- scipy/sparse/_base.py +270 -108
- scipy/sparse/_bsr.py +7 -4
- scipy/sparse/_compressed.py +59 -231
- scipy/sparse/_construct.py +90 -38
- scipy/sparse/_coo.py +115 -181
- scipy/sparse/_csc.py +4 -4
- scipy/sparse/_csparsetools.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/_csparsetools.cp311-win_amd64.pyd +0 -0
- scipy/sparse/_csr.py +2 -2
- scipy/sparse/_data.py +48 -48
- scipy/sparse/_dia.py +105 -18
- scipy/sparse/_dok.py +0 -23
- scipy/sparse/_index.py +4 -4
- scipy/sparse/_matrix.py +23 -0
- scipy/sparse/_sparsetools.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/_sparsetools.cp311-win_amd64.pyd +0 -0
- scipy/sparse/_sputils.py +37 -22
- scipy/sparse/base.py +0 -9
- scipy/sparse/bsr.py +0 -14
- scipy/sparse/compressed.py +0 -23
- scipy/sparse/construct.py +0 -6
- scipy/sparse/coo.py +0 -14
- scipy/sparse/csc.py +0 -3
- scipy/sparse/csgraph/_flow.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_flow.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_matching.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_matching.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_reordering.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_reordering.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_shortest_path.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_shortest_path.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_tools.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_tools.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/_traversal.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/csgraph/_traversal.cp311-win_amd64.pyd +0 -0
- scipy/sparse/csgraph/tests/test_matching.py +14 -2
- scipy/sparse/csgraph/tests/test_pydata_sparse.py +4 -1
- scipy/sparse/csgraph/tests/test_shortest_path.py +83 -27
- scipy/sparse/csr.py +0 -5
- scipy/sparse/data.py +1 -6
- scipy/sparse/dia.py +0 -7
- scipy/sparse/dok.py +0 -10
- scipy/sparse/linalg/_dsolve/_superlu.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_dsolve/_superlu.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_dsolve/linsolve.py +9 -0
- scipy/sparse/linalg/_dsolve/tests/test_linsolve.py +35 -28
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_eigen/arpack/_arpack.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_eigen/arpack/arpack.py +23 -17
- scipy/sparse/linalg/_eigen/lobpcg/lobpcg.py +6 -6
- scipy/sparse/linalg/_interface.py +17 -18
- scipy/sparse/linalg/_isolve/_gcrotmk.py +4 -4
- scipy/sparse/linalg/_isolve/iterative.py +51 -45
- scipy/sparse/linalg/_isolve/lgmres.py +6 -6
- scipy/sparse/linalg/_isolve/minres.py +5 -5
- scipy/sparse/linalg/_isolve/tfqmr.py +7 -7
- scipy/sparse/linalg/_isolve/utils.py +2 -8
- scipy/sparse/linalg/_matfuncs.py +1 -1
- scipy/sparse/linalg/_norm.py +1 -1
- scipy/sparse/linalg/_propack/_cpropack.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_cpropack.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_spropack.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp311-win_amd64.dll.a +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cp311-win_amd64.pyd +0 -0
- scipy/sparse/linalg/_special_sparse_arrays.py +39 -38
- scipy/sparse/linalg/tests/test_pydata_sparse.py +14 -0
- scipy/sparse/tests/test_arithmetic1d.py +5 -2
- scipy/sparse/tests/test_base.py +214 -42
- scipy/sparse/tests/test_common1d.py +7 -7
- scipy/sparse/tests/test_construct.py +1 -1
- scipy/sparse/tests/test_coo.py +272 -4
- scipy/sparse/tests/test_sparsetools.py +5 -0
- scipy/sparse/tests/test_sputils.py +36 -7
- scipy/spatial/_ckdtree.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_ckdtree.cp311-win_amd64.pyd +0 -0
- scipy/spatial/_distance_pybind.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_distance_pybind.cp311-win_amd64.pyd +0 -0
- scipy/spatial/_distance_wrap.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_distance_wrap.cp311-win_amd64.pyd +0 -0
- scipy/spatial/_hausdorff.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_hausdorff.cp311-win_amd64.pyd +0 -0
- scipy/spatial/_qhull.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_qhull.cp311-win_amd64.pyd +0 -0
- scipy/spatial/_voronoi.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/_voronoi.cp311-win_amd64.pyd +0 -0
- scipy/spatial/distance.py +49 -42
- scipy/spatial/tests/test_distance.py +15 -1
- scipy/spatial/tests/test_kdtree.py +1 -0
- scipy/spatial/tests/test_qhull.py +7 -2
- scipy/spatial/transform/__init__.py +5 -3
- scipy/spatial/transform/_rigid_transform.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/transform/_rigid_transform.cp311-win_amd64.pyd +0 -0
- scipy/spatial/transform/_rotation.cp311-win_amd64.dll.a +0 -0
- scipy/spatial/transform/_rotation.cp311-win_amd64.pyd +0 -0
- scipy/spatial/transform/tests/test_rigid_transform.py +1221 -0
- scipy/spatial/transform/tests/test_rotation.py +1213 -832
- scipy/spatial/transform/tests/test_rotation_groups.py +3 -3
- scipy/spatial/transform/tests/test_rotation_spline.py +29 -8
- scipy/special/__init__.py +1 -47
- scipy/special/_add_newdocs.py +34 -772
- scipy/special/_basic.py +22 -25
- scipy/special/_comb.cp311-win_amd64.dll.a +0 -0
- scipy/special/_comb.cp311-win_amd64.pyd +0 -0
- scipy/special/_ellip_harm_2.cp311-win_amd64.dll.a +0 -0
- scipy/special/_ellip_harm_2.cp311-win_amd64.pyd +0 -0
- scipy/special/_gufuncs.cp311-win_amd64.dll.a +0 -0
- scipy/special/_gufuncs.cp311-win_amd64.pyd +0 -0
- scipy/special/_logsumexp.py +67 -58
- scipy/special/_orthogonal.pyi +1 -1
- scipy/special/_specfun.cp311-win_amd64.dll.a +0 -0
- scipy/special/_specfun.cp311-win_amd64.pyd +0 -0
- scipy/special/_special_ufuncs.cp311-win_amd64.dll.a +0 -0
- scipy/special/_special_ufuncs.cp311-win_amd64.pyd +0 -0
- scipy/special/_spherical_bessel.py +4 -4
- scipy/special/_support_alternative_backends.py +212 -119
- scipy/special/_test_internal.cp311-win_amd64.dll.a +0 -0
- scipy/special/_test_internal.cp311-win_amd64.pyd +0 -0
- scipy/special/_testutils.py +4 -4
- scipy/special/_ufuncs.cp311-win_amd64.dll.a +0 -0
- scipy/special/_ufuncs.cp311-win_amd64.pyd +0 -0
- scipy/special/_ufuncs.pyi +1 -0
- scipy/special/_ufuncs.pyx +215 -1400
- scipy/special/_ufuncs_cxx.cp311-win_amd64.dll.a +0 -0
- scipy/special/_ufuncs_cxx.cp311-win_amd64.pyd +0 -0
- scipy/special/_ufuncs_cxx.pxd +2 -15
- scipy/special/_ufuncs_cxx.pyx +5 -44
- scipy/special/_ufuncs_cxx_defs.h +2 -16
- scipy/special/_ufuncs_defs.h +0 -8
- scipy/special/cython_special.cp311-win_amd64.dll.a +0 -0
- scipy/special/cython_special.cp311-win_amd64.pyd +0 -0
- scipy/special/cython_special.pxd +1 -1
- scipy/special/tests/_cython_examples/meson.build +10 -1
- scipy/special/tests/test_basic.py +153 -20
- scipy/special/tests/test_boost_ufuncs.py +3 -0
- scipy/special/tests/test_cdflib.py +35 -11
- scipy/special/tests/test_gammainc.py +16 -0
- scipy/special/tests/test_hyp2f1.py +2 -2
- scipy/special/tests/test_log1mexp.py +85 -0
- scipy/special/tests/test_logsumexp.py +206 -64
- scipy/special/tests/test_mpmath.py +1 -0
- scipy/special/tests/test_nan_inputs.py +1 -1
- scipy/special/tests/test_orthogonal.py +17 -18
- scipy/special/tests/test_sf_error.py +3 -2
- scipy/special/tests/test_sph_harm.py +6 -7
- scipy/special/tests/test_support_alternative_backends.py +211 -76
- scipy/stats/__init__.py +4 -1
- scipy/stats/_ansari_swilk_statistics.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_ansari_swilk_statistics.cp311-win_amd64.pyd +0 -0
- scipy/stats/_axis_nan_policy.py +5 -12
- scipy/stats/_biasedurn.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_biasedurn.cp311-win_amd64.pyd +0 -0
- scipy/stats/_continued_fraction.py +387 -0
- scipy/stats/_continuous_distns.py +277 -310
- scipy/stats/_correlation.py +1 -1
- scipy/stats/_covariance.py +6 -3
- scipy/stats/_discrete_distns.py +39 -32
- scipy/stats/_distn_infrastructure.py +39 -12
- scipy/stats/_distribution_infrastructure.py +900 -238
- scipy/stats/_entropy.py +9 -10
- scipy/{_lib → stats}/_finite_differences.py +1 -1
- scipy/stats/_hypotests.py +83 -50
- scipy/stats/_kde.py +53 -49
- scipy/stats/_ksstats.py +1 -1
- scipy/stats/_levy_stable/__init__.py +7 -15
- scipy/stats/_levy_stable/levyst.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_levy_stable/levyst.cp311-win_amd64.pyd +0 -0
- scipy/stats/_morestats.py +118 -73
- scipy/stats/_mstats_basic.py +13 -17
- scipy/stats/_mstats_extras.py +8 -8
- scipy/stats/_multivariate.py +89 -113
- scipy/stats/_new_distributions.py +97 -20
- scipy/stats/_page_trend_test.py +12 -5
- scipy/stats/_probability_distribution.py +265 -43
- scipy/stats/_qmc.py +14 -9
- scipy/stats/_qmc_cy.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_qmc_cy.cp311-win_amd64.pyd +0 -0
- scipy/stats/_qmvnt.py +16 -95
- scipy/stats/_qmvnt_cy.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_qmvnt_cy.cp311-win_amd64.pyd +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/rcont.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_rcont/rcont.cp311-win_amd64.pyd +0 -0
- scipy/stats/_resampling.py +4 -29
- scipy/stats/_sampling.py +1 -1
- scipy/stats/_sobol.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_sobol.cp311-win_amd64.pyd +0 -0
- scipy/stats/_stats.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_stats.cp311-win_amd64.pyd +0 -0
- scipy/stats/_stats_mstats_common.py +21 -2
- scipy/stats/_stats_py.py +550 -476
- scipy/stats/_stats_pythran.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_stats_pythran.cp311-win_amd64.pyd +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_unuran/unuran_wrapper.cp311-win_amd64.pyd +0 -0
- scipy/stats/_unuran/unuran_wrapper.pyi +2 -1
- scipy/stats/_variation.py +6 -8
- scipy/stats/_wilcoxon.py +13 -7
- scipy/stats/tests/common_tests.py +6 -4
- scipy/stats/tests/test_axis_nan_policy.py +62 -24
- scipy/stats/tests/test_continued_fraction.py +173 -0
- scipy/stats/tests/test_continuous.py +379 -60
- scipy/stats/tests/test_continuous_basic.py +18 -12
- scipy/stats/tests/test_discrete_basic.py +14 -8
- scipy/stats/tests/test_discrete_distns.py +16 -16
- scipy/stats/tests/test_distributions.py +95 -75
- scipy/stats/tests/test_entropy.py +40 -48
- scipy/stats/tests/test_fit.py +4 -3
- scipy/stats/tests/test_hypotests.py +153 -24
- scipy/stats/tests/test_kdeoth.py +109 -41
- scipy/stats/tests/test_marray.py +289 -0
- scipy/stats/tests/test_morestats.py +79 -47
- scipy/stats/tests/test_mstats_basic.py +3 -3
- scipy/stats/tests/test_multivariate.py +434 -83
- scipy/stats/tests/test_qmc.py +13 -10
- scipy/stats/tests/test_quantile.py +199 -0
- scipy/stats/tests/test_rank.py +119 -112
- scipy/stats/tests/test_resampling.py +47 -56
- scipy/stats/tests/test_sampling.py +9 -4
- scipy/stats/tests/test_stats.py +799 -939
- scipy/stats/tests/test_variation.py +8 -6
- scipy/version.py +2 -2
- scipy-1.16.0rc2.dist-info/DELVEWHEEL +2 -0
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/LICENSE.txt +4 -4
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/METADATA +11 -11
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/RECORD +685 -693
- scipy/_lib/array_api_extra/_funcs.py +0 -484
- scipy/_lib/array_api_extra/_typing.py +0 -8
- scipy/interpolate/_bspl.cp311-win_amd64.dll.a +0 -0
- scipy/interpolate/_bspl.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_cobyla.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_cobyla.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_cython_nnls.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_cython_nnls.cp311-win_amd64.pyd +0 -0
- scipy/optimize/_slsqp.cp311-win_amd64.dll.a +0 -0
- scipy/optimize/_slsqp.cp311-win_amd64.pyd +0 -0
- scipy/spatial/qhull_src/COPYING.txt +0 -38
- scipy/special/libsf_error_state.dll +0 -0
- scipy/special/libsf_error_state.dll.a +0 -0
- scipy/special/tests/test_log_softmax.py +0 -109
- scipy/special/tests/test_xsf_cuda.py +0 -114
- scipy/special/xsf/binom.h +0 -89
- scipy/special/xsf/cdflib.h +0 -100
- scipy/special/xsf/cephes/airy.h +0 -307
- scipy/special/xsf/cephes/besselpoly.h +0 -51
- scipy/special/xsf/cephes/beta.h +0 -257
- scipy/special/xsf/cephes/cbrt.h +0 -131
- scipy/special/xsf/cephes/chbevl.h +0 -85
- scipy/special/xsf/cephes/chdtr.h +0 -193
- scipy/special/xsf/cephes/const.h +0 -87
- scipy/special/xsf/cephes/ellie.h +0 -293
- scipy/special/xsf/cephes/ellik.h +0 -251
- scipy/special/xsf/cephes/ellpe.h +0 -107
- scipy/special/xsf/cephes/ellpk.h +0 -117
- scipy/special/xsf/cephes/expn.h +0 -260
- scipy/special/xsf/cephes/gamma.h +0 -398
- scipy/special/xsf/cephes/hyp2f1.h +0 -596
- scipy/special/xsf/cephes/hyperg.h +0 -361
- scipy/special/xsf/cephes/i0.h +0 -149
- scipy/special/xsf/cephes/i1.h +0 -158
- scipy/special/xsf/cephes/igam.h +0 -421
- scipy/special/xsf/cephes/igam_asymp_coeff.h +0 -195
- scipy/special/xsf/cephes/igami.h +0 -313
- scipy/special/xsf/cephes/j0.h +0 -225
- scipy/special/xsf/cephes/j1.h +0 -198
- scipy/special/xsf/cephes/jv.h +0 -715
- scipy/special/xsf/cephes/k0.h +0 -164
- scipy/special/xsf/cephes/k1.h +0 -163
- scipy/special/xsf/cephes/kn.h +0 -243
- scipy/special/xsf/cephes/lanczos.h +0 -112
- scipy/special/xsf/cephes/ndtr.h +0 -275
- scipy/special/xsf/cephes/poch.h +0 -85
- scipy/special/xsf/cephes/polevl.h +0 -167
- scipy/special/xsf/cephes/psi.h +0 -194
- scipy/special/xsf/cephes/rgamma.h +0 -111
- scipy/special/xsf/cephes/scipy_iv.h +0 -811
- scipy/special/xsf/cephes/shichi.h +0 -248
- scipy/special/xsf/cephes/sici.h +0 -224
- scipy/special/xsf/cephes/sindg.h +0 -221
- scipy/special/xsf/cephes/tandg.h +0 -139
- scipy/special/xsf/cephes/trig.h +0 -58
- scipy/special/xsf/cephes/unity.h +0 -186
- scipy/special/xsf/cephes/zeta.h +0 -172
- scipy/special/xsf/config.h +0 -304
- scipy/special/xsf/digamma.h +0 -205
- scipy/special/xsf/error.h +0 -57
- scipy/special/xsf/evalpoly.h +0 -47
- scipy/special/xsf/expint.h +0 -266
- scipy/special/xsf/hyp2f1.h +0 -694
- scipy/special/xsf/iv_ratio.h +0 -173
- scipy/special/xsf/lambertw.h +0 -150
- scipy/special/xsf/loggamma.h +0 -163
- scipy/special/xsf/sici.h +0 -200
- scipy/special/xsf/tools.h +0 -427
- scipy/special/xsf/trig.h +0 -164
- scipy/special/xsf/wright_bessel.h +0 -843
- scipy/special/xsf/zlog1.h +0 -35
- scipy/stats/_mvn.cp311-win_amd64.dll.a +0 -0
- scipy/stats/_mvn.cp311-win_amd64.pyd +0 -0
- scipy-1.15.3.dist-info/DELVEWHEEL +0 -2
- /scipy-1.15.3-cp311-cp311-win_amd64.whl → /scipy-1.16.0rc2-cp311-cp311-win_amd64.whl +0 -0
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
@@ -1,91 +1,119 @@
|
|
1
|
+
from collections import namedtuple
|
2
|
+
|
1
3
|
import numpy as np
|
2
4
|
import scipy.sparse as sps
|
3
5
|
from ._numdiff import approx_derivative, group_columns
|
4
6
|
from ._hessian_update_strategy import HessianUpdateStrategy
|
5
7
|
from scipy.sparse.linalg import LinearOperator
|
6
|
-
from scipy._lib._array_api import array_namespace
|
8
|
+
from scipy._lib._array_api import array_namespace, xp_copy
|
7
9
|
from scipy._lib import array_api_extra as xpx
|
10
|
+
from scipy._lib._util import _ScalarFunctionWrapper
|
8
11
|
|
9
12
|
|
10
13
|
FD_METHODS = ('2-point', '3-point', 'cs')
|
11
14
|
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
class _ScalarGradWrapper:
|
17
|
+
"""
|
18
|
+
Wrapper class for gradient calculation
|
19
|
+
"""
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
grad,
|
23
|
+
fun=None,
|
24
|
+
args=None,
|
25
|
+
finite_diff_options=None,
|
26
|
+
):
|
27
|
+
self.fun = fun
|
28
|
+
self.grad = grad
|
29
|
+
self.args = [] if args is None else args
|
30
|
+
self.finite_diff_options = finite_diff_options
|
31
|
+
self.ngev = 0
|
32
|
+
# number of function evaluations consumed by finite difference
|
33
|
+
self.nfev = 0
|
15
34
|
|
16
|
-
def
|
17
|
-
ncalls[0] += 1
|
35
|
+
def __call__(self, x, f0=None, **kwds):
|
18
36
|
# Send a copy because the user may overwrite it.
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"The user-provided objective function "
|
29
|
-
"must return a scalar value."
|
30
|
-
) from e
|
31
|
-
return fx
|
32
|
-
return wrapped, ncalls
|
33
|
-
|
34
|
-
|
35
|
-
def _wrapper_grad(grad, fun=None, args=(), finite_diff_options=None):
|
36
|
-
ncalls = [0]
|
37
|
-
|
38
|
-
if callable(grad):
|
39
|
-
def wrapped(x, **kwds):
|
40
|
-
# kwds present to give function same signature as numdiff variant
|
41
|
-
ncalls[0] += 1
|
42
|
-
return np.atleast_1d(grad(np.copy(x), *args))
|
43
|
-
return wrapped, ncalls
|
44
|
-
|
45
|
-
elif grad in FD_METHODS:
|
46
|
-
def wrapped1(x, f0=None):
|
47
|
-
ncalls[0] += 1
|
48
|
-
return approx_derivative(
|
49
|
-
fun, x, f0=f0, **finite_diff_options
|
37
|
+
# The user of this class might want `x` to remain unchanged.
|
38
|
+
if callable(self.grad):
|
39
|
+
g = np.atleast_1d(self.grad(np.copy(x), *self.args))
|
40
|
+
elif self.grad in FD_METHODS:
|
41
|
+
g, dct = approx_derivative(
|
42
|
+
self.fun,
|
43
|
+
x,
|
44
|
+
f0=f0,
|
45
|
+
**self.finite_diff_options,
|
50
46
|
)
|
47
|
+
self.nfev += dct['nfev']
|
51
48
|
|
52
|
-
|
49
|
+
self.ngev += 1
|
50
|
+
return g
|
53
51
|
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
class _ScalarHessWrapper:
|
54
|
+
"""
|
55
|
+
Wrapper class for hess calculation via finite differences
|
56
|
+
"""
|
57
|
+
def __init__(
|
58
|
+
self,
|
59
|
+
hess,
|
60
|
+
x0=None,
|
61
|
+
grad=None,
|
62
|
+
args=None,
|
63
|
+
finite_diff_options=None,
|
64
|
+
):
|
65
|
+
self.hess = hess
|
66
|
+
self.grad = grad
|
67
|
+
self.args = [] if args is None else args
|
68
|
+
self.finite_diff_options = finite_diff_options
|
69
|
+
# keep track of any finite difference function evaluations for grad
|
70
|
+
self.ngev = 0
|
71
|
+
self.nhev = 0
|
72
|
+
self.H = None
|
73
|
+
self._hess_func = None
|
64
74
|
|
65
|
-
|
75
|
+
if callable(hess):
|
76
|
+
self.H = hess(np.copy(x0), *args)
|
77
|
+
self.nhev += 1
|
66
78
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
79
|
+
if sps.issparse(self.H):
|
80
|
+
self._hess_func = self._sparse_callable
|
81
|
+
self.H = sps.csr_array(self.H)
|
82
|
+
elif isinstance(self.H, LinearOperator):
|
83
|
+
self._hess_func = self._linearoperator_callable
|
84
|
+
else:
|
85
|
+
# dense
|
86
|
+
self._hess_func = self._dense_callable
|
87
|
+
self.H = np.atleast_2d(np.asarray(self.H))
|
88
|
+
elif hess in FD_METHODS:
|
89
|
+
self._hess_func = self._fd_hess
|
71
90
|
|
72
|
-
|
73
|
-
|
74
|
-
ncalls[0] += 1
|
75
|
-
return np.atleast_2d(np.asarray(hess(np.copy(x), *args)))
|
91
|
+
def __call__(self, x, f0=None, **kwds):
|
92
|
+
return self._hess_func(np.copy(x), f0=f0)
|
76
93
|
|
77
|
-
|
94
|
+
def _fd_hess(self, x, f0=None, **kwds):
|
95
|
+
self.H, dct = approx_derivative(
|
96
|
+
self.grad, x, f0=f0, **self.finite_diff_options
|
97
|
+
)
|
98
|
+
self.ngev += dct["nfev"]
|
99
|
+
return self.H
|
78
100
|
|
79
|
-
|
80
|
-
|
81
|
-
|
101
|
+
def _sparse_callable(self, x, **kwds):
|
102
|
+
self.nhev += 1
|
103
|
+
self.H = sps.csr_array(self.hess(x, *self.args))
|
104
|
+
return self.H
|
82
105
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
)
|
106
|
+
def _dense_callable(self, x, **kwds):
|
107
|
+
self.nhev += 1
|
108
|
+
self.H = np.atleast_2d(
|
109
|
+
np.asarray(self.hess(x, *self.args))
|
110
|
+
)
|
111
|
+
return self.H
|
87
112
|
|
88
|
-
|
113
|
+
def _linearoperator_callable(self, x, **kwds):
|
114
|
+
self.nhev += 1
|
115
|
+
self.H = self.hess(x, *self.args)
|
116
|
+
return self.H
|
89
117
|
|
90
118
|
|
91
119
|
class ScalarFunction:
|
@@ -151,6 +179,21 @@ class ScalarFunction:
|
|
151
179
|
For ``method='3-point'`` the sign of `epsilon` is ignored. By default
|
152
180
|
relative steps are used, only if ``epsilon is not None`` are absolute
|
153
181
|
steps used.
|
182
|
+
workers : map-like callable, optional
|
183
|
+
A map-like callable, such as `multiprocessing.Pool.map` for evaluating
|
184
|
+
any numerical differentiation in parallel.
|
185
|
+
This evaluation is carried out as ``workers(fun, iterable)``, or
|
186
|
+
``workers(grad, iterable)``, depending on what is being numerically
|
187
|
+
differentiated.
|
188
|
+
Alternatively, if `workers` is an int the task is subdivided into `workers`
|
189
|
+
sections and the function evaluated in parallel
|
190
|
+
(uses `multiprocessing.Pool <multiprocessing>`).
|
191
|
+
Supply -1 to use all available CPU cores.
|
192
|
+
It is recommended that a map-like be used instead of int, as repeated
|
193
|
+
calls to `approx_derivative` will incur large overhead from setting up
|
194
|
+
new processes.
|
195
|
+
|
196
|
+
.. versionadded:: 1.16.0
|
154
197
|
|
155
198
|
Notes
|
156
199
|
-----
|
@@ -163,8 +206,9 @@ class ScalarFunction:
|
|
163
206
|
will be set. However, a subsequent call with a different argument
|
164
207
|
of *any* of the methods may overwrite the attribute.
|
165
208
|
"""
|
166
|
-
def __init__(self, fun, x0, args, grad, hess, finite_diff_rel_step,
|
167
|
-
finite_diff_bounds, epsilon=None):
|
209
|
+
def __init__(self, fun, x0, args, grad, hess, finite_diff_rel_step=None,
|
210
|
+
finite_diff_bounds=(-np.inf, np.inf), epsilon=None, workers=None):
|
211
|
+
|
168
212
|
if not callable(grad) and grad not in FD_METHODS:
|
169
213
|
raise ValueError(
|
170
214
|
f"`grad` must be either callable or one of {FD_METHODS}."
|
@@ -182,7 +226,6 @@ class ScalarFunction:
|
|
182
226
|
"finite-differences, we require the Hessian "
|
183
227
|
"to be estimated using one of the "
|
184
228
|
"quasi-Newton strategies.")
|
185
|
-
|
186
229
|
self.xp = xp = array_namespace(x0)
|
187
230
|
_x = xpx.atleast_nd(xp.asarray(x0), ndim=1, xp=xp)
|
188
231
|
_dtype = xp.float64
|
@@ -190,7 +233,7 @@ class ScalarFunction:
|
|
190
233
|
_dtype = _x.dtype
|
191
234
|
|
192
235
|
# original arguments
|
193
|
-
self._wrapped_fun
|
236
|
+
self._wrapped_fun = _ScalarFunctionWrapper(fun, args)
|
194
237
|
self._orig_fun = fun
|
195
238
|
self._orig_grad = grad
|
196
239
|
self._orig_hess = hess
|
@@ -207,65 +250,80 @@ class ScalarFunction:
|
|
207
250
|
self._lowest_x = None
|
208
251
|
self._lowest_f = np.inf
|
209
252
|
|
253
|
+
# normalize workers
|
254
|
+
workers = workers or map
|
255
|
+
|
210
256
|
finite_diff_options = {}
|
211
257
|
if grad in FD_METHODS:
|
212
258
|
finite_diff_options["method"] = grad
|
213
259
|
finite_diff_options["rel_step"] = finite_diff_rel_step
|
214
260
|
finite_diff_options["abs_step"] = epsilon
|
215
261
|
finite_diff_options["bounds"] = finite_diff_bounds
|
262
|
+
finite_diff_options["workers"] = workers
|
263
|
+
finite_diff_options["full_output"] = True
|
216
264
|
if hess in FD_METHODS:
|
217
265
|
finite_diff_options["method"] = hess
|
218
266
|
finite_diff_options["rel_step"] = finite_diff_rel_step
|
219
267
|
finite_diff_options["abs_step"] = epsilon
|
220
268
|
finite_diff_options["as_linear_operator"] = True
|
269
|
+
finite_diff_options["workers"] = workers
|
270
|
+
finite_diff_options["full_output"] = True
|
221
271
|
|
222
272
|
# Initial function evaluation
|
273
|
+
self._nfev = 0
|
223
274
|
self._update_fun()
|
224
275
|
|
225
276
|
# Initial gradient evaluation
|
226
|
-
self._wrapped_grad
|
277
|
+
self._wrapped_grad = _ScalarGradWrapper(
|
227
278
|
grad,
|
228
279
|
fun=self._wrapped_fun,
|
229
280
|
args=args,
|
230
|
-
finite_diff_options=finite_diff_options
|
281
|
+
finite_diff_options=finite_diff_options,
|
231
282
|
)
|
232
283
|
self._update_grad()
|
233
284
|
|
234
285
|
# Hessian evaluation
|
235
|
-
if
|
236
|
-
self._wrapped_hess, self._nhev, self.H = _wrapper_hess(
|
237
|
-
hess, x0=x0, args=args
|
238
|
-
)
|
239
|
-
self.H_updated = True
|
240
|
-
elif hess in FD_METHODS:
|
241
|
-
self._wrapped_hess, self._nhev, self.H = _wrapper_hess(
|
242
|
-
hess,
|
243
|
-
grad=self._wrapped_grad,
|
244
|
-
x0=x0,
|
245
|
-
finite_diff_options=finite_diff_options
|
246
|
-
)
|
247
|
-
self._update_grad()
|
248
|
-
self.H = self._wrapped_hess(self.x, f0=self.g)
|
249
|
-
self.H_updated = True
|
250
|
-
elif isinstance(hess, HessianUpdateStrategy):
|
286
|
+
if isinstance(hess, HessianUpdateStrategy):
|
251
287
|
self.H = hess
|
252
288
|
self.H.initialize(self.n, 'hess')
|
253
289
|
self.H_updated = True
|
254
290
|
self.x_prev = None
|
255
291
|
self.g_prev = None
|
256
|
-
|
292
|
+
_FakeCounter = namedtuple('_FakeCounter', ['ngev', 'nhev'])
|
293
|
+
self._wrapped_hess = _FakeCounter(ngev=0, nhev=0)
|
294
|
+
else:
|
295
|
+
if callable(hess):
|
296
|
+
self._wrapped_hess = _ScalarHessWrapper(
|
297
|
+
hess,
|
298
|
+
x0=x0,
|
299
|
+
args=args,
|
300
|
+
finite_diff_options=finite_diff_options
|
301
|
+
)
|
302
|
+
self.H = self._wrapped_hess.H
|
303
|
+
self.H_updated = True
|
304
|
+
elif hess in FD_METHODS:
|
305
|
+
self._wrapped_hess = _ScalarHessWrapper(
|
306
|
+
hess,
|
307
|
+
x0=x0,
|
308
|
+
args=args,
|
309
|
+
grad=self._wrapped_grad,
|
310
|
+
finite_diff_options=finite_diff_options
|
311
|
+
)
|
312
|
+
self._update_grad()
|
313
|
+
self.H = self._wrapped_hess(self.x, f0=self.g)
|
314
|
+
self.H_updated = True
|
257
315
|
|
258
316
|
@property
|
259
317
|
def nfev(self):
|
260
|
-
return self._nfev
|
318
|
+
return self._nfev + self._wrapped_grad.nfev
|
261
319
|
|
262
320
|
@property
|
263
321
|
def ngev(self):
|
264
|
-
return self.
|
322
|
+
return self._wrapped_grad.ngev #+ self._wrapped_hess.ngev
|
265
323
|
|
266
324
|
@property
|
267
325
|
def nhev(self):
|
268
|
-
return self.
|
326
|
+
return self._wrapped_hess.nhev
|
269
327
|
|
270
328
|
def _update_x(self, x):
|
271
329
|
if isinstance(self._orig_hess, HessianUpdateStrategy):
|
@@ -293,6 +351,7 @@ class ScalarFunction:
|
|
293
351
|
def _update_fun(self):
|
294
352
|
if not self.f_updated:
|
295
353
|
fx = self._wrapped_fun(self.x)
|
354
|
+
self._nfev += 1
|
296
355
|
if fx < self._lowest_f:
|
297
356
|
self._lowest_x = self.x
|
298
357
|
self._lowest_f = fx
|
@@ -346,6 +405,114 @@ class ScalarFunction:
|
|
346
405
|
return self.f, self.g
|
347
406
|
|
348
407
|
|
408
|
+
class _VectorFunWrapper:
|
409
|
+
def __init__(self, fun):
|
410
|
+
self.fun = fun
|
411
|
+
self.nfev = 0
|
412
|
+
|
413
|
+
def __call__(self, x):
|
414
|
+
self.nfev += 1
|
415
|
+
return np.atleast_1d(self.fun(x))
|
416
|
+
|
417
|
+
|
418
|
+
class _VectorJacWrapper:
|
419
|
+
"""
|
420
|
+
Wrapper class for Jacobian calculation
|
421
|
+
"""
|
422
|
+
def __init__(
|
423
|
+
self,
|
424
|
+
jac,
|
425
|
+
fun=None,
|
426
|
+
finite_diff_options=None,
|
427
|
+
sparse_jacobian=None
|
428
|
+
):
|
429
|
+
self.fun = fun
|
430
|
+
self.jac = jac
|
431
|
+
self.finite_diff_options = finite_diff_options
|
432
|
+
self.sparse_jacobian = sparse_jacobian
|
433
|
+
|
434
|
+
self.njev = 0
|
435
|
+
# number of function evaluations consumed by finite difference
|
436
|
+
self.nfev = 0
|
437
|
+
|
438
|
+
def __call__(self, x, f0=None, **kwds):
|
439
|
+
# Send a copy because the user may overwrite it.
|
440
|
+
# The user of this class might want `x` to remain unchanged.
|
441
|
+
if callable(self.jac):
|
442
|
+
J = self.jac(x)
|
443
|
+
self.njev += 1
|
444
|
+
elif self.jac in FD_METHODS:
|
445
|
+
J, dct = approx_derivative(
|
446
|
+
self.fun,
|
447
|
+
x,
|
448
|
+
f0=f0,
|
449
|
+
**self.finite_diff_options,
|
450
|
+
)
|
451
|
+
self.nfev += dct['nfev']
|
452
|
+
|
453
|
+
if self.sparse_jacobian:
|
454
|
+
return sps.csr_array(J)
|
455
|
+
elif sps.issparse(J):
|
456
|
+
return J.toarray()
|
457
|
+
elif isinstance(J, LinearOperator):
|
458
|
+
return J
|
459
|
+
else:
|
460
|
+
return np.atleast_2d(J)
|
461
|
+
|
462
|
+
|
463
|
+
class _VectorHessWrapper:
|
464
|
+
"""
|
465
|
+
Wrapper class for Jacobian calculation
|
466
|
+
"""
|
467
|
+
def __init__(
|
468
|
+
self,
|
469
|
+
hess,
|
470
|
+
jac=None,
|
471
|
+
finite_diff_options=None,
|
472
|
+
):
|
473
|
+
self.jac = jac
|
474
|
+
self.hess = hess
|
475
|
+
self.finite_diff_options = finite_diff_options
|
476
|
+
self.nhev = 0
|
477
|
+
# number of jac evaluations consumed by finite difference
|
478
|
+
self.njev = 0
|
479
|
+
|
480
|
+
def __call__(self, x, v, J0=None, **kwds):
|
481
|
+
# Send a copy because the user may overwrite it.
|
482
|
+
# The user of this class might want `x` to remain unchanged.
|
483
|
+
if callable(self.hess):
|
484
|
+
self.nhev += 1
|
485
|
+
return self._callable_hess(x, v)
|
486
|
+
elif self.hess in FD_METHODS:
|
487
|
+
return self._fd_hess(x, v, J0=J0)
|
488
|
+
|
489
|
+
def _fd_hess(self, x, v, J0=None):
|
490
|
+
if J0 is None:
|
491
|
+
J0 = self.jac(x)
|
492
|
+
self.njev += 1
|
493
|
+
|
494
|
+
# H will be a LinearOperator
|
495
|
+
H = approx_derivative(self.jac_dot_v, x,
|
496
|
+
f0=J0.T.dot(v),
|
497
|
+
args=(v,),
|
498
|
+
**self.finite_diff_options)
|
499
|
+
return H
|
500
|
+
|
501
|
+
def jac_dot_v(self, x, v):
|
502
|
+
self.njev += 1
|
503
|
+
return self.jac(x).T.dot(v)
|
504
|
+
|
505
|
+
def _callable_hess(self, x, v):
|
506
|
+
H = self.hess(x, v)
|
507
|
+
|
508
|
+
if sps.issparse(H):
|
509
|
+
return sps.csr_array(H)
|
510
|
+
elif isinstance(H, LinearOperator):
|
511
|
+
return H
|
512
|
+
else:
|
513
|
+
return np.atleast_2d(np.asarray(H))
|
514
|
+
|
515
|
+
|
349
516
|
class VectorFunction:
|
350
517
|
"""Vector function and its derivatives.
|
351
518
|
|
@@ -364,8 +531,9 @@ class VectorFunction:
|
|
364
531
|
of *any* of the methods may overwrite the attribute.
|
365
532
|
"""
|
366
533
|
def __init__(self, fun, x0, jac, hess,
|
367
|
-
finite_diff_rel_step, finite_diff_jac_sparsity,
|
368
|
-
finite_diff_bounds, sparse_jacobian
|
534
|
+
finite_diff_rel_step=None, finite_diff_jac_sparsity=None,
|
535
|
+
finite_diff_bounds=(-np.inf, np.inf), sparse_jacobian=None,
|
536
|
+
workers=None):
|
369
537
|
if not callable(jac) and jac not in FD_METHODS:
|
370
538
|
raise ValueError(f"`jac` must be either callable or one of {FD_METHODS}.")
|
371
539
|
|
@@ -386,18 +554,26 @@ class VectorFunction:
|
|
386
554
|
if xp.isdtype(_x.dtype, "real floating"):
|
387
555
|
_dtype = _x.dtype
|
388
556
|
|
389
|
-
#
|
557
|
+
# store original functions
|
558
|
+
self._orig_fun = fun
|
559
|
+
self._orig_jac = jac
|
560
|
+
self._orig_hess = hess
|
561
|
+
|
562
|
+
# promotes to floating, ensures that it's a copy
|
390
563
|
self.x = xp.astype(_x, _dtype)
|
391
564
|
self.x_dtype = _dtype
|
392
565
|
|
393
566
|
self.n = self.x.size
|
394
|
-
self.
|
395
|
-
self.
|
396
|
-
self.
|
567
|
+
self._nfev = 0
|
568
|
+
self._njev = 0
|
569
|
+
self._nhev = 0
|
397
570
|
self.f_updated = False
|
398
571
|
self.J_updated = False
|
399
572
|
self.H_updated = False
|
400
573
|
|
574
|
+
# normalize workers
|
575
|
+
workers = workers or map
|
576
|
+
|
401
577
|
finite_diff_options = {}
|
402
578
|
if jac in FD_METHODS:
|
403
579
|
finite_diff_options["method"] = jac
|
@@ -407,11 +583,17 @@ class VectorFunction:
|
|
407
583
|
finite_diff_options["sparsity"] = (finite_diff_jac_sparsity,
|
408
584
|
sparsity_groups)
|
409
585
|
finite_diff_options["bounds"] = finite_diff_bounds
|
586
|
+
finite_diff_options["workers"] = workers
|
587
|
+
finite_diff_options["full_output"] = True
|
410
588
|
self.x_diff = np.copy(self.x)
|
411
589
|
if hess in FD_METHODS:
|
412
590
|
finite_diff_options["method"] = hess
|
413
591
|
finite_diff_options["rel_step"] = finite_diff_rel_step
|
414
592
|
finite_diff_options["as_linear_operator"] = True
|
593
|
+
# workers is not useful for evaluation of the LinearOperator
|
594
|
+
# produced by approx_derivative. Only two/three function
|
595
|
+
# evaluations are used, and the LinearOperator may persist
|
596
|
+
# outside the scope that workers is valid in.
|
415
597
|
self.x_diff = np.copy(self.x)
|
416
598
|
if jac in FD_METHODS and hess in FD_METHODS:
|
417
599
|
raise ValueError("Whenever the Jacobian is estimated via "
|
@@ -419,122 +601,55 @@ class VectorFunction:
|
|
419
601
|
"be estimated using one of the quasi-Newton "
|
420
602
|
"strategies.")
|
421
603
|
|
422
|
-
|
423
|
-
|
424
|
-
self.nfev += 1
|
425
|
-
return np.atleast_1d(fun(x))
|
426
|
-
|
427
|
-
def update_fun():
|
428
|
-
self.f = fun_wrapped(self.x)
|
429
|
-
|
430
|
-
self._update_fun_impl = update_fun
|
431
|
-
update_fun()
|
604
|
+
self.fun_wrapped = _VectorFunWrapper(fun)
|
605
|
+
self._update_fun()
|
432
606
|
|
433
607
|
self.v = np.zeros_like(self.f)
|
434
608
|
self.m = self.v.size
|
435
609
|
|
436
|
-
# Jacobian Evaluation
|
610
|
+
# Initial Jacobian Evaluation
|
437
611
|
if callable(jac):
|
438
|
-
self.J = jac(self.x)
|
612
|
+
self.J = jac(xp_copy(self.x))
|
439
613
|
self.J_updated = True
|
440
|
-
self.
|
441
|
-
|
442
|
-
if (sparse_jacobian or
|
443
|
-
sparse_jacobian is None and sps.issparse(self.J)):
|
444
|
-
def jac_wrapped(x):
|
445
|
-
self.njev += 1
|
446
|
-
return sps.csr_matrix(jac(x))
|
447
|
-
self.J = sps.csr_matrix(self.J)
|
448
|
-
self.sparse_jacobian = True
|
449
|
-
|
450
|
-
elif sps.issparse(self.J):
|
451
|
-
def jac_wrapped(x):
|
452
|
-
self.njev += 1
|
453
|
-
return jac(x).toarray()
|
454
|
-
self.J = self.J.toarray()
|
455
|
-
self.sparse_jacobian = False
|
456
|
-
|
457
|
-
else:
|
458
|
-
def jac_wrapped(x):
|
459
|
-
self.njev += 1
|
460
|
-
return np.atleast_2d(jac(x))
|
461
|
-
self.J = np.atleast_2d(self.J)
|
462
|
-
self.sparse_jacobian = False
|
463
|
-
|
464
|
-
def update_jac():
|
465
|
-
self.J = jac_wrapped(self.x)
|
466
|
-
|
614
|
+
self._njev += 1
|
467
615
|
elif jac in FD_METHODS:
|
468
|
-
self.J = approx_derivative(
|
469
|
-
|
616
|
+
self.J, dct = approx_derivative(
|
617
|
+
self.fun_wrapped, self.x, f0=self.f, **finite_diff_options
|
618
|
+
)
|
470
619
|
self.J_updated = True
|
620
|
+
self._nfev += dct['nfev']
|
621
|
+
|
622
|
+
self.sparse_jacobian = False
|
623
|
+
if (sparse_jacobian or
|
624
|
+
sparse_jacobian is None and sps.issparse(self.J)):
|
625
|
+
# something truthy was specified for sparse_jacobian,
|
626
|
+
# or it turns out that the Jacobian was sparse.
|
627
|
+
self.J = sps.csr_array(self.J)
|
628
|
+
self.sparse_jacobian = True
|
629
|
+
elif sps.issparse(self.J):
|
630
|
+
self.J = self.J.toarray()
|
631
|
+
elif isinstance(self.J, LinearOperator):
|
632
|
+
pass
|
633
|
+
else:
|
634
|
+
self.J = np.atleast_2d(self.J)
|
471
635
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
**finite_diff_options))
|
479
|
-
self.J = sps.csr_matrix(self.J)
|
480
|
-
self.sparse_jacobian = True
|
481
|
-
|
482
|
-
elif sps.issparse(self.J):
|
483
|
-
def update_jac():
|
484
|
-
self._update_fun()
|
485
|
-
self.J = approx_derivative(fun_wrapped, self.x, f0=self.f,
|
486
|
-
**finite_diff_options).toarray()
|
487
|
-
self.J = self.J.toarray()
|
488
|
-
self.sparse_jacobian = False
|
489
|
-
|
490
|
-
else:
|
491
|
-
def update_jac():
|
492
|
-
self._update_fun()
|
493
|
-
self.J = np.atleast_2d(
|
494
|
-
approx_derivative(fun_wrapped, self.x, f0=self.f,
|
495
|
-
**finite_diff_options))
|
496
|
-
self.J = np.atleast_2d(self.J)
|
497
|
-
self.sparse_jacobian = False
|
636
|
+
self.jac_wrapped = _VectorJacWrapper(
|
637
|
+
jac,
|
638
|
+
fun=self.fun_wrapped,
|
639
|
+
finite_diff_options=finite_diff_options,
|
640
|
+
sparse_jacobian=self.sparse_jacobian
|
641
|
+
)
|
498
642
|
|
499
|
-
self.
|
643
|
+
self.hess_wrapped = _VectorHessWrapper(
|
644
|
+
hess, jac=self.jac_wrapped, finite_diff_options=finite_diff_options
|
645
|
+
)
|
500
646
|
|
501
647
|
# Define Hessian
|
502
|
-
if callable(hess):
|
503
|
-
self.H =
|
504
|
-
self.H_updated = True
|
505
|
-
self.nhev += 1
|
506
|
-
|
507
|
-
if sps.issparse(self.H):
|
508
|
-
def hess_wrapped(x, v):
|
509
|
-
self.nhev += 1
|
510
|
-
return sps.csr_matrix(hess(x, v))
|
511
|
-
self.H = sps.csr_matrix(self.H)
|
512
|
-
|
513
|
-
elif isinstance(self.H, LinearOperator):
|
514
|
-
def hess_wrapped(x, v):
|
515
|
-
self.nhev += 1
|
516
|
-
return hess(x, v)
|
517
|
-
|
518
|
-
else:
|
519
|
-
def hess_wrapped(x, v):
|
520
|
-
self.nhev += 1
|
521
|
-
return np.atleast_2d(np.asarray(hess(x, v)))
|
522
|
-
self.H = np.atleast_2d(np.asarray(self.H))
|
523
|
-
|
524
|
-
def update_hess():
|
525
|
-
self.H = hess_wrapped(self.x, self.v)
|
526
|
-
elif hess in FD_METHODS:
|
527
|
-
def jac_dot_v(x, v):
|
528
|
-
return jac_wrapped(x).T.dot(v)
|
529
|
-
|
530
|
-
def update_hess():
|
531
|
-
self._update_jac()
|
532
|
-
self.H = approx_derivative(jac_dot_v, self.x,
|
533
|
-
f0=self.J.T.dot(self.v),
|
534
|
-
args=(self.v,),
|
535
|
-
**finite_diff_options)
|
536
|
-
update_hess()
|
648
|
+
if callable(hess) or hess in FD_METHODS:
|
649
|
+
self.H = self.hess_wrapped(xp_copy(self.x), self.v, J0=self.J)
|
537
650
|
self.H_updated = True
|
651
|
+
if callable(hess):
|
652
|
+
self._nhev += 1
|
538
653
|
elif isinstance(hess, HessianUpdateStrategy):
|
539
654
|
self.H = hess
|
540
655
|
self.H.initialize(self.n, 'hess')
|
@@ -542,19 +657,26 @@ class VectorFunction:
|
|
542
657
|
self.x_prev = None
|
543
658
|
self.J_prev = None
|
544
659
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
# J_prev are None and we need this check.
|
549
|
-
if self.x_prev is not None and self.J_prev is not None:
|
550
|
-
delta_x = self.x - self.x_prev
|
551
|
-
delta_g = self.J.T.dot(self.v) - self.J_prev.T.dot(self.v)
|
552
|
-
self.H.update(delta_x, delta_g)
|
660
|
+
@property
|
661
|
+
def nfev(self):
|
662
|
+
return self._nfev + self.jac_wrapped.nfev
|
553
663
|
|
554
|
-
|
664
|
+
@property
|
665
|
+
def njev(self):
|
666
|
+
return self._njev + self.hess_wrapped.njev
|
555
667
|
|
556
|
-
|
557
|
-
|
668
|
+
@property
|
669
|
+
def nhev(self):
|
670
|
+
return self._nhev
|
671
|
+
|
672
|
+
def _update_v(self, v):
|
673
|
+
if not np.array_equal(v, self.v):
|
674
|
+
self.v = v
|
675
|
+
self.H_updated = False
|
676
|
+
|
677
|
+
def _update_x(self, x):
|
678
|
+
if not np.array_equal(x, self.x):
|
679
|
+
if isinstance(self._orig_hess, HessianUpdateStrategy):
|
558
680
|
self._update_jac()
|
559
681
|
self.x_prev = self.x
|
560
682
|
self.J_prev = self.J
|
@@ -564,48 +686,63 @@ class VectorFunction:
|
|
564
686
|
self.J_updated = False
|
565
687
|
self.H_updated = False
|
566
688
|
self._update_hess()
|
567
|
-
|
568
|
-
def update_x(x):
|
689
|
+
else:
|
569
690
|
_x = xpx.atleast_nd(self.xp.asarray(x), ndim=1, xp=self.xp)
|
570
691
|
self.x = self.xp.astype(_x, self.x_dtype)
|
571
692
|
self.f_updated = False
|
572
693
|
self.J_updated = False
|
573
694
|
self.H_updated = False
|
574
695
|
|
575
|
-
self._update_x_impl = update_x
|
576
|
-
|
577
|
-
def _update_v(self, v):
|
578
|
-
if not np.array_equal(v, self.v):
|
579
|
-
self.v = v
|
580
|
-
self.H_updated = False
|
581
|
-
|
582
|
-
def _update_x(self, x):
|
583
|
-
if not np.array_equal(x, self.x):
|
584
|
-
self._update_x_impl(x)
|
585
|
-
|
586
696
|
def _update_fun(self):
|
587
697
|
if not self.f_updated:
|
588
|
-
self.
|
698
|
+
self.f = self.fun_wrapped(xp_copy(self.x))
|
699
|
+
self._nfev += 1
|
589
700
|
self.f_updated = True
|
590
701
|
|
591
702
|
def _update_jac(self):
|
592
703
|
if not self.J_updated:
|
593
|
-
self.
|
704
|
+
if self._orig_jac in FD_METHODS:
|
705
|
+
# need to update fun to get f0
|
706
|
+
self._update_fun()
|
707
|
+
else:
|
708
|
+
self._njev += 1
|
709
|
+
|
710
|
+
self.J = self.jac_wrapped(xp_copy(self.x), f0=self.f)
|
594
711
|
self.J_updated = True
|
595
712
|
|
596
713
|
def _update_hess(self):
|
597
714
|
if not self.H_updated:
|
598
|
-
self.
|
715
|
+
if callable(self._orig_hess):
|
716
|
+
self.H = self.hess_wrapped(xp_copy(self.x), self.v)
|
717
|
+
self._nhev += 1
|
718
|
+
elif self._orig_hess in FD_METHODS:
|
719
|
+
self._update_jac()
|
720
|
+
self.H = self.hess_wrapped(xp_copy(self.x), self.v, J0=self.J)
|
721
|
+
elif isinstance(self._orig_hess, HessianUpdateStrategy):
|
722
|
+
self._update_jac()
|
723
|
+
# When v is updated before x was updated, then x_prev and
|
724
|
+
# J_prev are None and we need this check.
|
725
|
+
if self.x_prev is not None and self.J_prev is not None:
|
726
|
+
delta_x = self.x - self.x_prev
|
727
|
+
delta_g = self.J.T.dot(self.v) - self.J_prev.T.dot(self.v)
|
728
|
+
self.H.update(delta_x, delta_g)
|
729
|
+
|
599
730
|
self.H_updated = True
|
600
731
|
|
601
732
|
def fun(self, x):
|
602
733
|
self._update_x(x)
|
603
734
|
self._update_fun()
|
604
|
-
|
735
|
+
# returns a copy so that downstream can't overwrite the
|
736
|
+
# internal attribute
|
737
|
+
return xp_copy(self.f)
|
605
738
|
|
606
739
|
def jac(self, x):
|
607
740
|
self._update_x(x)
|
608
741
|
self._update_jac()
|
742
|
+
if hasattr(self.J, "astype"):
|
743
|
+
# returns a copy so that downstream can't overwrite the
|
744
|
+
# internal attribute. But one can't copy a LinearOperator
|
745
|
+
return self.J.astype(self.J.dtype)
|
609
746
|
return self.J
|
610
747
|
|
611
748
|
def hess(self, x, v):
|
@@ -613,6 +750,10 @@ class VectorFunction:
|
|
613
750
|
self._update_v(v)
|
614
751
|
self._update_x(x)
|
615
752
|
self._update_hess()
|
753
|
+
if hasattr(self.H, "astype"):
|
754
|
+
# returns a copy so that downstream can't overwrite the
|
755
|
+
# internal attribute. But one can't copy non-arrays
|
756
|
+
return self.H.astype(self.H.dtype)
|
616
757
|
return self.H
|
617
758
|
|
618
759
|
|
@@ -625,7 +766,7 @@ class LinearVectorFunction:
|
|
625
766
|
"""
|
626
767
|
def __init__(self, A, x0, sparse_jacobian):
|
627
768
|
if sparse_jacobian or sparse_jacobian is None and sps.issparse(A):
|
628
|
-
self.J = sps.
|
769
|
+
self.J = sps.csr_array(A)
|
629
770
|
self.sparse_jacobian = True
|
630
771
|
elif sps.issparse(A):
|
631
772
|
self.J = A.toarray()
|
@@ -651,7 +792,7 @@ class LinearVectorFunction:
|
|
651
792
|
self.f_updated = True
|
652
793
|
|
653
794
|
self.v = np.zeros(self.m, dtype=float)
|
654
|
-
self.H = sps.
|
795
|
+
self.H = sps.csr_array((self.n, self.n))
|
655
796
|
|
656
797
|
def _update_x(self, x):
|
657
798
|
if not np.array_equal(x, self.x):
|
@@ -686,7 +827,7 @@ class IdentityVectorFunction(LinearVectorFunction):
|
|
686
827
|
def __init__(self, x0, sparse_jacobian):
|
687
828
|
n = len(x0)
|
688
829
|
if sparse_jacobian or sparse_jacobian is None:
|
689
|
-
A = sps.
|
830
|
+
A = sps.eye_array(n, format='csr')
|
690
831
|
sparse_jacobian = True
|
691
832
|
else:
|
692
833
|
A = np.eye(n)
|