Skip to main content
Minimizers drive the optimization loop. This guide shows you how to create your own beyond the built-in simulated annealing and tempering.

The Minimizer base class

BAGEL provides two levels of abstraction for custom minimizers:
  1. Minimizer — full control over the optimization loop. You implement minimize_system() from scratch.
  2. MonteCarloMinimizer — MCMC with hooks. You get the Metropolis accept/reject loop for free and override _before_step() and/or _after_step() to customize behavior.
Most custom minimizers should extend MonteCarloMinimizer, which handles:
  • Temperature schedule management
  • Metropolis acceptance criterion
  • Callback execution
  • Logging infrastructure
  • Best-system tracking

Implementing minimize_system()

If you need full control (e.g., for a non-MCMC algorithm like a genetic algorithm), subclass Minimizer directly:

Using MonteCarloMinimizer hooks

For MCMC-based approaches, extend MonteCarloMinimizer and override the hooks: _before_step(system, step) -> System — called before each MC step. Use this to modify the system before the mutation is proposed (e.g., adjust parameters based on progress). _after_step(system, best_system, step, new_best, accept, **kwargs) -> (System, should_stop) — called after each MC step. The base implementation handles callback execution, best-system preservation, and logging. Return (system, should_stop) where should_stop=True triggers early termination. The built-in SimulatedAnnealing and SimulatedTempering are both implemented as MonteCarloMinimizer subclasses — they only differ in how they construct the temperature schedule.

MonteCarloMinimizer parameters

When subclassing MonteCarloMinimizer, pass these to super().__init__():
  • mutator — the MutationProtocol to use for proposing sequence changes
  • temperature — a float (constant), list, or numpy array defining the temperature at each step
  • n_steps — total number of MC steps
  • acceptance_criterion — currently "metropolis" (default)
  • preserve_best_system_every_n_steps — if set, resets the current system to the best system every N steps
  • callbacks — list of Callback instances for logging and monitoring

Example: a custom minimizer

Here is a minimizer that implements an exponential cooling schedule (instead of linear):
Usage: