Skip to main content

Module objective

Module objective 

Source
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.