gomez/core/solver.rs
1use nalgebra::{storage::StorageMut, Dyn, IsContiguous, Vector};
2
3use super::{domain::Domain, system::System};
4
5/// Interface of a solver.
6///
7/// A solver is an iterative algorithm which takes a point _x_ and computes the
8/// next step in the solving process. Repeated calls to the next step should
9/// eventually converge into a solution _x'_ in successful cases.
10///
11/// If you implement a solver, please reach out to discuss if we could include
12/// it in gomez.
13///
14/// ## Implementing a solver
15///
16/// Here is an implementation of a random "solver" which randomly generates
17/// values in a hope that a solution can be found with enough luck.
18///
19/// ```rust
20/// use gomez::nalgebra as na;
21/// use gomez::{Domain, Sample, Solver, System};
22/// use na::{storage::StorageMut, Dyn, IsContiguous, Vector};
23/// use fastrand::Rng;
24///
25/// struct Random {
26/// rng: Rng,
27/// }
28///
29/// impl Random {
30/// fn new(rng: Rng) -> Self {
31/// Self { rng }
32/// }
33/// }
34///
35/// impl<R: System> Solver<R> for Random
36/// where
37/// R::Field: Sample,
38/// {
39/// const NAME: &'static str = "Random";
40/// type Error = std::convert::Infallible;
41///
42/// fn solve_next<Sx, Srx>(
43/// &mut self,
44/// r: &R,
45/// dom: &Domain<R::Field>,
46/// x: &mut Vector<R::Field, Dyn, Sx>,
47/// rx: &mut Vector<R::Field, Dyn, Srx>,
48/// ) -> Result<(), Self::Error>
49/// where
50/// Sx: StorageMut<R::Field, Dyn> + IsContiguous,
51/// Srx: StorageMut<R::Field, Dyn>,
52/// {
53/// // Randomly sample in the domain.
54/// dom.sample(x, &mut self.rng);
55///
56/// // We must compute the residuals.
57/// r.eval(x, rx);
58///
59/// Ok(())
60/// }
61/// }
62/// ```
63pub trait Solver<R: System> {
64 /// Name of the solver.
65 const NAME: &'static str;
66
67 /// Error while computing the next step.
68 type Error;
69
70 /// Computes the next step in the solving process.
71 ///
72 /// The value of `x` is the current point. After the method returns, `x`
73 /// should hold the variable values of the performed step and `rx` _must_
74 /// contain residuals of that step as computed by [`System::eval`].
75 ///
76 /// The implementations _can_ assume that subsequent calls to `solve_next`
77 /// pass the value of `x` as was returned in the previous iteration.
78 fn solve_next<Sx, Srx>(
79 &mut self,
80 r: &R,
81 dom: &Domain<R::Field>,
82 x: &mut Vector<R::Field, Dyn, Sx>,
83 rx: &mut Vector<R::Field, Dyn, Srx>,
84 ) -> Result<(), Self::Error>
85 where
86 Sx: StorageMut<R::Field, Dyn> + IsContiguous,
87 Srx: StorageMut<R::Field, Dyn>;
88}