| 104 | } |
| 105 | |
| 106 | fn check_ode() { |
| 107 | struct StiffSpiral; |
| 108 | impl ODEProblem for StiffSpiral { |
| 109 | fn rhs(&self, _t: f64, y: &[f64], dy: &mut [f64]) -> anyhow::Result<()> { |
| 110 | dy[0] = -0.5 * y[0] - 1.5 * y[1]; |
| 111 | dy[1] = 1.5 * y[0] - 0.5 * y[1]; |
| 112 | Ok(()) |
| 113 | } |
| 114 | } |
| 115 | macro_rules! run_explicit { |
| 116 | ($name:expr, $integ:expr) => {{ |
| 117 | let (t, y) = BasicODESolver::new($integ) |
| 118 | .solve(&StiffSpiral, (0.0, 1.5), 0.05, &[1.0, 0.0]) |
| 119 | .unwrap(); |
| 120 | let y_flat: Vec<f64> = y.iter().flatten().copied().collect(); |
| 121 | print_kv(&format!("ode {} t-hash", $name), hash_f64s(&t)); |
| 122 | print_kv(&format!("ode {} y-hash", $name), hash_f64s(&y_flat)); |
| 123 | }}; |
| 124 | } |
| 125 | run_explicit!("RK4", RK4); |
| 126 | run_explicit!("RALS3", RALS3); |
| 127 | run_explicit!("RALS4", RALS4); |
| 128 | run_explicit!("RK5", RK5); |
| 129 | // embedded methods that drive the step() arms touched by clippy. |
| 130 | // Use a simple decay problem so every method converges within the |
| 131 | // step-iteration budget. |
| 132 | struct Decay; |
| 133 | impl ODEProblem for Decay { |
| 134 | fn rhs(&self, _t: f64, y: &[f64], dy: &mut [f64]) -> anyhow::Result<()> { |
| 135 | dy[0] = -y[0]; |
| 136 | Ok(()) |
| 137 | } |
| 138 | } |
| 139 | macro_rules! run_embedded { |
| 140 | ($name:expr, $integ:expr) => {{ |
| 141 | let (t, y) = BasicODESolver::new($integ) |
| 142 | .solve(&Decay, (0.0, 2.0), 0.05, &[1.0]) |
| 143 | .unwrap(); |
| 144 | let y_flat: Vec<f64> = y.iter().flatten().copied().collect(); |
| 145 | print_kv(&format!("ode {} t-len", $name), t.len()); |
| 146 | print_kv(&format!("ode {} y-hash", $name), hash_f64s(&y_flat)); |
| 147 | }}; |
| 148 | } |
| 149 | run_embedded!("RKF45", RKF45::new(1e-6, 0.9, 1e-6, 1e-1, 200)); |
| 150 | run_embedded!("DP45", DP45::new(1e-6, 0.9, 1e-6, 1e-1, 200)); |
| 151 | run_embedded!("TSIT45", TSIT45::new(1e-6, 0.9, 1e-6, 1e-1, 200)); |
| 152 | run_embedded!("RKF78", RKF78::new(1e-6, 0.9, 1e-6, 1e-1, 200)); |
| 153 | run_embedded!("BS23", BS23::new(1e-6, 0.9, 1e-6, 1e-1, 200)); |
| 154 | run_embedded!("GL4", GL4::new(ImplicitSolver::FixedPoint, 1e-6, 100)); |
| 155 | } |
| 156 | |
| 157 | fn check_distributions() { |
| 158 | let mut rng = SmallRng::seed_from_u64(0xC0FFEE); |