From 6a3394b0f33eae50795924eaf30ac365c80b7102 Mon Sep 17 00:00:00 2001 From: jorenham Date: Sun, 1 Dec 2024 17:04:51 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20complete=20`optimize.=5Ftrustre?= =?UTF-8?q?gion`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scipy-stubs/optimize/_trustregion.pyi | 41 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/scipy-stubs/optimize/_trustregion.pyi b/scipy-stubs/optimize/_trustregion.pyi index 94efdb4e..78aba72d 100644 --- a/scipy-stubs/optimize/_trustregion.pyi +++ b/scipy-stubs/optimize/_trustregion.pyi @@ -1,7 +1,8 @@ import abc +from collections.abc import Callable import numpy as np -from scipy._typing import Untyped +import optype.numpy as onp __all__: list[str] = [] @@ -9,22 +10,34 @@ class BaseQuadraticSubproblem: def __init__( self, /, - x: Untyped, - fun: Untyped, - jac: Untyped, - hess: Untyped | None = None, - hessp: Untyped | None = None, + x: onp.ToFloat1D, + fun: Callable[[onp.Array1D[np.float64]], onp.ToFloat], + jac: Callable[[onp.Array1D[np.float64]], onp.ToFloat1D], + hess: Callable[[onp.Array1D[np.float64]], onp.ToFloat2D] | None = None, + hessp: Callable[[onp.Array1D[np.float64], onp.Array1D[np.float64]], onp.ToFloat1D] | None = None, ) -> None: ... - def __call__(self, /, p: Untyped) -> Untyped: ... + def __call__(self, /, p: onp.ToFloat1D) -> float | np.float64: ... + + # @property - def fun(self, /) -> Untyped: ... + def fun(self, /) -> float | np.float64: ... @property - def jac(self, /) -> Untyped: ... + def jac_mag(self, /) -> float | np.float64: ... @property - def hess(self, /) -> Untyped: ... - def hessp(self, /, p: Untyped) -> Untyped: ... + def jac(self, /) -> onp.Array1D[np.float64]: ... @property - def jac_mag(self, /) -> Untyped: ... - def get_boundaries_intersections(self, /, z: Untyped, d: Untyped, trust_radius: Untyped) -> Untyped: ... + def hess(self, /) -> onp.Array2D[np.float64]: ... + + # + def hessp(self, /, p: onp.ToFloat1D) -> onp.Array1D[np.float64]: ... + def get_boundaries_intersections( + self, + /, + z: onp.ToArray1D, + d: onp.ToArray1D, + trust_radius: onp.ToFloat, + ) -> list[float | np.float64]: ... # list of size 2 + + # @abc.abstractmethod - def solve(self, /, trust_radius: float | np.float64) -> Untyped: ... + def solve(self, /, trust_radius: onp.ToFloat) -> tuple[onp.Array1D[np.float64], bool]: ... From 9ffb701c6058416aec97c031f14a3fc6dd4f3007 Mon Sep 17 00:00:00 2001 From: jorenham Date: Sun, 1 Dec 2024 17:31:40 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8=20complete=20`optimize.=5Ftrlib`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scipy-stubs/optimize/_trlib/__init__.pyi | 26 ++++++++++++++++++-- scipy-stubs/optimize/_trlib/_trlib.pyi | 31 ++++++++++++------------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/scipy-stubs/optimize/_trlib/__init__.pyi b/scipy-stubs/optimize/_trlib/__init__.pyi index b7082c8d..cdf3b5ca 100644 --- a/scipy-stubs/optimize/_trlib/__init__.pyi +++ b/scipy-stubs/optimize/_trlib/__init__.pyi @@ -1,6 +1,28 @@ -from scipy._typing import Untyped +from collections.abc import Callable +from typing import Protocol, type_check_only + +import numpy as np +import optype.numpy as onp from ._trlib import TRLIBQuadraticSubproblem __all__ = ["TRLIBQuadraticSubproblem", "get_trlib_quadratic_subproblem"] -def get_trlib_quadratic_subproblem(tol_rel_i: float = -2.0, tol_rel_b: float = -3.0, disp: bool = False) -> Untyped: ... +@type_check_only +class _SubproblemFactory(Protocol): + def __call__( + self, + /, + x: onp.ToFloat1D, + fun: Callable[[onp.Array1D[np.float64]], onp.ToFloat], + jac: Callable[[onp.Array1D[np.float64]], onp.ToFloat1D], + hess: Callable[[onp.Array1D[np.float64]], onp.ToFloat2D] | None = None, + hessp: Callable[[onp.Array1D[np.float64], onp.Array1D[np.float64]], onp.ToFloat1D] | None = None, + ) -> TRLIBQuadraticSubproblem: ... + +### + +def get_trlib_quadratic_subproblem( + tol_rel_i: onp.ToFloat = -2.0, + tol_rel_b: onp.ToFloat = -3.0, + disp: onp.ToBool = False, +) -> _SubproblemFactory: ... diff --git a/scipy-stubs/optimize/_trlib/_trlib.pyi b/scipy-stubs/optimize/_trlib/_trlib.pyi index 0d237d0b..41598a73 100644 --- a/scipy-stubs/optimize/_trlib/_trlib.pyi +++ b/scipy-stubs/optimize/_trlib/_trlib.pyi @@ -1,26 +1,27 @@ -from collections.abc import Mapping +# https://github.com/scipy/scipy/blob/v1.14.1/scipy/optimize/_trlib/_trlib.pyx + +from collections.abc import Callable, Mapping from typing import Final -from typing_extensions import Never, override +from typing_extensions import Never import numpy as np import optype.numpy as onp -from scipy._typing import Untyped, UntypedCallable from scipy.optimize._trustregion import BaseQuadraticSubproblem -__test__: Final[Mapping[Never, Never]] +### + +__test__: Final[Mapping[Never, Never]] # undocumented -class TRLIBQuadraticSubproblem(BaseQuadraticSubproblem): +class TRLIBQuadraticSubproblem(BaseQuadraticSubproblem): # undocumented def __init__( self, /, - x: Untyped, - fun: UntypedCallable, - jac: UntypedCallable, - hess: UntypedCallable | None, - hessp: UntypedCallable | None, - tol_rel_i: float = -2.0, - tol_rel_b: float = -3.0, - disp: bool = False, + x: onp.ToFloat1D, + fun: Callable[[onp.Array1D[np.float64]], onp.ToFloat], + jac: Callable[[onp.Array1D[np.float64]], onp.ToFloat1D], + hess: Callable[[onp.Array1D[np.float64]], onp.ToFloat2D] | None, + hessp: Callable[[onp.Array1D[np.float64], onp.Array1D[np.float64]], onp.ToFloat1D] | None, + tol_rel_i: onp.ToFloat = -2.0, + tol_rel_b: onp.ToFloat = -3.0, + disp: onp.ToBool = False, ) -> None: ... - @override - def solve(self, /, trust_radius: float | np.float64) -> tuple[onp.ArrayND[np.float64], bool]: ... From 32f51140a6dd0d3b8e1ac8f2bd42281769d58f15 Mon Sep 17 00:00:00 2001 From: jorenham Date: Sun, 1 Dec 2024 17:32:00 +0100 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20complete=20`optimize.=5Ftrustre?= =?UTF-8?q?gion*`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scipy-stubs/optimize/_trustregion.pyi | 2 - scipy-stubs/optimize/_trustregion_dogleg.pyi | 10 +-- scipy-stubs/optimize/_trustregion_exact.pyi | 76 ++++++++++++-------- scipy-stubs/optimize/_trustregion_krylov.pyi | 37 +++++++--- scipy-stubs/optimize/_trustregion_ncg.pyi | 8 +-- 5 files changed, 77 insertions(+), 56 deletions(-) diff --git a/scipy-stubs/optimize/_trustregion.pyi b/scipy-stubs/optimize/_trustregion.pyi index 78aba72d..1abb19e1 100644 --- a/scipy-stubs/optimize/_trustregion.pyi +++ b/scipy-stubs/optimize/_trustregion.pyi @@ -1,4 +1,3 @@ -import abc from collections.abc import Callable import numpy as np @@ -39,5 +38,4 @@ class BaseQuadraticSubproblem: ) -> list[float | np.float64]: ... # list of size 2 # - @abc.abstractmethod def solve(self, /, trust_radius: onp.ToFloat) -> tuple[onp.Array1D[np.float64], bool]: ... diff --git a/scipy-stubs/optimize/_trustregion_dogleg.pyi b/scipy-stubs/optimize/_trustregion_dogleg.pyi index ce01967a..b0189fa5 100644 --- a/scipy-stubs/optimize/_trustregion_dogleg.pyi +++ b/scipy-stubs/optimize/_trustregion_dogleg.pyi @@ -1,13 +1,9 @@ -from typing_extensions import override - import numpy as np -from scipy._typing import Untyped +import optype.numpy as onp from ._trustregion import BaseQuadraticSubproblem __all__: list[str] = [] class DoglegSubproblem(BaseQuadraticSubproblem): - def cauchy_point(self, /) -> Untyped: ... - def newton_point(self, /) -> Untyped: ... - @override - def solve(self, /, trust_radius: float | np.float64) -> Untyped: ... + def cauchy_point(self, /) -> onp.Array1D[np.float64]: ... + def newton_point(self, /) -> onp.Array1D[np.float64]: ... diff --git a/scipy-stubs/optimize/_trustregion_exact.pyi b/scipy-stubs/optimize/_trustregion_exact.pyi index ffb48947..f7042728 100644 --- a/scipy-stubs/optimize/_trustregion_exact.pyi +++ b/scipy-stubs/optimize/_trustregion_exact.pyi @@ -1,47 +1,63 @@ -from typing_extensions import override +from collections.abc import Callable +from typing import ClassVar, Concatenate, Final, TypedDict +from typing_extensions import Unpack, override import numpy as np import optype.numpy as onp -from scipy._typing import Untyped, UntypedCallable, UntypedTuple +from ._minimize import OptimizeResult from ._trustregion import BaseQuadraticSubproblem __all__ = ["IterativeSubproblem", "_minimize_trustregion_exact", "estimate_smallest_singular_value", "singular_leading_submatrix"] +class _TrustRegionOptions(TypedDict, total=False): + initial_trust_radius: onp.ToFloat + max_trust_radius: onp.ToFloat + eta: onp.ToFloat + gtol: onp.ToFloat + +### + def _minimize_trustregion_exact( - fun: UntypedCallable, - x0: Untyped, - args: UntypedTuple = (), - jac: Untyped | None = None, - hess: Untyped | None = None, - **trust_region_options: Untyped, -) -> Untyped: ... -def estimate_smallest_singular_value(U: Untyped) -> Untyped: ... -def gershgorin_bounds(H: Untyped) -> Untyped: ... -def singular_leading_submatrix(A: Untyped, U: Untyped, k: Untyped) -> Untyped: ... + fun: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat], + x0: onp.ToFloat1D, + args: tuple[object, ...] = (), + jac: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat1D] | None = None, + hess: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat2D] | None = None, + **trust_region_options: Unpack[_TrustRegionOptions], +) -> OptimizeResult: ... +def estimate_smallest_singular_value(U: onp.ToFloat2D) -> tuple[float | np.float64, onp.Array1D[np.float64]]: ... +def gershgorin_bounds(H: onp.ToFloat2D) -> tuple[float | np.float64, float | np.float64]: ... +def singular_leading_submatrix( + A: onp.ToFloat2D, + U: onp.ToFloat2D, + k: onp.ToJustInt, +) -> tuple[float | np.float64, onp.Array1D[np.float64]]: ... class IterativeSubproblem(BaseQuadraticSubproblem): - UPDATE_COEFF: float - EPS: Untyped + UPDATE_COEFF: ClassVar[float] = 0.01 + EPS: ClassVar[float | np.float64] = ... + + CLOSE_TO_ZERO: Final[float | np.float64] + dimension: Final[int] previous_tr_radius: int - lambda_lb: Untyped niter: int - k_easy: Untyped - k_hard: Untyped - dimension: Untyped - hess_inf: Untyped - hess_fro: Untyped - CLOSE_TO_ZERO: Untyped - lambda_current: Untyped + k_easy: float | np.float64 + k_hard: float | np.float64 + hess_inf: float | np.float64 + hess_fro: float | np.float64 + lambda_lb: float | np.float64 | None # intially `None` + lambda_current: float | np.float64 # set in `solve()` + def __init__( self, /, - x: Untyped, - fun: UntypedCallable, - jac: Untyped, - hess: Untyped, - hessp: Untyped | None = None, - k_easy: float = 0.1, - k_hard: float = 0.2, + x: onp.ToFloat1D, + fun: Callable[[onp.Array1D[np.float64]], onp.ToFloat], + jac: Callable[[onp.Array1D[np.float64]], onp.ToFloat1D], + hess: Callable[[onp.Array1D[np.float64]], onp.ToFloat2D], + hessp: Callable[[onp.Array1D[np.float64], onp.Array1D[np.float64]], onp.ToFloat1D] | None = None, + k_easy: onp.ToFloat = 0.1, + k_hard: onp.ToFloat = 0.2, ) -> None: ... @override - def solve(self, /, trust_radius: float | np.float64) -> tuple[onp.ArrayND[np.float64], bool]: ... + def solve(self, /, tr_radius: onp.ToFloat) -> tuple[onp.ArrayND[np.float64], bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] diff --git a/scipy-stubs/optimize/_trustregion_krylov.pyi b/scipy-stubs/optimize/_trustregion_krylov.pyi index 1a4e996b..c4fa7817 100644 --- a/scipy-stubs/optimize/_trustregion_krylov.pyi +++ b/scipy-stubs/optimize/_trustregion_krylov.pyi @@ -1,14 +1,31 @@ +from collections.abc import Callable +from typing import Concatenate, TypedDict, type_check_only +from typing_extensions import Unpack + +import numpy as np +import optype.numpy as onp +from ._minimize import OptimizeResult + __all__ = ["_minimize_trust_krylov"] -from scipy._typing import Untyped, UntypedCallable, UntypedTuple +@type_check_only +class _TrustRegionOptions(TypedDict, total=False): + initial_trust_radius: onp.ToFloat + max_trust_radius: onp.ToFloat + eta: onp.ToFloat + gtol: onp.ToFloat + maxiter: onp.ToJustInt + disp: onp.ToBool + +### def _minimize_trust_krylov( - fun: UntypedCallable, - x0: Untyped, - args: UntypedTuple = (), - jac: Untyped | None = None, - hess: Untyped | None = None, - hessp: Untyped | None = None, - inexact: bool = True, - **trust_region_options: Untyped, -) -> Untyped: ... + fun: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat], + x0: onp.ToFloat1D, + args: tuple[object, ...] = (), + jac: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat1D] | None = None, + hess: Callable[Concatenate[onp.Array1D[np.float64], ...], onp.ToFloat2D] | None = None, + hessp: Callable[Concatenate[onp.Array1D[np.float64], onp.Array1D[np.float64], ...], onp.ToFloat1D] | None = None, + inexact: onp.ToBool = True, + **trust_region_options: Unpack[_TrustRegionOptions], +) -> OptimizeResult: ... diff --git a/scipy-stubs/optimize/_trustregion_ncg.pyi b/scipy-stubs/optimize/_trustregion_ncg.pyi index adfb4677..1e8ba926 100644 --- a/scipy-stubs/optimize/_trustregion_ncg.pyi +++ b/scipy-stubs/optimize/_trustregion_ncg.pyi @@ -1,11 +1,5 @@ -from typing_extensions import override - -import numpy as np -from scipy._typing import Untyped from ._trustregion import BaseQuadraticSubproblem __all__: list[str] = [] -class CGSteihaugSubproblem(BaseQuadraticSubproblem): - @override - def solve(self, /, trust_radius: float | np.float64) -> Untyped: ... +class CGSteihaugSubproblem(BaseQuadraticSubproblem): ...