Skip to content

Commit f2eea28

Browse files
authored
Merge pull request #222 from jorenham/optimize.shgo
`optimize`: complete `shgo`, improve `basinhopping`
2 parents 49cf93c + d35acc6 commit f2eea28

File tree

4 files changed

+62
-177
lines changed

4 files changed

+62
-177
lines changed

scipy-stubs/optimize/_basinhopping.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
from collections.abc import Callable, Mapping
1+
from collections.abc import Callable
22
from typing import Concatenate, Literal, Protocol, TypeAlias, TypeVar, type_check_only
33

44
import numpy as np
55
import optype.numpy as onp
66
from scipy._typing import Seed
77
from ._minimize import OptimizeResult as _MinimizeResult
88
from ._optimize import OptimizeResult as _OptimizeResult
9+
from ._typing import MinimizerKwargs
910

1011
__all__ = ["basinhopping"]
1112

@@ -53,7 +54,7 @@ def basinhopping(
5354
niter: onp.ToJustInt = 100,
5455
T: onp.ToFloat = 1.0,
5556
stepsize: onp.ToFloat = 0.5,
56-
minimizer_kwargs: Mapping[str, object] | None = None,
57+
minimizer_kwargs: MinimizerKwargs | None = None,
5758
take_step: Callable[[_Float1D], onp.ToFloat] | None = None,
5859
accept_test: _AcceptTestFun[onp.ToFloat] | None = None,
5960
callback: _CallbackFun[float] | _CallbackFun[np.float64] | None = None,

scipy-stubs/optimize/_dual_annealing.pyi

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
11
from collections.abc import Callable
2-
from typing import Concatenate, Literal, TypeAlias, TypedDict, type_check_only
2+
from typing import Concatenate, Literal, TypeAlias
33

44
import numpy as np
55
import optype.numpy as onp
66
from scipy._typing import Seed
77
from scipy.optimize import OptimizeResult as _OptimizeResult
88
from ._constraints import Bounds
9-
from ._hessian_update_strategy import HessianUpdateStrategy
10-
from ._minimize import _MinimizeOptions
11-
from ._typing import Constraints, MethodMimimize
9+
from ._typing import MinimizerKwargs
1210

1311
__all__ = ["dual_annealing"]
1412

1513
_Float1D: TypeAlias = onp.Array1D[np.float64]
16-
_FDMethod: TypeAlias = Literal["2-point", "3-point", "cs"]
17-
18-
@type_check_only
19-
class _MinimizeKwargs(TypedDict, total=False):
20-
method: MethodMimimize
21-
jac: Callable[Concatenate[_Float1D, ...], onp.ToFloat1D] | _FDMethod | bool
22-
hess: Callable[Concatenate[_Float1D, ...], onp.ToFloat2D] | _FDMethod | HessianUpdateStrategy
23-
hessp: Callable[Concatenate[_Float1D, _Float1D, ...], onp.ToFloat1D]
24-
constraints: Constraints
25-
tol: onp.ToFloat
26-
options: _MinimizeOptions
2714

2815
###
2916

@@ -43,7 +30,7 @@ def dual_annealing(
4330
bounds: Bounds | tuple[onp.ToFloat1D, onp.ToFloat1D] | onp.ToFloat2D,
4431
args: tuple[object, ...] = (),
4532
maxiter: onp.ToJustInt = 1_000,
46-
minimizer_kwargs: _MinimizeKwargs | None = None,
33+
minimizer_kwargs: MinimizerKwargs | None = None,
4734
initial_temp: onp.ToFloat = 5_230.0,
4835
restart_temp_ratio: onp.ToFloat = 2e-05,
4936
visit: onp.ToFloat = 2.62,

scipy-stubs/optimize/_shgo.pyi

Lines changed: 41 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,46 @@
1-
from collections.abc import Callable, Iterable, Mapping, Sequence
2-
from typing import Any, Final, Literal, TypeAlias, TypeVar
1+
from collections.abc import Callable, Iterable, Sequence
2+
from typing import Concatenate, Literal, TypeAlias, TypedDict, TypeVar, type_check_only
33

44
import numpy as np
5-
import numpy.typing as npt
65
import optype.numpy as onp
7-
from scipy._typing import EnterSelfMixin, Untyped, UntypedArray, UntypedCallable
6+
from ._constraints import Bounds
87
from ._optimize import OptimizeResult as _OptimizeResult
9-
from ._typing import Constraints
8+
from ._typing import Constraints, MinimizerKwargs
109

1110
__all__ = ["shgo"]
1211

13-
_MinimizerKwargs: TypeAlias = Mapping[str, object] # TODO(jorenham): TypedDict
14-
_Options: TypeAlias = Mapping[str, object] # TODO(jorenham): TypedDict
15-
16-
_SamplingMethodName: TypeAlias = Literal["simplicial", "halton", "sobol"]
17-
_SamplingMethodFunc: TypeAlias = Callable[[int, int], onp.ArrayND[np.float64]]
18-
_SamplingMethod: TypeAlias = _SamplingMethodName | _SamplingMethodFunc
19-
2012
_VT = TypeVar("_VT")
2113
_RT = TypeVar("_RT")
2214

15+
_Float: TypeAlias = float | np.float64
16+
_Float1D: TypeAlias = onp.Array1D[np.float64]
17+
_Fun1D: TypeAlias = Callable[Concatenate[_Float1D, ...], _RT]
18+
19+
@type_check_only
20+
class _SHGOOptions(TypedDict, total=False):
21+
f_min: _Float
22+
f_tol: _Float
23+
maxiter: int
24+
maxfev: int
25+
maxev: int
26+
mmaxtime: _Float
27+
minhgrd: int
28+
symmetry: Sequence[int] | onp.ToBool
29+
jac: _Fun1D[onp.ToFloat1D] | onp.ToBool # gradient
30+
hess: _Fun1D[onp.ToFloat2D]
31+
hessp: Callable[Concatenate[_Float1D, _Float1D, ...], onp.ToFloat1D]
32+
minimize_every_iter: onp.ToBool
33+
local_iter: int
34+
infty_constraints: onp.ToBool
35+
disp: onp.ToBool
36+
37+
###
38+
2339
class OptimizeResult(_OptimizeResult):
24-
x: onp.ArrayND[np.float64]
25-
xl: list[onp.ArrayND[np.float64]]
26-
fun: float | np.float64
27-
funl: list[float | np.float64]
40+
x: _Float1D
41+
xl: Sequence[_Float1D]
42+
fun: _Float
43+
funl: Sequence[_Float]
2844
success: bool
2945
message: str
3046
nfev: int
@@ -33,151 +49,17 @@ class OptimizeResult(_OptimizeResult):
3349
nlhev: int # undocumented
3450
nit: int
3551

36-
###
37-
38-
class SHGO(EnterSelfMixin):
39-
func: UntypedCallable
40-
bounds: Untyped
41-
args: tuple[object, ...]
42-
callback: UntypedCallable
43-
dim: int
44-
constraints: Constraints
45-
min_cons: Untyped
46-
g_cons: Untyped
47-
g_args: Untyped
48-
minimizer_kwargs: _MinimizerKwargs
49-
f_min_true: Untyped
50-
minimize_every_iter: bool
51-
maxiter: int
52-
maxfev: int
53-
maxev: Untyped
54-
maxtime: Untyped
55-
minhgrd: Untyped
56-
symmetry: Untyped
57-
infty_cons_sampl: bool
58-
local_iter: bool
59-
disp: bool
60-
min_solver_args: Untyped
61-
stop_global: bool
62-
break_routine: bool
63-
iters: int
64-
iters_done: int
65-
n: int
66-
nc: int
67-
n_prc: int
68-
n_sampled: int
69-
fn: int
70-
hgr: int
71-
qhull_incremental: bool
72-
HC: Untyped
73-
iterate_complex: Untyped
74-
sampling_method: Untyped
75-
qmc_engine: Untyped
76-
sampling: Untyped
77-
sampling_function: Untyped
78-
stop_l_iter: bool
79-
stop_complex_iter: bool
80-
minimizer_pool: Untyped
81-
LMC: Untyped
82-
res: Untyped
83-
init: Untyped
84-
f_tol: Untyped
85-
f_lowest: Untyped
86-
x_lowest: Untyped
87-
hgrd: Untyped
88-
Ind_sorted: Untyped
89-
Tri: Untyped
90-
points: Untyped
91-
minimizer_pool_F: Untyped
92-
X_min: Untyped
93-
X_min_cache: Untyped
94-
Y: Untyped
95-
Z: Untyped
96-
Ss: Untyped
97-
ind_f_min: Untyped
98-
C: Untyped
99-
Xs: Untyped
100-
def __init__(
101-
self,
102-
/,
103-
func: UntypedCallable,
104-
bounds: Untyped,
105-
args: tuple[object, ...] = (),
106-
constraints: Constraints | None = None,
107-
n: Untyped | None = None,
108-
iters: Untyped | None = None,
109-
callback: UntypedCallable | None = None,
110-
minimizer_kwargs: Mapping[str, Any] | None = None,
111-
options: Mapping[str, Any] | None = None,
112-
sampling_method: _SamplingMethod = "simplicial",
113-
workers: int = 1,
114-
) -> None: ...
115-
def init_options(self, /, options: Untyped) -> None: ...
116-
def iterate_all(self, /) -> None: ...
117-
def find_minima(self, /) -> None: ...
118-
def find_lowest_vertex(self, /) -> None: ...
119-
def finite_iterations(self, /) -> Untyped: ...
120-
def finite_fev(self, /) -> Untyped: ...
121-
def finite_ev(self, /) -> None: ...
122-
def finite_time(self, /) -> None: ...
123-
def finite_precision(self, /) -> Untyped: ...
124-
def finite_homology_growth(self, /) -> Untyped: ...
125-
def stopping_criteria(self, /) -> Untyped: ...
126-
def iterate(self, /) -> None: ...
127-
def iterate_hypercube(self, /) -> None: ...
128-
def iterate_delaunay(self, /) -> None: ...
129-
def minimizers(self, /) -> Untyped: ...
130-
def minimise_pool(self, /, force_iter: bool = False) -> None: ...
131-
def sort_min_pool(self, /) -> None: ...
132-
def trim_min_pool(self, /, trim_ind: Untyped) -> None: ...
133-
def g_topograph(self, /, x_min: Untyped, X_min: Untyped) -> Untyped: ...
134-
def construct_lcb_simplicial(self, /, v_min: Untyped) -> Untyped: ...
135-
def construct_lcb_delaunay(self, /, v_min: Untyped, ind: Untyped | None = None) -> Untyped: ...
136-
def minimize(self, /, x_min: Untyped, ind: Untyped | None = None) -> Untyped: ...
137-
def sort_result(self, /) -> Untyped: ...
138-
def fail_routine(self, /, mes: str = "Failed to converge") -> None: ...
139-
def sampled_surface(self, /, infty_cons_sampl: bool = False) -> None: ...
140-
def sampling_custom(self, /, n: Untyped, dim: Untyped) -> Untyped: ...
141-
def sampling_subspace(self, /) -> None: ...
142-
def sorted_samples(self, /) -> Untyped: ...
143-
def delaunay_triangulation(self, /, n_prc: int = 0) -> Untyped: ...
144-
145-
# undocumented
146-
class LMap:
147-
v: Untyped
148-
x_l: Untyped
149-
lres: Untyped
150-
f_min: Untyped
151-
lbounds: list[Untyped]
152-
def __init__(self, /, v: Untyped) -> None: ...
153-
154-
# undocumented
155-
class LMapCache:
156-
cache: Final[dict[tuple[np.number[Any], ...], Untyped]]
157-
xl_maps_set: Final[set[Untyped]]
158-
v_maps: Final[list[Untyped]]
159-
lbound_maps: Final[list[Untyped]]
160-
161-
xl_maps: list[Untyped] | UntypedArray
162-
f_maps: list[Untyped]
163-
size: int
164-
165-
def __init__(self, /) -> None: ...
166-
def __getitem__(self, v: npt.ArrayLike, /) -> Untyped: ...
167-
def add_res(self, /, v: Untyped, lres: Untyped, bounds: Untyped | None = None) -> None: ...
168-
def sort_cache_result(self, /) -> dict[str, Untyped]: ... # TODO(jorenham): TypedDict
169-
17052
def shgo(
171-
func: UntypedCallable,
172-
bounds: Untyped,
53+
func: _Fun1D[onp.ToFloat],
54+
bounds: tuple[onp.ToFloat | onp.ToFloat1D, onp.ToFloat | onp.ToFloat1D] | Bounds,
17355
args: tuple[object, ...] = (),
17456
constraints: Constraints | None = None,
175-
n: int = 100,
176-
iters: int = 1,
177-
callback: Callable[[onp.Array1D[np.float64]], None] | None = None,
178-
minimizer_kwargs: _MinimizerKwargs | None = None, # TODO(jorenham): TypedDict
179-
options: _Options | None = None, # TODO(jorenham): TypedDict
180-
sampling_method: _SamplingMethod = "simplicial",
57+
n: onp.ToJustInt = 100,
58+
iters: onp.ToJustInt = 1,
59+
callback: Callable[[_Float1D], None] | None = None,
60+
minimizer_kwargs: MinimizerKwargs | None = None,
61+
options: _SHGOOptions | None = None,
62+
sampling_method: Callable[[int, int], onp.ToFloat2D] | Literal["simplicial", "halton", "sobol"] = "simplicial",
18163
*,
182-
workers: int | Callable[[Callable[[_VT], _RT], Iterable[_VT]], Sequence[_RT]] = 1,
64+
workers: onp.ToJustInt | Callable[[Callable[[_VT], _RT], Iterable[_VT]], Sequence[_RT]] = 1,
18365
) -> OptimizeResult: ...

scipy-stubs/optimize/_typing.pyi

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ from typing_extensions import NotRequired, TypedDict
55
import numpy as np
66
import optype.numpy as onp
77
from ._constraints import Bounds as _Bounds, LinearConstraint, NonlinearConstraint
8+
from ._hessian_update_strategy import HessianUpdateStrategy
9+
from ._minimize import _MinimizeOptions
810

911
__all__ = [
1012
"Bound",
@@ -17,6 +19,7 @@ __all__ = [
1719
"MethodMimimize",
1820
"MethodMinimizeScalar",
1921
"MethodRootScalar",
22+
"MinimizerKwargs",
2023
"Solver",
2124
"TRSolver",
2225
]
@@ -84,3 +87,15 @@ MethodAll: TypeAlias = Literal[
8487
MethodLinprog,
8588
_MethodQuadraticAssignment,
8689
]
90+
91+
_FDMethod: TypeAlias = Literal["2-point", "3-point", "cs"]
92+
93+
@type_check_only
94+
class MinimizerKwargs(TypedDict, total=False):
95+
method: MethodMimimize
96+
jac: Callable[Concatenate[_Float1D, ...], onp.ToFloat1D] | _FDMethod | bool
97+
hess: Callable[Concatenate[_Float1D, ...], onp.ToFloat2D] | _FDMethod | HessianUpdateStrategy
98+
hessp: Callable[Concatenate[_Float1D, _Float1D, ...], onp.ToFloat1D]
99+
constraints: Constraints
100+
tol: onp.ToFloat
101+
options: _MinimizeOptions

0 commit comments

Comments
 (0)