use differential_equations::prelude::*;
use faer::Mat;
#[derive(Clone)]
struct IntegrationODE;
impl ODE<f64, Mat<f64>> for IntegrationODE {
fn diff(&self, t: f64, _y: &Mat<f64>, dydt: &mut Mat<f64>) {
*dydt.get_mut(0, 0) = t;
}
}
fn main() {
let ode = IntegrationODE;
let t0 = 0.0;
let tf: f64 = 5.0;
let y0 = Mat::from_fn(1, 1, |_, _| 0.0);
let solution = IVP::ode(&ode, t0, tf, y0.clone())
.method(ExplicitRungeKutta::rkf45())
.solve()
.unwrap();
println!("Numerical Integration Example:");
println!("-----------------------------");
println!("t\t\ty");
for (t, y) in solution.iter() {
println!("{:.6}\t{:.6}", t, *y.get(0, 0));
}
let analytical_solution = tf.powi(2) / 2.0;
let numerical_solution = *solution.y.last().unwrap().get(0, 0);
let error = (analytical_solution - numerical_solution).abs();
println!("-----------------------------");
println!("Analytical Solution at tf: {:.6}", analytical_solution);
println!("Numerical Solution at tf: {:.6}", numerical_solution);
println!("Absolute Error: {:.6}", error);
println!("-----------------------------");
println!("Dense Output Example:");
let solution_dense = IVP::ode(&ode, t0, tf, y0.clone())
.dense(2) .method(ExplicitRungeKutta::rkf45())
.solve()
.unwrap();
println!("t\t\ty");
for (t, y) in solution_dense.iter() {
println!("{:.6}\t{:.6}", t, *y.get(0, 0));
}
println!("-----------------------------");
println!("Even t-out Example:");
let solution_even = IVP::ode(&ode, t0, tf, y0.clone())
.even(1.0) .method(ExplicitRungeKutta::rkf45())
.solve()
.unwrap();
println!("t\t\ty");
for (t, y) in solution_even.iter() {
println!("{:.6}\t{:.6}", t, *y.get(0, 0));
}
println!("-----------------------------");
println!("t-out Points Example:");
let t_out = vec![0.0, 2.0, 5.0];
let solution_t_out = IVP::ode(&ode, t0, tf, y0)
.t_eval(t_out)
.method(ExplicitRungeKutta::rkf45())
.solve()
.unwrap();
println!("t\t\ty");
for (t, y) in solution_t_out.iter() {
println!("{:.6}\t{:.6}", t, *y.get(0, 0));
}
}