Skip to content

Commit 08b6ba3

Browse files
committed
optimize: method-specific overloads and options for minimize_scalar
1 parent 25c6e67 commit 08b6ba3

File tree

1 file changed

+133
-48
lines changed

1 file changed

+133
-48
lines changed

scipy-stubs/optimize/_minimize.pyi

Lines changed: 133 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from collections.abc import Callable, Mapping, Sequence
22
from typing import Any, Concatenate, Final, Literal, Protocol, TypeAlias, TypedDict, TypeVar, overload, type_check_only
3+
from typing_extensions import LiteralString
34

45
import numpy as np
56
import optype.numpy as onp
7+
import optype.numpy.compat as npc
68
from scipy._typing import Falsy, Truthy
79
from scipy.sparse.linalg import LinearOperator
810
from ._hessian_update_strategy import HessianUpdateStrategy
@@ -13,9 +15,13 @@ __all__ = ["minimize", "minimize_scalar"]
1315

1416
###
1517

18+
_T = TypeVar("_T")
19+
_Tuple2: TypeAlias = tuple[_T, _T]
20+
_Tuple3: TypeAlias = tuple[_T, _T, _T]
1621
_Args: TypeAlias = tuple[object, ...]
1722

1823
_Float: TypeAlias = float | np.float64
24+
_Floating: TypeAlias = float | npc.floating
1925
_Float1D: TypeAlias = onp.Array1D[np.float64]
2026
_Float2D: TypeAlias = onp.Array2D[np.float64]
2127

@@ -26,6 +32,13 @@ _Fun1Dp: TypeAlias = Callable[Concatenate[_Float1D, _Float1D, ...], _RT]
2632

2733
_FDMethod: TypeAlias = Literal["2-point", "3-point", "cs"]
2834

35+
_ToBracket: TypeAlias = Sequence[_Tuple2[onp.ToFloat] | _Tuple3[onp.ToFloat]]
36+
_ToBound: TypeAlias = _Tuple2[onp.ToFloat]
37+
_Ignored: TypeAlias = object
38+
39+
_MinimizeScalarResultT = TypeVar("_MinimizeScalarResultT", bound=_MinimizeScalarResultBase)
40+
_MinimizeScalarResultT_co = TypeVar("_MinimizeScalarResultT_co", bound=_MinimizeScalarResultBase, covariant=True)
41+
2942
@type_check_only
3043
class _CallbackResult(Protocol):
3144
def __call__(self, /, intermediate_result: OptimizeResult) -> None: ...
@@ -38,88 +51,117 @@ class _CallbackVector(Protocol):
3851
class _MinimizeMethodFun(Protocol):
3952
def __call__(self, fun: _Fun1D[onp.ToFloat], x0: onp.ToFloat1D, /, args: _Args, **kwargs: Any) -> OptimizeResult: ...
4053

