Skip to content

Commit 2273895

Browse files
lindonlindon
authored andcommitted
Sensible error if nan in objective evaluation from trust-region step
1 parent 34e709b commit 2273895

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

dfols/controller.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
__all__ = ['Controller', 'ExitInformation', 'EXIT_SLOW_WARNING', 'EXIT_MAXFUN_WARNING', 'EXIT_SUCCESS',
4343
'EXIT_INPUT_ERROR', 'EXIT_TR_INCREASE_ERROR', 'EXIT_LINALG_ERROR', 'EXIT_FALSE_SUCCESS_WARNING',
44-
'EXIT_AUTO_DETECT_RESTART_WARNING']
44+
'EXIT_AUTO_DETECT_RESTART_WARNING', 'EXIT_EVAL_ERROR']
4545

4646
module_logger = logging.getLogger(__name__)
4747

@@ -54,6 +54,7 @@
5454
EXIT_INPUT_ERROR = -1 # error, bad inputs
5555
EXIT_TR_INCREASE_ERROR = -2 # error, trust region step increased model value
5656
EXIT_LINALG_ERROR = -3 # error, linalg error (singular matrix encountered)
57+
EXIT_EVAL_ERROR = -4 # error, objective evaluation error (e.g. nan result received)
5758

5859

5960
class ExitInformation(object):
@@ -83,11 +84,13 @@ def message(self, with_stem=True):
8384
return "Error (linear algebra): " + self.msg
8485
elif self.flag == EXIT_FALSE_SUCCESS_WARNING:
8586
return "Warning (max false good steps): " + self.msg
87+
elif self.flag == EXIT_EVAL_ERROR:
88+
return "Error (function evaluation): " + self.msg
8689
else:
8790
return "Unknown exit flag: " + self.msg
8891

8992
def able_to_do_restart(self):
90-
if self.flag in [EXIT_TR_INCREASE_ERROR, EXIT_TR_INCREASE_WARNING, EXIT_LINALG_ERROR, EXIT_SLOW_WARNING, EXIT_AUTO_DETECT_RESTART_WARNING]:
93+
if self.flag in [EXIT_TR_INCREASE_ERROR, EXIT_TR_INCREASE_WARNING, EXIT_LINALG_ERROR, EXIT_SLOW_WARNING, EXIT_AUTO_DETECT_RESTART_WARNING, EXIT_EVAL_ERROR]:
9194
return True
9295
elif self.flag in [EXIT_MAXFUN_WARNING, EXIT_INPUT_ERROR]:
9396
return False

dfols/solver.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,17 @@ def solve_main(objfun, x0, args, xl, xu, projections, npt, rhobeg, rhoend, maxfu
516516
x = control.model.as_absolute_coordinates(xnew)
517517
number_of_samples = max(nsamples(control.delta, control.rho, current_iter, nruns_so_far), 1)
518518
rvec_list, f_list, num_samples_run, exit_info = control.evaluate_objective(x, number_of_samples, params)
519+
if np.any(np.isnan(rvec_list)):
520+
# Just exit without saving the current point
521+
# We should be able to do a hard restart though, because it's unlikely
522+
# that we will get the same trust-region step after expanding the radius/re-initialising
523+
module_logger.warning("NaN encountered in evaluation of trust-region step")
524+
if params("interpolation.throw_error_on_nans"):
525+
raise np.linalg.LinAlgError("NaN encountered in objective evaluations")
526+
527+
exit_info = ExitInformation(EXIT_EVAL_ERROR, "NaN received from objective function evaluation")
528+
nruns_so_far += 1
529+
break # quit
519530
if exit_info is not None:
520531
if num_samples_run > 0:
521532
control.model.save_point(x, np.mean(rvec_list[:num_samples_run, :], axis=0), num_samples_run,

0 commit comments

Comments
 (0)