Source code for scm.glompo.stoppers.optimizertype

from .basestopper import BaseStopper
from ..core.optimizerlogger import BaseLogger
from ..optimizers.baseoptimizer import BaseOptimizer
from ..optimizers.armc import ARMCOptimizer
from ..optimizers.cmawrapper import CMAOptimizer
from ..optimizers.random import RandomOptimizer
from ..optimizers.scipy import Scipy
from ..optimizers.simplegrid import SimpleGridOptimizer
from ...plams.core.settings import Settings

__all__ = ("OptimizerType", "OPTIMIZER_DICT")


OPTIMIZER_DICT = {
    "adaptiveratemontecarlo": ARMCOptimizer,
    "cmaes": CMAOptimizer,
    "randomsampling": RandomOptimizer,
    "scipy": Scipy,
    "gridsampling": SimpleGridOptimizer,
}
try:
    from ..optimizers.nevergrad import Nevergrad

    OPTIMIZER_DICT["nevergrad"] = Nevergrad
except ImportError:
    pass


[docs]class OptimizerType(BaseStopper): """Stops an optimizer based on its class. Intended for use with other stoppers to allow for specific stopping conditions based on the type of optimizer. :Parameters: opt_to_stop :class:`.BaseOptimizer` class which is targeted. :Returns: bool ``True`` if the tested optimizer is an instance of ``opt_to_stop``. :Examples: >>> OptimizerType(CMAOptimizer) & StopperA() | OptimizerType(Nevergrad) & StopperB() In this case ``StopperA`` will only stop :class:`.CMAOptimizer`\\s and ``StopperB`` will only stop :class:`scm.glompo.optimizers.nevergrad.Nevergrad` optimizers. This is useful in cases where exploratory optimizers should be stopped quickly but late stage optimizers encouraged to converge and iterate for longer periods. """ def __init__(self, opt_to_stop: BaseOptimizer): super().__init__() if issubclass(opt_to_stop, BaseOptimizer): self.opt_to_stop = opt_to_stop.__name__ else: raise TypeError("Optimizer not recognized, must be a subclass of BaseOptimizer") def __call__(self, log: BaseLogger, best_opt_id: int, tested_opt_id: int) -> bool: self.last_result = self.opt_to_stop == log.get_metadata(tested_opt_id, "opt_type") return self.last_result def __amssettings__(self, s: Settings) -> Settings: opt_dict = {v.__name__: k for k, v in OPTIMIZER_DICT.items()} s.input.ams.Stopper.Type = "OptimizerType" s.input.ams.Stopper.OptimizerType = opt_dict[self.opt_to_stop] return s