54+
@type_check_only
55+
class _MinimizeScalarMethodFun(Protocol[_MinimizeScalarResultT_co]):
56+
def __call__(
57+
self,
58+
fun: _Fun0D[onp.ToFloat],
59+
/,
60+
*,
61+
args: _Args,
62+
bracket: _ToBracket,
63+
bound: _ToBound,
64+
**options: Any,
65+
) -> _MinimizeScalarResultT_co: ...
66+
4167
@type_check_only
4268
class _MinimizeOptions(TypedDict, total=False):
4369
# Nelder-Mead, Powell, CG, BFGS, Newton-CG
44-
return_all: bool
70+
return_all: onp.ToBool
4571
# Nelder-Mead, Powell, CG, BFGS, L-BFGS-B, Newton-CG, TNC, COBYLA, COBYQA, SLSQP, trust-constr
46-
disp: bool
72+
disp: onp.ToBool
4773
# Nelder-Mead, Powell, CG, BFGS, L-BFGS-B, Newton-CG, COBYLA, SLSQP, trust-constr
4874
maxiter: int
4975
# Nelder-Mead, Powell, COBYQA
5076
maxfev: int
5177
# TNC
5278
maxCGit: int
53-
offset: float
54-
stepmx: float
55-
accuracy: float
56-
minfev: float
57-
rescale: float
79+
offset: _Floating
80+
stepmx: _Floating
81+
accuracy: _Floating
82+
minfev: _Floating
83+
rescale: _Floating
5884
# L-BFGS-B, TNC
5985
maxfun: int
6086
# L-BFGS-B
6187
maxcor: int
6288
iprint: int
6389
maxls: int
6490
# Nelder-Mead
65-
initial_simplex: onp.ToArrayND
66-
adaptive: bool
67-
xatol: float
68-
fatol: float
91+
initial_simplex: onp.ToFloatND
92+
adaptive: onp.ToBool
93+
xatol: _Floating
94+
fatol: _Floating
6995
# CG, BFGS, L-BFGS-B, dogleg, trust-ncg, trust-exact, TNC, trust-constr
70-
gtol: float
96+
gtol: _Floating
7197
# Powell, Newton-CG, TNC, trust-constr
72-
xtol: float
98+
xtol: _Floating
7399
# Powell, L-BFGS-B, TNC, SLSQP
74-
ftol: float
100+
ftol: _Floating
75101
# BFGS
76-
xrtol: float
77-
hess_inv0: onp.ArrayND[np.floating[Any]]
102+
xrtol: _Floating
103+
hess_inv0: onp.ArrayND[npc.floating]
78104
# COBYLA
79-
tol: float
80-
catool: float
81-
rhobeg: float
82-
f_target: float
105+
tol: _Floating
106+
catool: _Floating
107+
rhobeg: _Floating
108+
f_target: _Floating
83109
# COBYQA
84-
feasibility_tol: float
85-
final_tr_radius: float
110+
feasibility_tol: _Floating
111+
final_tr_radius: _Floating
86112
# Powell
87-
direc: onp.ArrayND[np.floating[Any]]
113+
direc: onp.ArrayND[npc.floating]
88114
# CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP
89-
eps: float | onp.ArrayND[np.floating[Any]]
115+
eps: _Floating | onp.ArrayND[npc.floating]
90116
# CG, BFGS, Newton-CG
91-
c1: float
92-
c2: float
117+
c1: _Floating
118+
c2: _Floating
93119
# CG, BFGS
94-
norm: float
120+
norm: _Floating
95121
# CG, BFGS, L-BFGS-B, TNC, SLSQP, trust-constr
96-
finite_diff_rel_step: onp.ToFloat | onp.ToArrayND
122+
finite_diff_rel_step: onp.ToFloat | onp.ToFloatND
97123
# dogleg, trust-ncg, trust-exact
98-
initial_trust_radius: float
99-
max_trust_radius: float
124+
initial_trust_radius: _Floating
125+
max_trust_radius: _Floating
100126
# COBYQA, trust-constr
101-
initial_tr_radius: float
127+
initial_tr_radius: _Floating
102128
# trust-constr
103-
barrier_tol: float
104-
sparse_jacobian: bool
105-
initial_constr_penalty: float
106-
initial_barrier_parameter: float
107-
initial_barrier_tolerance: float
129+
barrier_tol: _Floating
130+
sparse_jacobian: onp.ToBool
131+
initial_constr_penalty: _Floating
132+
initial_barrier_parameter: _Floating
133+
initial_barrier_tolerance: _Floating
108134
factorization_method: Literal["NormalEquation", "AugmentedSystem", "QRFactorization", "SVDFactorization"]
109135
verbose: Literal[0, 1, 2, 3]
110136
# dogleg, trust-ncg, trust-exact, TNC
111-
eta: float
137+
eta: _Floating
112138
# trust-krylov
113-
inexact: bool
139+
inexact: onp.ToBool
114140
# TNC (list of floats), COBYQA (bool)
115-
scale: Sequence[float] | bool
141+
scale: Sequence[_Floating] | onp.ToBool
142+
143+
@type_check_only
144+
class _MinimizeScalarOptionsCommon(TypedDict, total=False):
145+
maxiter: int
146+
disp: Literal[0, 1, 2, 3]
116147

117148
@type_check_only
118-
class _MinimizeScalarResult(_OptimizeResult):
149+
class _MinimizeScalarOptionsBracketed(_MinimizeScalarOptionsCommon, TypedDict, total=False):
150+
xtol: _Floating
151+
152+
@type_check_only
153+
class _MinimizeScalarOptionsBounded(_MinimizeScalarOptionsCommon, TypedDict, total=False):
154+
xatol: _Floating
155+
156+
@type_check_only
157+
class _MinimizeScalarResultBase(_OptimizeResult):
119158
x: _Float
120159
fun: _Float
160+
161+
@type_check_only
162+
class _MinimizeScalarResult(_MinimizeScalarResultBase):
121163
success: bool
122-
message: str
164+
message: LiteralString
123165
nit: int
124166
nfev: int
125167

