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
pub trait FunctionArguments: Into<Vec<f64>> + Clone + std::convert::TryFrom<Vec<f64>> {}
impl FunctionArguments for [f64; 2] {}
impl FunctionArguments for [f64; 3] {}
impl FunctionArguments for [f64; 4] {}
impl FunctionArguments for [f64; 5] {}
pub struct EulerSolver<A, F> {
derivative_function: F,
phantom: std::marker::PhantomData<A>,
}
impl<A: FunctionArguments, F: Fn(&A) -> f64> EulerSolver<A, F> {
pub fn new(derivative_function: F) -> EulerSolver<A, F> {
EulerSolver {
derivative_function,
phantom: std::marker::PhantomData,
}
}
pub fn do_step(&self, values: A, step: f64) -> A {
let f_eval: f64 = (self.derivative_function)(&values);
let as_vec: Vec<f64> = values.into();
let mut next_values: Vec<f64> = vec![];
let mut value: f64 = as_vec.get(0).unwrap() + step * f_eval;
let t_new: f64 = as_vec.get(as_vec.len() - 1).unwrap() + step;
next_values.push(value);
as_vec[1..as_vec.len() - 1].into_iter().for_each(|x| {
let new_val: f64 = x + step * value;
value = new_val;
next_values.push(new_val);
});
next_values.push(t_new);
match A::try_from(next_values) {
Ok(v) => v,
Err(_) => panic!("Nooo"),
}
}
}