equations/
equations.rs

1use gomez::nalgebra as na;
2use gomez::{Domain, Problem, SolverDriver, System};
3use na::{Dyn, IsContiguous};
4
5// https://en.wikipedia.org/wiki/Rosenbrock_function
6struct Rosenbrock {
7    a: f64,
8    b: f64,
9}
10
11impl Problem for Rosenbrock {
12    type Field = f64;
13
14    fn domain(&self) -> Domain<Self::Field> {
15        Domain::unconstrained(2)
16    }
17}
18
19impl System for Rosenbrock {
20    fn eval<Sx, Srx>(
21        &self,
22        x: &na::Vector<Self::Field, Dyn, Sx>,
23        rx: &mut na::Vector<Self::Field, Dyn, Srx>,
24    ) where
25        Sx: na::storage::Storage<Self::Field, Dyn> + IsContiguous,
26        Srx: na::storage::StorageMut<Self::Field, Dyn>,
27    {
28        rx[0] = (self.a - x[0]).powi(2);
29        rx[1] = self.b * (x[1] - x[0].powi(2)).powi(2);
30    }
31}
32
33fn main() -> Result<(), String> {
34    let r = Rosenbrock { a: 1.0, b: 1.0 };
35    let mut solver = SolverDriver::builder(&r)
36        .with_initial(vec![10.0, -5.0])
37        .build();
38
39    let tolerance = 1e-6;
40
41    let (_, norm) = solver
42        .find(|state| {
43            println!(
44                "iter = {}\t|| r(x) || = {}\tx = {:?}",
45                state.iter(),
46                state.norm(),
47                state.x()
48            );
49            state.norm() <= tolerance || state.iter() >= 100
50        })
51        .map_err(|error| format!("{error}"))?;
52
53    if norm <= tolerance {
54        Ok(())
55    } else {
56        Err("did not converge".to_string())
57    }
58}