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