Skip to content

Commit 38f2db0

Browse files
committed
merge from gfo_pop, tests, renaming
1 parent 6eceedb commit 38f2db0

2 files changed

Lines changed: 39 additions & 25 deletions

File tree

src/optimagic/optimizers/gfo_optimizers.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class GFOCommonOptions:
5757
stopping_maxtime: NonNegativeFloat | None = None
5858
"""Maximum time in seconds before termination."""
5959

60-
stopping_funval: float | None = None
60+
convergence_target_value: float | None = None
6161
""""Stop the optimization if the objective function is less than this value."""
6262

6363
convergence_iter_noimprove: PositiveInt = 1000000 # do not want to trigger this
@@ -77,8 +77,13 @@ class GFOCommonOptions:
7777
"""Whether to cache evaluated param and function values in a dictionary for
7878
lookup."""
7979

80-
extra_start_points: list[PyTree] | None = None
81-
"""List of additional start points for the optimization run."""
80+
extra_start_params: list[PyTree] | None = None
81+
"""List of additional start points for the optimization run.
82+
83+
In case of population based optimizers, the initial_population can be provided
84+
via `extra_start_params`
85+
86+
"""
8287

8388
warm_start: pd.DataFrame | None = None
8489
"""Pandas dataframe that contains score and paramter information that will be
@@ -604,15 +609,15 @@ def _gfo_internal(
604609
"tol_rel": common.convergence_ftol_rel,
605610
}
606611

607-
# define search space, initial params, population, constraints
612+
# define search space, initial params, initial_population and constraints
608613
opt = optimizer(
609614
search_space=_get_search_space_gfo(
610615
problem.bounds,
611616
common.n_grid_points,
612617
problem.converter,
613618
),
614619
initialize=_get_initialize_gfo(
615-
x0, common.n_init, common.extra_start_points, problem.converter
620+
x0, common.n_init, common.extra_start_params, problem.converter
616621
),
617622
constraints=_get_gfo_constraints(),
618623
random_state=common.seed,
@@ -624,16 +629,18 @@ def objective_function(para: dict[str, float]) -> float | NDArray[np.float64]:
624629
return -problem.fun(x)
625630

626631
# negate in case of minimize
627-
stopping_funval = (
628-
-1 * common.stopping_funval if common.stopping_funval is not None else None
632+
convergence_target_value = (
633+
-1 * common.convergence_target_value
634+
if common.convergence_target_value is not None
635+
else None
629636
)
630637

631638
# run optimization
632639
opt.search(
633640
objective_function=objective_function,
634641
n_iter=common.stopping_maxiter,
635642
max_time=common.stopping_maxtime,
636-
max_score=stopping_funval,
643+
max_score=convergence_target_value,
637644
early_stopping=early_stopping,
638645
memory=common.caching,
639646
memory_warm_start=common.warm_start,
@@ -683,8 +690,8 @@ def _get_initialize_gfo(
683690
extra_start_points: list[PyTree] | None,
684691
converter: Converter,
685692
) -> dict[str, Any]:
686-
"""Set initial params x0, additional start points for the optimization run or the
687-
initial_population. Here, warm_start is actually extra_start_points.
693+
"""Set initial params x0, additional start params for the optimization run or the
694+
initial_population. Here, warm_start is actually extra_start_params.
688695
689696
Args:
690697
x0: initial param

tests/optimagic/optimization/test_many_algorithms.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
if algo.algo_info.supports_bounds
2929
]
3030

31-
PRECISION_LOOKUP = {"scipy_trust_constr": 3}
31+
PRECISION_LOOKUP = {
32+
"scipy_trust_constr": 3,
33+
"iminuit_migrad": 2,
34+
}
3235

3336

3437
@pytest.fixture
@@ -40,7 +43,7 @@ def _get_options(algo):
4043
options = {}
4144
"Max time before termination"
4245
if hasattr(algo, "stopping_maxtime"):
43-
options.update({"stopping_maxtime": 200})
46+
options.update({"stopping_maxtime": 10})
4447

4548
"Fix seed if algorithm is stochastic"
4649
if hasattr(algo, "seed"):
@@ -49,10 +52,6 @@ def _get_options(algo):
4952

5053

5154
def _get_required_decimals(algorithm, algo):
52-
# Do not expect solution if algorithm is experimental
53-
if algo.algo_info.experimental:
54-
return 0
55-
5655
if algorithm in PRECISION_LOOKUP:
5756
return PRECISION_LOOKUP[algorithm]
5857
else:
@@ -65,14 +64,22 @@ def sos(x):
6564

6665

6766
def _get_params_and_binding_bounds(algo):
68-
params = np.array([3, 2, -3])
69-
if algo.algo_info.supports_infinite_bounds:
70-
bounds = Bounds(
71-
lower=np.array([1, -np.inf, -np.inf]), upper=np.array([np.inf, np.inf, -1])
72-
)
67+
if algo.algo_info.is_global:
68+
params = np.array([0.5, -0.5])
69+
bounds = Bounds(lower=np.array([0.25, -1]), upper=np.array([1, -0.25]))
70+
expected = np.array([0.25, -0.25])
71+
7372
else:
74-
bounds = Bounds(lower=np.array([1, -10, -10]), upper=np.array([10, 10, -1]))
75-
expected = np.array([1, 0, -1])
73+
params = np.array([3, 2, -3])
74+
if algo.algo_info.supports_infinite_bounds:
75+
bounds = Bounds(
76+
lower=np.array([1, -np.inf, -np.inf]),
77+
upper=np.array([np.inf, np.inf, -1]),
78+
)
79+
else:
80+
bounds = Bounds(lower=np.array([1, -10, -10]), upper=np.array([10, 10, -1]))
81+
expected = np.array([1, 0, -1])
82+
7683
return params, bounds, expected
7784

7885

@@ -128,8 +135,8 @@ def test_sum_of_squares_on_local_algorithms(algorithm, algo):
128135
def _get_params_and_bounds_on_global_and_bounded(algo):
129136
if algo.algo_info.is_global:
130137
params = np.array([0.35, 0.35])
131-
bounds = Bounds(lower=np.array([0.2, -0.5]), upper=np.array([1, 0.5]))
132-
expected = np.array([0.2, 0])
138+
bounds = Bounds(lower=np.array([-0.2, -0.5]), upper=np.array([1, 0.5]))
139+
expected = np.array([0, 0])
133140
else:
134141
params = np.arange(3)
135142
bounds = Bounds(lower=np.full(3, -10), upper=np.full(3, 10))

0 commit comments

Comments
 (0)