pub struct Rk45<T: Numeric = f64> { /* private fields */ }Expand description
Adaptive Dormand–Prince 5(4) integrator for y' = f(t, y) with state Vector<N, T>.
Build with Rk45::default and adjust with the with_* methods. Solve with
solve, stream accepted steps with for_each_step,
or sample a time grid with solve_on_grid.
Implementations§
Source§impl<T: Numeric> Rk45<T>
impl<T: Numeric> Rk45<T>
Sourcepub fn with_first_step(self, h: T) -> Self
pub fn with_first_step(self, h: T) -> Self
Sets the first step size; 0 (the default) auto-selects it.
Sourcepub fn with_min_step(self, h: T) -> Self
pub fn with_min_step(self, h: T) -> Self
Sets the minimum step magnitude; falling below it returns IntegrateError::StepSizeTooSmall.
0 (the default) disables the floor.
Sourcepub fn with_max_step(self, h: T) -> Self
pub fn with_max_step(self, h: T) -> Self
Sets the maximum step magnitude (default unbounded).
Sourcepub fn with_max_steps(self, n: usize) -> Self
pub fn with_max_steps(self, n: usize) -> Self
Sets the maximum number of step attempts before IntegrateError::DidNotConverge
(default 100_000).
Source§impl<T: Numeric> Rk45<T>
impl<T: Numeric> Rk45<T>
Sourcepub fn for_each_step<const N: usize, F, O>(
&self,
f: &F,
t0: T,
y0: &Vector<N, T>,
tf: T,
obs: O,
) -> Result<Vector<N, T>, IntegrateError>
pub fn for_each_step<const N: usize, F, O>( &self, f: &F, t0: T, y0: &Vector<N, T>, tf: T, obs: O, ) -> Result<Vector<N, T>, IntegrateError>
Integrates from t0 to tf, invoking obs with each accepted Step, and returns
the final state.
§Errors
LimitsIllDefined for a NaN or
zero-length span; NonFinite if f or the state goes
non-finite; StepSizeTooSmall if the step drops below
min_step; DidNotConverge if max_steps is exhausted.
use multicalc::ode::Rk45;
use multicalc::linear_algebra::Vector;
// y' = -y over [0, 2]; y(2) = e^{-2}.
let yf = Rk45::default()
.solve(&|_t, y: &Vector<1, f64>| -*y, 0.0, &Vector::new([1.0]), 2.0)
.unwrap();
assert!((yf[0] - (-2.0_f64).exp()).abs() < 1e-6);Sourcepub fn solve<const N: usize, F>(
&self,
f: &F,
t0: T,
y0: &Vector<N, T>,
tf: T,
) -> Result<Vector<N, T>, IntegrateError>
pub fn solve<const N: usize, F>( &self, f: &F, t0: T, y0: &Vector<N, T>, tf: T, ) -> Result<Vector<N, T>, IntegrateError>
Integrates from t0 to tf and returns the final state (no per-step callback).
Sourcepub fn solve_on_grid<const N: usize, F>(
&self,
f: &F,
t0: T,
y0: &Vector<N, T>,
times: &[T],
out: &mut [Vector<N, T>],
) -> Result<(), IntegrateError>
pub fn solve_on_grid<const N: usize, F>( &self, f: &F, t0: T, y0: &Vector<N, T>, times: &[T], out: &mut [Vector<N, T>], ) -> Result<(), IntegrateError>
Samples the solution at each time in times (sorted in the integration direction and lying
within [t0, tf]), writing to out via cubic-Hermite dense output. No allocation.
§Errors
LimitsIllDefined if times.len() != out.len() or a time is out of range / out of order; otherwise as
for_each_step.
use multicalc::ode::Rk45;
use multicalc::linear_algebra::Vector;
// Sample y' = -y at t = 0.5 and t = 1 by cubic-Hermite dense output.
let times = [0.5, 1.0];
let mut out = [Vector::<1, f64>::zeros(); 2];
Rk45::default()
.solve_on_grid(&|_t, y: &Vector<1, f64>| -*y, 0.0, &Vector::new([1.0]), ×, &mut out)
.unwrap();
assert!((out[0][0] - (-0.5_f64).exp()).abs() < 1e-6);
assert!((out[1][0] - (-1.0_f64).exp()).abs() < 1e-6);