import numpy as np
from bagel.minimizer import MonteCarloMinimizer
from bagel.mutation import MutationProtocol
from bagel.callbacks import Callback
import pathlib as pl
from typing import Any
class ExponentialAnnealing(MonteCarloMinimizer):
"""Simulated annealing with exponential temperature decay."""
def __init__(
self,
mutator: MutationProtocol,
initial_temperature: float,
final_temperature: float,
n_steps: int,
experiment_name: str | None = None,
log_frequency: int = 100,
log_path: pl.Path | str | None = None,
callbacks: list[Callback] | None = None,
**kwargs: Any,
) -> None:
if experiment_name is None:
experiment_name = f"exponential_annealing"
super().__init__(
mutator=mutator,
temperature=initial_temperature, # placeholder, overwritten below
n_steps=n_steps,
experiment_name=experiment_name,
log_frequency=log_frequency,
log_path=log_path,
callbacks=callbacks,
**kwargs,
)
# Overwrite the temperature schedule with exponential decay
self.temperature_schedule = initial_temperature * np.exp(
np.linspace(0, np.log(final_temperature / initial_temperature), n_steps)
)