Skip to content

Commit

Permalink
Implement use of max_iter for nelder_mead engine. (#42)
Browse files Browse the repository at this point in the history
Implement use of `max_iter` for nelder_mead engine.

Also adds some clarifying logs in the report
  • Loading branch information
bosonie committed Mar 24, 2021
1 parent e3e006d commit 0927fbc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
17 changes: 17 additions & 0 deletions aiida_optimize/engines/_nelder_mead.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__( # pylint: disable=too-many-arguments
next_submit='submit_initialize',
next_update=None,
finished=False,
exceeded_max_iters=False,
result_state=None,
):
super(_NelderMeadImpl, self).__init__(logger=logger, result_state=result_state)
Expand Down Expand Up @@ -112,6 +113,7 @@ def __init__( # pylint: disable=too-many-arguments
self.next_update = next_update

self.finished = finished
self.exceeded_max_iters = exceeded_max_iters

def _get_values(self, outputs):
return [get_nested_result(res, self.result_key).value for _, res in sorted(outputs.items())]
Expand Down Expand Up @@ -144,6 +146,9 @@ def new_iter(self): # pylint: disable=missing-function-docstring
self.next_update = 'finalize'
return []
self.num_iter += 1
self._logger.report(
f'Start of Nelder-Mead iteration {self.num_iter}, max number of iterations: {self.max_iter}.'
)
xr = (1 + RHO) * self.xbar - RHO * self.simplex[-1]
self.next_update = 'choose_step'
return [self._to_input_list(xr)]
Expand All @@ -170,6 +175,14 @@ def check_finished(self):
f_diff_max = np.max(np.abs(self.fun_simplex[1:] - self.fun_simplex[0]))
self._logger.report('Maximum function difference: {}'.format(f_diff_max))
self.finished = (x_dist_max < self.xtol) and (f_diff_max < self.ftol)
self._logger.report(
f'End of Nelder-Mead iteration {self.num_iter}, max number of iterations: {self.max_iter}.'
)
if not self.finished:
if self.num_iter >= self.max_iter:
self._logger.report('Number of iterations exceeded the maximum. Stop.')
self.exceeded_max_iters = True
self.finished = True

@update_method()
def choose_step(self, outputs):
Expand Down Expand Up @@ -276,6 +289,10 @@ def _state(self):
def is_finished(self):
return self.finished

@property
def is_finished_ok(self):
return self.is_finished and not self.exceeded_max_iters

def _create_inputs(self):
return getattr(self, self.next_submit)()

Expand Down
19 changes: 19 additions & 0 deletions tests/test_nelder_mead.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,22 @@ def test_nelder_mead(
x_exact=x_exact,
f_exact=f_exact,
)


def test_nelder_mead_max_iter(check_error):
"""
Test the OptimizationWorkChain with the Nelder-Mead engine in the case
when the set `max_iter` is reached. This triggers the 202 exut status.
"""

check_error(
engine=NelderMead,
engine_kwargs=dict(
simplex=[[1.2, 0.9], [1., 2.], [2., 1.]],
xtol=1e-1,
ftol=1e-1,
max_iter=10,
),
func_workchain_name='rosenbrock',
exit_status=202
)

0 comments on commit 0927fbc

Please sign in to comment.