@@ -129,11 +171,11 @@ MINIMIZE_METHODS: Final[list[MethodMimimize]] = ...
129171
MINIMIZE_METHODS_NEW_CB: Final[list[MethodMimimize]] = ...
130172
MINIMIZE_SCALAR_METHODS: Final[list[MethodMinimizeScalar]] = ...
131173

132-
# NOTE: This `OptimizeResult` "flavor" is Specific to `minimize`
174+
# NOTE: This `OptimizeResult` "flavor" is specific to `minimize`
133175
class OptimizeResult(_OptimizeResult):
134176
success: bool
135177
status: int
136-
message: str
178+
message: LiteralString
137179
x: _Float1D
138180
nit: int
139181
maxcv: float # requires `bounds`
@@ -180,7 +222,7 @@ def minimize(
180222
fun: _Fun1D[tuple[onp.ToFloat, onp.ToFloat1D]],
181223
x0: onp.ToFloat1D,
182224
args: _Args = (),
183-
method: _MinimizeMethodFun | MethodMimimize | None = None,
225+
method: MethodMimimize | _MinimizeMethodFun | None = None,
184226
*,
185227
jac: Truthy,
186228
hess: _Fun1D[onp.ToFloat2D] | _FDMethod | HessianUpdateStrategy | None = None,
@@ -193,15 +235,58 @@ def minimize(
193235
) -> OptimizeResult: ...
194236

195237
#
238+
@overload # method="brent" or method="golden"
196239
def minimize_scalar(
197240
fun: _Fun0D[onp.ToFloat],
198-
bracket: Sequence[tuple[onp.ToFloat, onp.ToFloat] | tuple[onp.ToFloat, onp.ToFloat, onp.ToFloat]] | None = None,
199-
bounds: Bound | None = None,
241+
bracket: _ToBracket,
242+
bounds: None = None,
200243
args: _Args = (),
201-
method: MethodMinimizeScalar | Callable[..., _MinimizeScalarResult] | None = None,
244+
method: Literal["brent", "golden"] | None = None, # default: "brent"
202245
tol: onp.ToFloat | None = None,
203-
options: Mapping[str, object] | None = None,
246+
options: _MinimizeScalarOptionsBracketed | None = None,
204247
) -> _MinimizeScalarResult: ...
248+
@overload # bound=<given> (positional)
249+
def minimize_scalar(
250+
fun: _Fun0D[onp.ToFloat],
251+
bracket: _Ignored | None,
252+
bounds: _ToBound,
253+
args: _Args,
254+
method: Literal["bounded"] | None = None,
255+
tol: onp.ToFloat | None = None,
256+
options: _MinimizeScalarOptionsBounded | None = None,
257+
) -> _MinimizeScalarResult: ...
258+
@overload # bound=<given> (keyword)
259+
def minimize_scalar(
260+
fun: _Fun0D[onp.ToFloat],
261+
bracket: _Ignored | None = None,
262+
*,
263+
bounds: _ToBound,
264+
args: _Args,
265+
method: Literal["bounded"] | None = None,
266+
tol: onp.ToFloat | None = None,
267+
options: _MinimizeScalarOptionsBounded | None = None,
268+
) -> _MinimizeScalarResult: ...
269+
@overload # method=<custom> (positional)
270+
def minimize_scalar(
271+
fun: _Fun0D[onp.ToFloat],
272+
bracket: _ToBracket | None,
273+
bounds: _ToBound | None,
274+
args: _Args,
275+
method: _MinimizeScalarMethodFun[_MinimizeScalarResultT],
276+
tol: onp.ToFloat | None = None,
277+
options: Mapping[str, object] | None = None,
278+
) -> _MinimizeScalarResultT: ...
279+
@overload # method=<custom> (keyword)
280+
def minimize_scalar(
281+
fun: _Fun0D[onp.ToFloat],
282+
bracket: _ToBracket | None = None,
283+
bounds: _ToBound | None = None,
284+
args: _Args = (),
285+
*,
286+
method: _MinimizeScalarMethodFun[_MinimizeScalarResultT],
287+
tol: onp.ToFloat | None = None,
288+
options: Mapping[str, object] | None = None,
289+
) -> _MinimizeScalarResultT: ...
205290

206291
# undocumented
207292
def standardize_bounds(bounds: Bounds, x0: onp.ToFloat1D, meth: MethodMimimize) -> Bounds | list[Bound]: ...

0 commit comments

Comments
 (0)