use fastrand::Rng; use gomez::nalgebra as na; use gomez::{Domain, Function, Optimizer, OptimizerDriver, Problem, Sample}; use na::{storage::StorageMut, Dyn, IsContiguous, Vector}; struct Random { rng: Rng, } impl Random { fn new(rng: Rng) -> Self { Self { rng } } } impl Optimizer for Random where F::Field: Sample, { const NAME: &'static str = "Random"; type Error = std::convert::Infallible; fn opt_next( &mut self, f: &F, dom: &Domain, x: &mut Vector, ) -> Result where Sx: StorageMut + IsContiguous, { // Randomly sample in the domain. dom.sample(x, &mut self.rng); // We must compute the value. Ok(f.apply(x)) } } // https://en.wikipedia.org/wiki/Rosenbrock_function struct Rosenbrock { a: f64, b: f64, } impl Problem for Rosenbrock { type Field = f64; fn domain(&self) -> Domain { Domain::rect(vec![-10.0, -10.0], vec![10.0, 10.0]) } } impl Function for Rosenbrock { fn apply(&self, x: &na::Vector) -> Self::Field where Sx: na::Storage + IsContiguous, { (self.a - x[0]).powi(2) + self.b * (x[1] - x[0].powi(2)).powi(2) } } fn main() { let f = Rosenbrock { a: 1.0, b: 1.0 }; let mut optimizer = OptimizerDriver::builder(&f) .with_algo(|_, _| Random::new(Rng::new())) .build(); optimizer .find(|state| { println!("f(x) = {}\tx = {:?}", state.fx(), state.x()); state.iter() >= 100 }) .unwrap(); }