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
use structure::matrix::*;
use structure::vector::*;
use structure::dual::*;
use numerical::utils::*;
use util::non_macro::*;
pub fn bdf1<F>(t_init: f64, ys_init: Vec<f64>, f: F, h: f64, rtol: f64, num: usize) -> Matrix
where F: Fn(Dual, Vec<Dual>) -> Vec<Dual> + Copy
{
let mut ys = ys_init.clone();
let mut t = t_init.clone();
let mut records = zeros(num + 1, ys_init.len() + 1);
for i in 0 .. (num+1) {
records.subs_row(i, concat(vec![t], ys.clone()));
t += h;
ys = one_step_bdf1(t, ys.clone(), f, h, rtol);
}
records
}
pub fn one_step_bdf1<F>(t: f64, ys: Vec<f64>, f: F, h: f64, rtol: f64) -> Vec<f64>
where F: Fn(Dual, Vec<Dual>) -> Vec<Dual> + Copy
{
let new_t = t + h;
let new_ys_0 = ys.add(
&(f(dual(t, 0.), ys.conv_dual()).values().fmap(|y| h*y))
);
let mut iter_prev_ys = new_ys_0;
let mut iter_next_ys = non_auto_update(new_t, ys.clone(), iter_prev_ys.clone(), f, h);
let mut err = iter_next_ys.sub(&iter_prev_ys).norm();
let mut max_iter = 0;
while err >= rtol && max_iter <= 10 {
iter_prev_ys = iter_next_ys.clone();
iter_next_ys = non_auto_update(new_t, ys.clone(), iter_prev_ys.clone(), f, h);
err = iter_next_ys.sub(&iter_prev_ys).norm();
max_iter += 1;
}
iter_next_ys
}
#[allow(non_snake_case)]
fn non_auto_update<F>(t: f64, yn: Vec<f64>, ys: Vec<f64>, f: F, h: f64) -> Vec<f64>
where F: Fn(Dual, Vec<Dual>) -> Vec<Dual> + Copy
{
let n = ys.len();
let f_vec = |_xs: Vec<Dual>| f(dual(t, 0.), ys.conv_dual());
let Df = jacobian(ys.clone(), f_vec);
let I = eye(n);
let DF = I - h * Df;
let f_xs = f(dual(t, 0.), ys.conv_dual()).values();
let F_ys = ys.sub(&yn).sub(&(f_xs.fmap(|x| h*x)));
ys.sub(&(DF.inv().unwrap() % F_ys).col(0))
}