class NelderAndMeadTermination2(Termination): def __init__(self, **kwargs): super().__init__() self.default = SingleObjectiveDefaultTermination(**kwargs) def _do_continue(self, algorithm): do_continue = self.default.do_continue(algorithm) # if the default says do not continue just follow that if not do_continue: return False # additionally check for degenerated simplex else: X = algorithm.pop.get("X") # degenerated simplex - get all edges and minimum and maximum length D = vectorized_cdist(X, X) val = D[np.triu_indices(len(X), 1)] min_e, max_e = val.min(), val.max() # either if the maximum length is very small or the ratio is degenerated is_degenerated = max_e < 1e-16 or min_e / max_e < 1e-16 return not is_degenerated
class PatternSearchTermination(Termination): def __init__(self, eps=1e-5, **kwargs): super().__init__() self.default = SingleObjectiveDefaultTermination(**kwargs) self.eps = eps def do_continue(self, algorithm): decision_default = self.default.do_continue(algorithm) delta = np.max(np.abs(algorithm.explr_delta)) if delta < self.eps: return decision_default else: return True