scipy 1.15.3__cp312-cp312-musllinux_1_2_aarch64.whl → 1.16.0rc2__cp312-cp312-musllinux_1_2_aarch64.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 +10 -10
- scipy/__init__.py +3 -6
- scipy/_cyutility.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_docscrape.py +1 -1
- scipy/_lib/_elementwise_iterative_method.py +15 -26
- scipy/_lib/_fpumode.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_sparse.py +41 -0
- scipy/_lib/_test_ccallback.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_test_deprecation_call.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_test_deprecation_def.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/_lib/_testutils.py +6 -2
- scipy/_lib/_uarray/_uarray.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/cluster/_optimal_leaf_ordering.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/cluster/_vq.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_lsoda.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_ode.py +9 -2
- scipy/integrate/_odepack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_quad_vec.py +21 -29
- scipy/integrate/_quadpack.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_test_odeint_banded.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/integrate/_vode.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_dierckx.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_fitpack.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_rbf.py +2 -2
- scipy/interpolate/_rbfinterp.py +1 -1
- scipy/interpolate/_rbfinterp_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/interpolate/_rgi.py +31 -26
- scipy/interpolate/_rgi_cython.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/matlab/_mio_utils.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/io/matlab/_miobase.py +4 -1
- scipy/io/matlab/_streams.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_decomp_ldl.py +4 -1
- scipy/linalg/_decomp_lu.py +18 -6
- scipy/linalg/_decomp_lu_cython.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_expm_frechet.py +4 -0
- scipy/linalg/_fblas.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_flapack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_linalg_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs.py +187 -4
- scipy/linalg/_matfuncs_expm.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs_schur_sqrtm.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_matfuncs_sqrtm.py +1 -99
- scipy/linalg/_matfuncs_sqrtm_triu.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_procrustes.py +2 -0
- scipy/linalg/_sketches.py +17 -6
- scipy/linalg/_solve_toeplitz.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/_solvers.py +7 -2
- scipy/linalg/_special_matrices.py +26 -36
- scipy/linalg/cython_blas.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/linalg/cython_lapack.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_cytest.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_ni_docstrings.py +5 -1
- scipy/ndimage/_ni_label.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/ndimage/_ni_support.py +1 -5
- scipy/ndimage/_rank_filter_1d.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_basinhopping.py +13 -7
- scipy/optimize/_bglu_dense.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_dual_annealing.py +1 -1
- scipy/optimize/_elementwise.py +1 -4
- scipy/optimize/_group_columns.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_highspy/_core.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_highspy/_highs_options.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lbfgsb.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_lsq/common.py +3 -3
- scipy/optimize/_lsq/dogbox.py +16 -2
- scipy/optimize/_lsq/givens_elimination.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_minpack_py.py +21 -14
- scipy/optimize/_moduleTNC.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_spectral.py +1 -1
- scipy/optimize/_tnc.py +8 -1
- scipy/optimize/_trlib/_trlib.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_zeros_py.py +97 -17
- scipy/optimize/cython_optimize/_zeros.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_peak_finding_utils.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_sosfilt.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/signal/_spectral_py.py +230 -50
- scipy/signal/_spline.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_matching.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_min_spanning_tree.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_reordering.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_shortest_path.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_tools.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/csgraph/_traversal.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_dpropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_spropack.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/sparse/linalg/_propack/_zpropack.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_distance_pybind.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_distance_wrap.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_hausdorff.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_qhull.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/_voronoi.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/transform/_rotation.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_ellip_harm_2.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_gufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_logsumexp.py +67 -58
- scipy/special/_orthogonal.pyi +1 -1
- scipy/special/_specfun.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_special_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_spherical_bessel.py +4 -4
- scipy/special/_support_alternative_backends.py +212 -119
- scipy/special/_test_internal.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_testutils.py +4 -4
- scipy/special/_ufuncs.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/special/_ufuncs.pyi +1 -0
- scipy/special/_ufuncs.pyx +215 -1400
- scipy/special/_ufuncs_cxx.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_axis_nan_policy.py +5 -12
- scipy/stats/_biasedurn.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_qmvnt.py +16 -95
- scipy/stats/_qmvnt_cy.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_quantile.py +335 -0
- scipy/stats/_rcont/rcont.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_resampling.py +4 -29
- scipy/stats/_sampling.py +1 -1
- scipy/stats/_sobol.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_stats.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_stats_mstats_common.py +21 -2
- scipy/stats/_stats_py.py +550 -476
- scipy/stats/_stats_pythran.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/stats/_unuran/unuran_wrapper.cpython-312-aarch64-linux-musl.so +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.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 +1262 -1269
- scipy.libs/libgcc_s-69c45f16.so.1 +0 -0
- scipy.libs/libgfortran-db0b6589.so.5.0.0 +0 -0
- scipy.libs/{libstdc++-1b614e01.so.6.0.32 → libstdc++-1f1a71be.so.6.0.33} +0 -0
- scipy/_lib/array_api_extra/_funcs.py +0 -484
- scipy/_lib/array_api_extra/_typing.py +0 -8
- scipy/interpolate/_bspl.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_cobyla.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_cython_nnls.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/optimize/_slsqp.cpython-312-aarch64-linux-musl.so +0 -0
- scipy/spatial/qhull_src/COPYING.txt +0 -38
- scipy/special/libsf_error_state.so +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.cpython-312-aarch64-linux-musl.so +0 -0
- scipy.libs/libgcc_s-7393e603.so.1 +0 -0
- scipy.libs/libgfortran-eb933d8e.so.5.0.0 +0 -0
- {scipy-1.15.3.dist-info → scipy-1.16.0rc2.dist-info}/WHEEL +0 -0
scipy/optimize/_numdiff.py
CHANGED
@@ -4,9 +4,10 @@ import numpy as np
|
|
4
4
|
from numpy.linalg import norm
|
5
5
|
|
6
6
|
from scipy.sparse.linalg import LinearOperator
|
7
|
-
from ..sparse import issparse,
|
7
|
+
from ..sparse import issparse, isspmatrix, find, csc_array, csr_array, csr_matrix
|
8
8
|
from ._group_columns import group_dense, group_sparse
|
9
9
|
from scipy._lib._array_api import array_namespace
|
10
|
+
from scipy._lib._util import MapWrapper
|
10
11
|
from scipy._lib import array_api_extra as xpx
|
11
12
|
|
12
13
|
|
@@ -221,7 +222,7 @@ def group_columns(A, order=0):
|
|
221
222
|
|
222
223
|
Parameters
|
223
224
|
----------
|
224
|
-
A : array_like or sparse
|
225
|
+
A : array_like or sparse array, shape (m, n)
|
225
226
|
Matrix of which to group columns.
|
226
227
|
order : int, iterable of int with shape (n,) or None
|
227
228
|
Permutation array which defines the order of columns enumeration.
|
@@ -244,7 +245,7 @@ def group_columns(A, order=0):
|
|
244
245
|
and its Applications, 13 (1974), pp. 117-120.
|
245
246
|
"""
|
246
247
|
if issparse(A):
|
247
|
-
A =
|
248
|
+
A = csc_array(A)
|
248
249
|
else:
|
249
250
|
A = np.atleast_2d(A)
|
250
251
|
A = (A != 0).astype(np.int32)
|
@@ -276,7 +277,8 @@ def group_columns(A, order=0):
|
|
276
277
|
|
277
278
|
def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
278
279
|
f0=None, bounds=(-np.inf, np.inf), sparsity=None,
|
279
|
-
as_linear_operator=False, args=(), kwargs=None
|
280
|
+
as_linear_operator=False, args=(), kwargs=None,
|
281
|
+
full_output=False, workers=None):
|
280
282
|
"""Compute finite difference approximation of the derivatives of a
|
281
283
|
vector-valued function.
|
282
284
|
|
@@ -325,20 +327,20 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
325
327
|
case the bound will be the same for all variables. Use it to limit the
|
326
328
|
range of function evaluation. Bounds checking is not implemented
|
327
329
|
when `as_linear_operator` is True.
|
328
|
-
sparsity : {None, array_like, sparse
|
330
|
+
sparsity : {None, array_like, sparse array, 2-tuple}, optional
|
329
331
|
Defines a sparsity structure of the Jacobian matrix. If the Jacobian
|
330
332
|
matrix is known to have only few non-zero elements in each row, then
|
331
333
|
it's possible to estimate its several columns by a single function
|
332
334
|
evaluation [3]_. To perform such economic computations two ingredients
|
333
335
|
are required:
|
334
336
|
|
335
|
-
* structure : array_like or sparse
|
337
|
+
* structure : array_like or sparse array of shape (m, n). A zero
|
336
338
|
element means that a corresponding element of the Jacobian
|
337
339
|
identically equals to zero.
|
338
340
|
* groups : array_like of shape (n,). A column grouping for a given
|
339
341
|
sparsity structure, use `group_columns` to obtain it.
|
340
342
|
|
341
|
-
A single array or a sparse
|
343
|
+
A single array or a sparse array is interpreted as a sparsity
|
342
344
|
structure, and groups are computed inside the function. A tuple is
|
343
345
|
interpreted as (structure, groups). If None (default), a standard
|
344
346
|
dense differencing will be used.
|
@@ -347,7 +349,7 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
347
349
|
matrices where each row contains few non-zero elements.
|
348
350
|
as_linear_operator : bool, optional
|
349
351
|
When True the function returns an `scipy.sparse.linalg.LinearOperator`.
|
350
|
-
Otherwise it returns a dense array or a sparse
|
352
|
+
Otherwise it returns a dense array or a sparse array depending on
|
351
353
|
`sparsity`. The linear operator provides an efficient way of computing
|
352
354
|
``J.dot(p)`` for any vector ``p`` of shape (n,), but does not allow
|
353
355
|
direct access to individual elements of the matrix. By default
|
@@ -355,20 +357,44 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
355
357
|
args, kwargs : tuple and dict, optional
|
356
358
|
Additional arguments passed to `fun`. Both empty by default.
|
357
359
|
The calling signature is ``fun(x, *args, **kwargs)``.
|
360
|
+
full_output : bool, optional
|
361
|
+
If True then the function also returns a dictionary with extra information
|
362
|
+
about the calculation.
|
363
|
+
workers : int or map-like callable, optional
|
364
|
+
Supply a map-like callable, such as
|
365
|
+
`multiprocessing.Pool.map` for evaluating the population in parallel.
|
366
|
+
This evaluation is carried out as ``workers(fun, iterable)``.
|
367
|
+
Alternatively, if `workers` is an int the task is subdivided into `workers`
|
368
|
+
sections and the fun evaluated in parallel
|
369
|
+
(uses `multiprocessing.Pool <multiprocessing>`).
|
370
|
+
Supply -1 to use all available CPU cores.
|
371
|
+
It is recommended that a map-like be used instead of int, as repeated
|
372
|
+
calls to `approx_derivative` will incur large overhead from setting up
|
373
|
+
new processes.
|
358
374
|
|
359
375
|
Returns
|
360
376
|
-------
|
361
|
-
J : {ndarray, sparse
|
377
|
+
J : {ndarray, sparse array, LinearOperator}
|
362
378
|
Finite difference approximation of the Jacobian matrix.
|
363
379
|
If `as_linear_operator` is True returns a LinearOperator
|
364
380
|
with shape (m, n). Otherwise it returns a dense array or sparse
|
365
|
-
|
381
|
+
array depending on how `sparsity` is defined. If `sparsity`
|
366
382
|
is None then a ndarray with shape (m, n) is returned. If
|
367
|
-
`sparsity` is not None returns a csr_matrix with
|
368
|
-
|
369
|
-
|
383
|
+
`sparsity` is not None returns a csr_array or csr_matrix with
|
384
|
+
shape (m, n) following the array/matrix type of the incoming structure.
|
385
|
+
For sparse arrays and linear operators it is always returned as
|
386
|
+
a 2-D structure. For ndarrays, if m=1 it is returned
|
370
387
|
as a 1-D gradient array with shape (n,).
|
371
388
|
|
389
|
+
info_dict : dict
|
390
|
+
Dictionary containing extra information about the calculation. The
|
391
|
+
keys include:
|
392
|
+
|
393
|
+
- `nfev`, number of function evaluations. If `as_linear_operator` is True
|
394
|
+
then `fun` is expected to track the number of evaluations itself.
|
395
|
+
This is because multiple calls may be made to the linear operator which
|
396
|
+
are not trackable here.
|
397
|
+
|
372
398
|
See Also
|
373
399
|
--------
|
374
400
|
check_derivative : Check correctness of a function computing derivatives.
|
@@ -436,10 +462,51 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
436
462
|
array([ 1.])
|
437
463
|
>>> approx_derivative(g, x0, bounds=(1.0, np.inf))
|
438
464
|
array([ 2.])
|
465
|
+
|
466
|
+
We can also parallelize the derivative calculation using the workers
|
467
|
+
keyword.
|
468
|
+
|
469
|
+
>>> from multiprocessing import Pool
|
470
|
+
>>> import time
|
471
|
+
>>> def fun2(x): # import from an external file for use with multiprocessing
|
472
|
+
... time.sleep(0.002)
|
473
|
+
... return rosen(x)
|
474
|
+
|
475
|
+
>>> rng = np.random.default_rng()
|
476
|
+
>>> x0 = rng.uniform(high=10, size=(2000,))
|
477
|
+
>>> f0 = rosen(x0)
|
478
|
+
|
479
|
+
>>> %timeit approx_derivative(fun2, x0, f0=f0) # may vary
|
480
|
+
10.5 s ± 5.91 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
|
481
|
+
|
482
|
+
>>> elapsed = []
|
483
|
+
>>> with Pool() as workers:
|
484
|
+
... for i in range(10):
|
485
|
+
... t = time.perf_counter()
|
486
|
+
... approx_derivative(fun2, x0, workers=workers.map, f0=f0)
|
487
|
+
... et = time.perf_counter()
|
488
|
+
... elapsed.append(et - t)
|
489
|
+
>>> np.mean(elapsed) # may vary
|
490
|
+
np.float64(1.442545195999901)
|
491
|
+
|
492
|
+
Create a map-like vectorized version. `x` is a generator, so first of all
|
493
|
+
a 2-D array, `xx`, is reconstituted. Here `xx` has shape `(Y, N)` where `Y`
|
494
|
+
is the number of function evaluations to perform and `N` is the dimensionality
|
495
|
+
of the objective function. The underlying objective function is `rosen`, which
|
496
|
+
requires `xx` to have shape `(N, Y)`, so a transpose is required.
|
497
|
+
|
498
|
+
>>> def fun(f, x, *args, **kwds):
|
499
|
+
... xx = np.r_[[xs for xs in x]]
|
500
|
+
... return f(xx.T)
|
501
|
+
>>> %timeit approx_derivative(fun2, x0, workers=fun, f0=f0) # may vary
|
502
|
+
91.8 ms ± 755 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
|
503
|
+
|
439
504
|
"""
|
440
505
|
if method not in ['2-point', '3-point', 'cs']:
|
441
506
|
raise ValueError(f"Unknown method '{method}'. ")
|
442
507
|
|
508
|
+
info_dict = {'nfev': None}
|
509
|
+
|
443
510
|
xp = array_namespace(x0)
|
444
511
|
_x = xpx.atleast_nd(xp.asarray(x0), ndim=1, xp=xp)
|
445
512
|
_dtype = xp.float64
|
@@ -465,20 +532,20 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
465
532
|
if kwargs is None:
|
466
533
|
kwargs = {}
|
467
534
|
|
468
|
-
|
469
|
-
# send user function same fp type as x0. (but only if cs is not being
|
470
|
-
# used
|
471
|
-
if xp.isdtype(x.dtype, "real floating"):
|
472
|
-
x = xp.astype(x, x0.dtype)
|
535
|
+
fun_wrapped = _Fun_Wrapper(fun, x0, args, kwargs)
|
473
536
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
537
|
+
# Record how function evaluations are consumed by `approx_derivative`.
|
538
|
+
# Historically this was done by upstream functions wrapping `fun`.
|
539
|
+
# However, with parallelization via workers it was going to be impossible to
|
540
|
+
# keep that counter updated across Processes. Counter synchronisation can
|
541
|
+
# be achieved via multiprocessing.Value and a Pool. However, workers can be
|
542
|
+
# any map-like, not necessarily a Pool, so initialization of the Value would
|
543
|
+
# be difficult.
|
544
|
+
nfev = _nfev = 0
|
479
545
|
|
480
546
|
if f0 is None:
|
481
547
|
f0 = fun_wrapped(x0)
|
548
|
+
nfev = 1
|
482
549
|
else:
|
483
550
|
f0 = np.atleast_1d(f0)
|
484
551
|
if f0.ndim > 1:
|
@@ -491,7 +558,7 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
491
558
|
if rel_step is None:
|
492
559
|
rel_step = _eps_for_method(x0.dtype, f0.dtype, method)
|
493
560
|
|
494
|
-
|
561
|
+
J, _ = _linear_operator_difference(fun_wrapped, x0,
|
495
562
|
f0, rel_step, method)
|
496
563
|
else:
|
497
564
|
# by default we use rel_step
|
@@ -519,25 +586,35 @@ def approx_derivative(fun, x0, method='3-point', rel_step=None, abs_step=None,
|
|
519
586
|
elif method == 'cs':
|
520
587
|
use_one_sided = False
|
521
588
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
589
|
+
# normalize workers
|
590
|
+
workers = workers or map
|
591
|
+
with MapWrapper(workers) as mf:
|
592
|
+
if sparsity is None:
|
593
|
+
J, _nfev = _dense_difference(fun_wrapped, x0, f0, h,
|
594
|
+
use_one_sided, method,
|
595
|
+
mf)
|
528
596
|
else:
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
597
|
+
if not issparse(sparsity) and len(sparsity) == 2:
|
598
|
+
structure, groups = sparsity
|
599
|
+
else:
|
600
|
+
structure = sparsity
|
601
|
+
groups = group_columns(sparsity)
|
602
|
+
|
603
|
+
if issparse(structure):
|
604
|
+
structure = structure.tocsc()
|
605
|
+
else:
|
606
|
+
structure = np.atleast_2d(structure)
|
607
|
+
groups = np.atleast_1d(groups)
|
608
|
+
J, _nfev = _sparse_difference(fun_wrapped, x0, f0, h,
|
609
|
+
use_one_sided, structure,
|
610
|
+
groups, method, mf)
|
611
|
+
|
612
|
+
if full_output:
|
613
|
+
nfev += _nfev
|
614
|
+
info_dict["nfev"] = nfev
|
615
|
+
return J, info_dict
|
616
|
+
else:
|
617
|
+
return J
|
541
618
|
|
542
619
|
|
543
620
|
def _linear_operator_difference(fun, x0, f0, h, method):
|
@@ -545,6 +622,7 @@ def _linear_operator_difference(fun, x0, f0, h, method):
|
|
545
622
|
n = x0.size
|
546
623
|
|
547
624
|
if method == '2-point':
|
625
|
+
# nfev = 1
|
548
626
|
def matvec(p):
|
549
627
|
if np.array_equal(p, np.zeros_like(p)):
|
550
628
|
return np.zeros(m)
|
@@ -554,6 +632,7 @@ def _linear_operator_difference(fun, x0, f0, h, method):
|
|
554
632
|
return df / dx
|
555
633
|
|
556
634
|
elif method == '3-point':
|
635
|
+
# nfev = 2
|
557
636
|
def matvec(p):
|
558
637
|
if np.array_equal(p, np.zeros_like(p)):
|
559
638
|
return np.zeros(m)
|
@@ -566,6 +645,7 @@ def _linear_operator_difference(fun, x0, f0, h, method):
|
|
566
645
|
return df / dx
|
567
646
|
|
568
647
|
elif method == 'cs':
|
648
|
+
# nfev = 1
|
569
649
|
def matvec(p):
|
570
650
|
if np.array_equal(p, np.zeros_like(p)):
|
571
651
|
return np.zeros(m)
|
@@ -574,59 +654,97 @@ def _linear_operator_difference(fun, x0, f0, h, method):
|
|
574
654
|
f1 = fun(x)
|
575
655
|
df = f1.imag
|
576
656
|
return df / dx
|
577
|
-
|
578
657
|
else:
|
579
658
|
raise RuntimeError("Never be here.")
|
580
659
|
|
581
|
-
return LinearOperator((m, n), matvec)
|
660
|
+
return LinearOperator((m, n), matvec), 0
|
582
661
|
|
583
662
|
|
584
|
-
def _dense_difference(fun, x0, f0, h, use_one_sided, method):
|
663
|
+
def _dense_difference(fun, x0, f0, h, use_one_sided, method, workers):
|
585
664
|
m = f0.size
|
586
665
|
n = x0.size
|
587
666
|
J_transposed = np.empty((n, m))
|
588
|
-
|
589
|
-
x2 = x0.copy()
|
590
|
-
xc = x0.astype(complex, copy=True)
|
667
|
+
nfev = 0
|
591
668
|
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
xc[i] += h[i] * 1.j
|
613
|
-
f1 = fun(xc)
|
614
|
-
df = f1.imag
|
615
|
-
dx = h[i]
|
616
|
-
else:
|
617
|
-
raise RuntimeError("Never be here.")
|
669
|
+
if method == '2-point':
|
670
|
+
def x_generator2(x0, h):
|
671
|
+
for i in range(n):
|
672
|
+
# If copying isn't done then it's possible for different workers
|
673
|
+
# to see the same values of x1. (At least that's what happened
|
674
|
+
# when I used `multiprocessing.dummy.Pool`).
|
675
|
+
# I also considered creating all the vectors at once, but that
|
676
|
+
# means assembling a very large N x N array. It's therefore a
|
677
|
+
# trade-off between N array copies or creating an NxN array.
|
678
|
+
x1 = np.copy(x0)
|
679
|
+
x1[i] = x0[i] + h[i]
|
680
|
+
yield x1
|
681
|
+
|
682
|
+
# only f_evals (numerator) needs parallelization, the denominator
|
683
|
+
# (the step size) is fast to calculate.
|
684
|
+
f_evals = workers(fun, x_generator2(x0, h))
|
685
|
+
dx = [(x0[i] + h[i]) - x0[i] for i in range(n)]
|
686
|
+
df = [f_eval - f0 for f_eval in f_evals]
|
687
|
+
df_dx = [delf / delx for delf, delx in zip(df, dx)]
|
688
|
+
nfev += len(df_dx)
|
618
689
|
|
619
|
-
|
620
|
-
|
690
|
+
elif method == '3-point':
|
691
|
+
def x_generator3(x0, h, use_one_sided):
|
692
|
+
for i, one_sided in enumerate(use_one_sided):
|
693
|
+
x1 = np.copy(x0)
|
694
|
+
x2 = np.copy(x0)
|
695
|
+
if one_sided:
|
696
|
+
x1[i] = x0[i] + h[i]
|
697
|
+
x2[i] = x0[i] + 2*h[i]
|
698
|
+
else:
|
699
|
+
x1[i] = x0[i] - h[i]
|
700
|
+
x2[i] = x0[i] + h[i]
|
701
|
+
yield x1
|
702
|
+
yield x2
|
703
|
+
|
704
|
+
# workers may return something like a list that needs to be turned
|
705
|
+
# into an iterable (can't call `next` on a list)
|
706
|
+
f_evals = iter(workers(fun, x_generator3(x0, h, use_one_sided)))
|
707
|
+
gen = x_generator3(x0, h, use_one_sided)
|
708
|
+
dx = list()
|
709
|
+
df = list()
|
710
|
+
for i, one_sided in enumerate(use_one_sided):
|
711
|
+
l = next(gen)
|
712
|
+
u = next(gen)
|
713
|
+
|
714
|
+
f1 = next(f_evals)
|
715
|
+
f2 = next(f_evals)
|
716
|
+
if one_sided:
|
717
|
+
dx.append(u[i] - x0[i])
|
718
|
+
df.append(-3.0 * f0 + 4 * f1 - f2)
|
719
|
+
else:
|
720
|
+
dx.append(u[i] - l[i])
|
721
|
+
df.append(f2 - f1)
|
722
|
+
df_dx = [delf / delx for delf, delx in zip(df, dx)]
|
723
|
+
nfev += 2 * len(df_dx)
|
724
|
+
elif method == 'cs':
|
725
|
+
def x_generator_cs(x0, h):
|
726
|
+
for i in range(n):
|
727
|
+
xc = x0.astype(complex, copy=True)
|
728
|
+
xc[i] += h[i] * 1.j
|
729
|
+
yield xc
|
730
|
+
|
731
|
+
f_evals = iter(workers(fun, x_generator_cs(x0, h)))
|
732
|
+
df_dx = [f1.imag / hi for f1, hi in zip(f_evals, h)]
|
733
|
+
nfev += len(df_dx)
|
734
|
+
else:
|
735
|
+
raise RuntimeError("Never be here.")
|
736
|
+
|
737
|
+
for i, v in enumerate(df_dx):
|
738
|
+
J_transposed[i] = v
|
621
739
|
|
622
740
|
if m == 1:
|
623
741
|
J_transposed = np.ravel(J_transposed)
|
624
742
|
|
625
|
-
return J_transposed.T
|
743
|
+
return J_transposed.T, nfev
|
626
744
|
|
627
745
|
|
628
746
|
def _sparse_difference(fun, x0, f0, h, use_one_sided,
|
629
|
-
structure, groups, method):
|
747
|
+
structure, groups, method, workers):
|
630
748
|
m = f0.size
|
631
749
|
n = x0.size
|
632
750
|
row_indices = []
|
@@ -634,24 +752,24 @@ def _sparse_difference(fun, x0, f0, h, use_one_sided,
|
|
634
752
|
fractions = []
|
635
753
|
|
636
754
|
n_groups = np.max(groups) + 1
|
637
|
-
|
755
|
+
nfev = 0
|
756
|
+
|
757
|
+
def e_generator():
|
638
758
|
# Perturb variables which are in the same group simultaneously.
|
639
|
-
|
640
|
-
|
641
|
-
|
759
|
+
for group in range(n_groups):
|
760
|
+
yield np.equal(group, groups)
|
761
|
+
|
762
|
+
def x_generator2():
|
763
|
+
e_gen = e_generator()
|
764
|
+
for e in e_gen:
|
765
|
+
h_vec = h * e
|
642
766
|
x = x0 + h_vec
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
i, j, _ = find(structure[:, cols])
|
650
|
-
# Restore column indices in the full array.
|
651
|
-
j = cols[j]
|
652
|
-
elif method == '3-point':
|
653
|
-
# Here we do conceptually the same but separate one-sided
|
654
|
-
# and two-sided schemes.
|
767
|
+
yield x
|
768
|
+
|
769
|
+
def x_generator3():
|
770
|
+
e_gen = e_generator()
|
771
|
+
for e in e_gen:
|
772
|
+
h_vec = h * e
|
655
773
|
x1 = x0.copy()
|
656
774
|
x2 = x0.copy()
|
657
775
|
|
@@ -662,17 +780,54 @@ def _sparse_difference(fun, x0, f0, h, use_one_sided,
|
|
662
780
|
mask_2 = ~use_one_sided & e
|
663
781
|
x1[mask_2] -= h_vec[mask_2]
|
664
782
|
x2[mask_2] += h_vec[mask_2]
|
783
|
+
yield x1
|
784
|
+
yield x2
|
785
|
+
|
786
|
+
def x_generator_cs():
|
787
|
+
e_gen = e_generator()
|
788
|
+
for e in e_gen:
|
789
|
+
h_vec = h * e
|
790
|
+
yield x0 + h_vec * 1.j
|
791
|
+
|
792
|
+
# evaluate the function for each of the groups
|
793
|
+
if method == '2-point':
|
794
|
+
f_evals = iter(workers(fun, x_generator2()))
|
795
|
+
xs = x_generator2()
|
796
|
+
elif method == '3-point':
|
797
|
+
f_evals = iter(workers(fun, x_generator3()))
|
798
|
+
xs = x_generator3()
|
799
|
+
elif method == 'cs':
|
800
|
+
f_evals = iter(workers(fun, x_generator_cs()))
|
801
|
+
|
802
|
+
for e in e_generator():
|
803
|
+
# The result is written to columns which correspond to perturbed
|
804
|
+
# variables.
|
805
|
+
cols, = np.nonzero(e)
|
806
|
+
# Find all non-zero elements in selected columns of Jacobian.
|
807
|
+
i, j, _ = find(structure[:, cols])
|
808
|
+
# Restore column indices in the full array.
|
809
|
+
j = cols[j]
|
810
|
+
|
811
|
+
if method == '2-point':
|
812
|
+
dx = next(xs) - x0
|
813
|
+
df = next(f_evals) - f0
|
814
|
+
nfev += 1
|
815
|
+
elif method == '3-point':
|
816
|
+
# Here we do conceptually the same but separate one-sided
|
817
|
+
# and two-sided schemes.
|
818
|
+
x1 = next(xs)
|
819
|
+
x2 = next(xs)
|
820
|
+
|
821
|
+
mask_1 = use_one_sided & e
|
822
|
+
mask_2 = ~use_one_sided & e
|
665
823
|
|
666
824
|
dx = np.zeros(n)
|
667
825
|
dx[mask_1] = x2[mask_1] - x0[mask_1]
|
668
826
|
dx[mask_2] = x2[mask_2] - x1[mask_2]
|
669
827
|
|
670
|
-
f1 =
|
671
|
-
f2 =
|
672
|
-
|
673
|
-
cols, = np.nonzero(e)
|
674
|
-
i, j, _ = find(structure[:, cols])
|
675
|
-
j = cols[j]
|
828
|
+
f1 = next(f_evals)
|
829
|
+
f2 = next(f_evals)
|
830
|
+
nfev += 2
|
676
831
|
|
677
832
|
mask = use_one_sided[j]
|
678
833
|
df = np.empty(m)
|
@@ -683,17 +838,15 @@ def _sparse_difference(fun, x0, f0, h, use_one_sided,
|
|
683
838
|
rows = i[~mask]
|
684
839
|
df[rows] = f2[rows] - f1[rows]
|
685
840
|
elif method == 'cs':
|
686
|
-
f1 =
|
841
|
+
f1 = next(f_evals)
|
842
|
+
nfev += 1
|
687
843
|
df = f1.imag
|
688
|
-
dx =
|
689
|
-
cols, = np.nonzero(e)
|
690
|
-
i, j, _ = find(structure[:, cols])
|
691
|
-
j = cols[j]
|
844
|
+
dx = h * e
|
692
845
|
else:
|
693
846
|
raise ValueError("Never be here.")
|
694
847
|
|
695
848
|
# All that's left is to compute the fraction. We store i, j and
|
696
|
-
# fractions as separate arrays and later construct
|
849
|
+
# fractions as separate arrays and later construct csr_array.
|
697
850
|
row_indices.append(i)
|
698
851
|
col_indices.append(j)
|
699
852
|
fractions.append(df[i] / dx[j])
|
@@ -701,8 +854,33 @@ def _sparse_difference(fun, x0, f0, h, use_one_sided,
|
|
701
854
|
row_indices = np.hstack(row_indices)
|
702
855
|
col_indices = np.hstack(col_indices)
|
703
856
|
fractions = np.hstack(fractions)
|
704
|
-
|
705
|
-
|
857
|
+
|
858
|
+
if isspmatrix(structure):
|
859
|
+
return csr_matrix((fractions, (row_indices, col_indices)), shape=(m, n)), nfev
|
860
|
+
return csr_array((fractions, (row_indices, col_indices)), shape=(m, n)), nfev
|
861
|
+
|
862
|
+
|
863
|
+
class _Fun_Wrapper:
|
864
|
+
# Permits pickling of a wrapped function
|
865
|
+
def __init__(self, fun, x0, args, kwargs):
|
866
|
+
self.fun = fun
|
867
|
+
self.x0 = x0
|
868
|
+
self.args = args
|
869
|
+
self.kwargs = kwargs
|
870
|
+
|
871
|
+
def __call__(self, x):
|
872
|
+
# send user function same fp type as x0. (but only if cs is not being
|
873
|
+
# used
|
874
|
+
xp = array_namespace(self.x0)
|
875
|
+
|
876
|
+
if xp.isdtype(x.dtype, "real floating"):
|
877
|
+
x = xp.astype(x, self.x0.dtype)
|
878
|
+
|
879
|
+
f = np.atleast_1d(self.fun(x, *self.args, **self.kwargs))
|
880
|
+
if f.ndim > 1:
|
881
|
+
raise RuntimeError("`fun` return value has "
|
882
|
+
"more than 1 dimension.")
|
883
|
+
return f
|
706
884
|
|
707
885
|
|
708
886
|
def check_derivative(fun, jac, x0, bounds=(-np.inf, np.inf), args=(),
|
@@ -719,7 +897,7 @@ def check_derivative(fun, jac, x0, bounds=(-np.inf, np.inf), args=(),
|
|
719
897
|
jac : callable
|
720
898
|
Function which computes Jacobian matrix of `fun`. It must work with
|
721
899
|
argument x the same way as `fun`. The return value must be array_like
|
722
|
-
or sparse
|
900
|
+
or sparse array with an appropriate shape.
|
723
901
|
x0 : array_like of shape (n,) or float
|
724
902
|
Point at which to estimate the derivatives. Float will be converted
|
725
903
|
to 1-D array.
|
@@ -772,7 +950,7 @@ def check_derivative(fun, jac, x0, bounds=(-np.inf, np.inf), args=(),
|
|
772
950
|
if issparse(J_to_test):
|
773
951
|
J_diff = approx_derivative(fun, x0, bounds=bounds, sparsity=J_to_test,
|
774
952
|
args=args, kwargs=kwargs)
|
775
|
-
J_to_test =
|
953
|
+
J_to_test = csr_array(J_to_test)
|
776
954
|
abs_err = J_to_test - J_diff
|
777
955
|
i, j, abs_err_data = find(abs_err)
|
778
956
|
J_diff_data = np.asarray(J_diff[i, j]).ravel()
|