From 7b2cca872467921cd335c2379ee09a78b5b7ec4c Mon Sep 17 00:00:00 2001 From: bluthej Date: Wed, 10 Sep 2025 21:14:30 +0200 Subject: [PATCH 1/4] Fix doc comment --- src/ivp/rk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ivp/rk.rs b/src/ivp/rk.rs index a1a2e2c..f34d858 100644 --- a/src/ivp/rk.rs +++ b/src/ivp/rk.rs @@ -622,7 +622,7 @@ impl RungeKuttaCoefficients<4> for RK23Coefficients { /// Bogacki-Shampine method for solving an IVP. /// -/// Defines the Butcher Tableaux for a 5(4) order adaptive +/// Defines the Butcher Tableaux for a 3(2) order adaptive /// Runge-Kutta method. Uses [`RungeKutta`] to do the actual solving. /// Provides an implementation of the [`IVPSolver`] trait. /// From c9411dade73f576e5a324b4603045d600303d5f1 Mon Sep 17 00:00:00 2001 From: bluthej Date: Wed, 10 Sep 2025 21:14:47 +0200 Subject: [PATCH 2/4] Fix coefficient sign + add tests for RK23 --- src/ivp/rk.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/ivp/rk.rs b/src/ivp/rk.rs index f34d858..b31de10 100644 --- a/src/ivp/rk.rs +++ b/src/ivp/rk.rs @@ -615,7 +615,7 @@ impl RungeKuttaCoefficients<4> for RK23Coefficients { -Self::RealField::from_u8(5)? / Self::RealField::from_u8(72)?, Self::RealField::from_u8(12)?.recip(), Self::RealField::from_u8(9)?.recip(), - Self::RealField::from_u8(8)?.recip(), + -Self::RealField::from_u8(8)?.recip(), ])) } } @@ -737,4 +737,74 @@ mod test { )); } } + + #[test] + fn rungekutta23_quadratic() { + let t_initial = 0.0; + let t_final = 10.0; + + let solver = RungeKutta23::new() + .unwrap() + .with_minimum_dt(0.0001) + .unwrap() + .with_maximum_dt(0.1) + .unwrap() + .with_initial_time(t_initial) + .unwrap() + .with_ending_time(t_final) + .unwrap() + .with_tolerance(1e-5) + .unwrap() + .with_initial_conditions_slice(&[1.0]) + .unwrap() + .with_derivative(quadratic_deriv) + .solve(()) + .unwrap(); + + let path = solver.collect_vec().unwrap(); + + for step in &path { + assert!(approx_eq!( + f64, + step.1.column(0)[0], + 1.0 - step.0.powi(2), + epsilon = 0.0001 + )); + } + } + + #[test] + fn rungekutta23_sine() { + let t_initial = 0.0; + let t_final = 10.0; + + let solver = RungeKutta23::new() + .unwrap() + .with_minimum_dt(0.001) + .unwrap() + .with_maximum_dt(0.01) + .unwrap() + .with_tolerance(0.0001) + .unwrap() + .with_initial_time(t_initial) + .unwrap() + .with_ending_time(t_final) + .unwrap() + .with_initial_conditions_slice(&[0.0]) + .unwrap() + .with_derivative(sine_deriv) + .solve(()) + .unwrap(); + + let path = solver.collect_vec().unwrap(); + + for step in &path { + assert!(approx_eq!( + f64, + step.1.column(0)[0], + step.0.sin(), + epsilon = 0.01 + )); + } + } } From 4514b2ec6bc787bbf87012d1ab293005147d51e8 Mon Sep 17 00:00:00 2001 From: bluthej Date: Wed, 10 Sep 2025 21:43:40 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Parametrize=20RK=C2=A0tests=20with=20rstest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + src/ivp/rk.rs | 105 +++++++++++++------------------------------------- 2 files changed, 28 insertions(+), 78 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ea2c867..7a7a2de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ categories =["science"] [dev-dependencies] float-cmp = "0.9" rand = "0.8" +rstest = "0.26.1" [dependencies] nalgebra = "0.32" diff --git a/src/ivp/rk.rs b/src/ivp/rk.rs index b31de10..677fac1 100644 --- a/src/ivp/rk.rs +++ b/src/ivp/rk.rs @@ -659,6 +659,7 @@ pub type RungeKutta23<'a, N, D, T, F> = RungeKutta<'a, N, D, 4, T, F, RK23Coeffi mod test { use super::*; use crate::{ivp::UserError, BSVector}; + use rstest::rstest; fn quadratic_deriv(t: f64, _y: &[f64], _: &mut ()) -> Result, UserError> { Ok(BSVector::from_column_slice(&[-2.0 * t])) @@ -668,83 +669,27 @@ mod test { Ok(BSVector::from_column_slice(&[t.cos()])) } - #[test] - fn rungekutta45_quadratic() { + type TestRK<'a, const O: usize, R> = RungeKutta< + 'a, + f64, + Const<1>, + O, + (), + fn(f64, &[f64], &mut ()) -> Result>, UserError>, + R, + >; + + #[rstest] + #[case::rk23(RungeKutta23::new().unwrap())] + #[case::rk45(RungeKutta45::new().unwrap())] + fn rungekutta_quadratic<'a, const O: usize, R>(#[case] rk: TestRK<'a, O, R>) + where + R: RungeKuttaCoefficients, + { let t_initial = 0.0; let t_final = 10.0; - let solver = RungeKutta45::new() - .unwrap() - .with_minimum_dt(0.0001) - .unwrap() - .with_maximum_dt(0.1) - .unwrap() - .with_initial_time(t_initial) - .unwrap() - .with_ending_time(t_final) - .unwrap() - .with_tolerance(1e-5) - .unwrap() - .with_initial_conditions_slice(&[1.0]) - .unwrap() - .with_derivative(quadratic_deriv) - .solve(()) - .unwrap(); - - let path = solver.collect_vec().unwrap(); - - for step in &path { - assert!(approx_eq!( - f64, - step.1.column(0)[0], - 1.0 - step.0.powi(2), - epsilon = 0.0001 - )); - } - } - - #[test] - fn rungekutta45_sine() { - let t_initial = 0.0; - let t_final = 10.0; - - let solver = RungeKutta45::new() - .unwrap() - .with_minimum_dt(0.001) - .unwrap() - .with_maximum_dt(0.01) - .unwrap() - .with_tolerance(0.0001) - .unwrap() - .with_initial_time(t_initial) - .unwrap() - .with_ending_time(t_final) - .unwrap() - .with_initial_conditions_slice(&[0.0]) - .unwrap() - .with_derivative(sine_deriv) - .solve(()) - .unwrap(); - - let path = solver.collect_vec().unwrap(); - - for step in &path { - assert!(approx_eq!( - f64, - step.1.column(0)[0], - step.0.sin(), - epsilon = 0.01 - )); - } - } - - #[test] - fn rungekutta23_quadratic() { - let t_initial = 0.0; - let t_final = 10.0; - - let solver = RungeKutta23::new() - .unwrap() + let solver = rk .with_minimum_dt(0.0001) .unwrap() .with_maximum_dt(0.1) @@ -773,13 +718,17 @@ mod test { } } - #[test] - fn rungekutta23_sine() { + #[rstest] + #[case::rk23(RungeKutta23::new().unwrap())] + #[case::rk45(RungeKutta45::new().unwrap())] + fn rungekutta_sine<'a, const O: usize, R>(#[case] rk: TestRK<'a, O, R>) + where + R: RungeKuttaCoefficients, + { let t_initial = 0.0; let t_final = 10.0; - let solver = RungeKutta23::new() - .unwrap() + let solver = rk .with_minimum_dt(0.001) .unwrap() .with_maximum_dt(0.01) From e1b646adcc0a78f3ce0b1ecd7c5149ebe4c2bc0d Mon Sep 17 00:00:00 2001 From: bluthej Date: Wed, 10 Sep 2025 22:36:56 +0200 Subject: [PATCH 4/4] Sort dependencies --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7a7a2de..25a2b7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,6 @@ readme = "README.md" keywords =["numeric", "science", "integration", "quadrature"] categories =["science"] -[dev-dependencies] -float-cmp = "0.9" -rand = "0.8" -rstest = "0.26.1" - [dependencies] nalgebra = "0.32" num-complex = "0.4" @@ -26,3 +21,8 @@ typenum = "1.17" [build-dependencies] phf_codegen = "0.11" + +[dev-dependencies] +float-cmp = "0.9" +rand = "0.8" +rstest = "0.26.1"