Expand description
The Objective trait defines what gets optimized.
§Closures work directly
Any Fn(&mut Trial) -> Result<V, E> closure automatically implements
Objective, so you can pass closures straight to
Study::optimize:
use optimizer::prelude::*;
let study: Study<f64> = Study::new(Direction::Minimize);
let x = FloatParam::new(-10.0, 10.0).name("x");
study
.optimize(50, |trial: &mut optimizer::Trial| {
let v = x.suggest(trial)?;
Ok::<_, Error>((v - 3.0).powi(2))
})
.unwrap();§Structs for lifecycle hooks
For richer control — early stopping or per-trial logging — implement
Objective on a struct and pass it to the same
Study::optimize method:
use std::ops::ControlFlow;
use optimizer::Objective;
use optimizer::prelude::*;
struct QuadraticWithEarlyStopping {
x: FloatParam,
target: f64,
}
impl Objective<f64> for QuadraticWithEarlyStopping {
type Error = Error;
fn evaluate(&self, trial: &mut Trial) -> Result<f64> {
let v = self.x.suggest(trial)?;
Ok((v - 3.0).powi(2))
}
fn after_trial(&self, _study: &Study<f64>, trial: &CompletedTrial<f64>) -> ControlFlow<()> {
if trial.value < self.target {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
let study: Study<f64> = Study::new(Direction::Minimize);
let obj = QuadraticWithEarlyStopping {
x: FloatParam::new(-10.0, 10.0).name("x"),
target: 1.0,
};
study.optimize(200, obj).unwrap();
assert!(study.best_value().unwrap() < 1.0);Traits§
- Objective
- Defines an objective function with lifecycle hooks for optimization.