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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use crate::analysis::differential_equation::ordinary::ExplicitODE;
use crate::algebra::linear::Vector;
use crate::algebra::abstr::Real;
use std::fmt::Debug;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ButcherFixedStepSize<T>
{
a: Vec<T>,
b: Vec<T>,
c: Vec<T>,
}
impl<T> ButcherFixedStepSize<T>
{
pub fn new(a: Vec<T>, b: Vec<T>, c: Vec<T>) -> ButcherFixedStepSize<T>
{
ButcherFixedStepSize
{
a,
b,
c
}
}
}
impl<T> ButcherFixedStepSize<T>
where T: Real
{
pub fn do_step<F>(self: &Self, prob: &F, t_n: &T, x_n: &Vector<T>, h: &T) -> Vector<T>
where F: ExplicitODE<T>,
{
let mut k: Vec<Vector<T>> = Vec::with_capacity(self.b.len());
let (rows, _columns): (usize, usize) = x_n.dim();
k.push(prob.func(t_n, x_n));
for j in 1..self.b.len()
{
let i_b = (j - 1) * j / 2;
let i_e = i_b + j;
let sum= self.a[i_b..i_e].iter().zip(k.iter()).map(|(a_jl, k_l)| k_l * a_jl).fold(Vector::zero(rows), | a, b| a + b);
k.push(prob.func(&(*t_n + self.c[j - 1] * *h), &(x_n + &(&sum * h))));
}
let sum: Vector<T> = self.b.iter().zip(k.iter()).map(|(b, k_j)| k_j * b).fold(Vector::zero(rows), |a, b| a + b);
x_n + &(&sum * h)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ButcherAdaptiveStepSize<T>
{
a: Vec<T>,
b: Vec<T>,
b_s: Vec<T>,
c: Vec<T>,
}
impl<T: Debug> ButcherAdaptiveStepSize<T>
{
pub fn new(a: Vec<T>, b: Vec<T>, b_s: Vec<T>, c: Vec<T>) -> ButcherAdaptiveStepSize<T>
{
ButcherAdaptiveStepSize
{
a,
b,
b_s,
c
}
}
}
impl<T> ButcherAdaptiveStepSize<T>
where T: Real + Debug
{
pub fn do_step<F>(self: &Self, prob: &F, t_n: &T, x_n: &Vector<T>, h: &T) -> (Vector<T>, Vector<T>)
where F: ExplicitODE<T>,
{
let mut k: Vec<Vector<T>> = Vec::with_capacity(self.b.len());
let (rows, _columns): (usize, usize) = x_n.dim();
k.push(prob.func(t_n, x_n));
for j in 1..self.b.len()
{
let i_b = (j - 1) * j / 2;
let i_e = i_b + j;
let sum= self.a[i_b..i_e].iter().zip(k.iter()).map(|(a_jl, k_l)| k_l * a_jl).fold(Vector::zero(rows), | a, b| a + b);
let k_i = prob.func(&(*t_n + self.c[j - 1] * *h), &(x_n + &(&sum * h))) ;
k.push(k_i);
}
let sum: Vector<T> = self.b.iter().zip(k.iter()).map(|(b, k_j)| k_j * b).fold(Vector::zero(rows), |a, b| a + b);
let x_n_1 = x_n + &(&sum * h);
let sum_s: Vector<T> = self.b_s.iter().zip(k.iter()).map(|(b, k_j)| k_j * b).fold(Vector::zero(rows), |a, b| a + b);
let x_s_n_1 = x_n + &(&sum_s * h);
(x_n_1, x_s_n_1)
}
}