Struct Milstein

Source
pub struct Milstein<T: Real, V: State<T>, D: CallBackData> {
    pub h: T,
    /* private fields */
}
Expand description

Milstein Method for solving stochastic differential equations.

The Milstein method is a higher-order method for SDEs that includes an additional term from the Itô-Taylor expansion to achieve better accuracy.

For an SDE of the form: dY = a(t,Y)dt + b(t,Y)dW

The Milstein update is: Y_{n+1} = Y_n + a(t_n, Y_n)Δt + b(t_n, Y_n)ΔW_n + 0.5 * b(t_n, Y_n)^2 * [(ΔW_n)² - Δt]

where ΔW_n is a Wiener process increment.

This implementation is based on the standard form of the Milstein method for scalar SDEs. For geometric Brownian motion, the b(t,Y) term is σY, so the correction term becomes 0.5 * (σY)^2 * [(ΔW)² - Δt].

The Milstein method has strong order of convergence 1.0 (compared to 0.5 for Euler-Maruyama), making it more accurate for SDEs with significant diffusion effects.

§Example

use differential_equations::prelude::*;
use nalgebra::SVector;
use rand::SeedableRng;
use rand_distr::{Distribution, Normal};

struct GBM {
    mu: f64,     // Drift rate
    sigma: f64,  // Volatility
    rng: rand::rngs::StdRng,
}

impl GBM {
    fn new(mu: f64, sigma: f64, seed: u64) -> Self {
        Self {
            mu,
            sigma,
            rng: rand::rngs::StdRng::seed_from_u64(seed),
        }
    }
}

impl SDE<f64, SVector<f64, 1>> for GBM {
    fn drift(&self, _t: f64, y: &SVector<f64, 1>, dydt: &mut SVector<f64, 1>) {
        dydt[0] = self.mu * y[0];
    }
     
    fn diffusion(&self, _t: f64, y: &SVector<f64, 1>, dydw: &mut SVector<f64, 1>) {
        dydw[0] = self.sigma * y[0];
    }
     
    fn noise(&self, dt: f64, dw: &mut SVector<f64, 1>) {
        let normal = Normal::new(0.0, dt.sqrt()).unwrap();
        dw[0] = normal.sample(&mut self.rng.clone());
    }
}

let t0 = 0.0;
let tf = 1.0;
let y0 = SVector::<f64, 1>::new(100.0);
let mut solver = Milstein::new(0.01);
let gbm = GBM::new(0.1, 0.2, 42);
let gbm_problem = SDEProblem::new(gbm, t0, tf, y0);

// Solve the SDE
let result = gbm_problem.solve(&mut solver);

Fields§

§h: T

Implementations§

Source§

impl<T: Real, V: State<T>, D: CallBackData> Milstein<T, V, D>

Source

pub fn new(h: T) -> Self

Create a new Milstein solver with the specified step size

§Arguments
  • h - Step size
§Returns
  • A new solver instance

Trait Implementations§

Source§

impl<T: Real, V: State<T>, D: CallBackData> Default for Milstein<T, V, D>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T: Real, V: State<T>, D: CallBackData> Interpolation<T, V> for Milstein<T, V, D>

Source§

fn interpolate(&mut self, t_interp: T) -> Result<V, Error<T, V>>

Interpolate between previous and current step Read more
Source§

impl<T: Real, V: State<T>, D: CallBackData> SDENumericalMethod<T, V, D> for Milstein<T, V, D>

Source§

fn init<F>( &mut self, sde: &F, t0: T, tf: T, y0: &V, ) -> Result<Evals, Error<T, V>>
where F: SDE<T, V, D>,

Initialize SDENumericalMethod before solving SDE Read more
Source§

fn step<F>(&mut self, sde: &F) -> Result<Evals, Error<T, V>>
where F: SDE<T, V, D>,

Step through solving the SDE by one step Read more
Source§

fn t(&self) -> T

Access time of last accepted step
Source§

fn y(&self) -> &V

Access solution of last accepted step
Source§

fn t_prev(&self) -> T

Access time of previous accepted step
Source§

fn y_prev(&self) -> &V

Access solution of previous accepted step
Source§

fn h(&self) -> T

Access step size of next step
Source§

fn set_h(&mut self, h: T)

Set step size of next step
Source§

fn status(&self) -> &Status<T, V, D>

Status of solver
Source§

fn set_status(&mut self, status: Status<T, V, D>)

Set status of solver

Auto Trait Implementations§

§

impl<T, V, D> Freeze for Milstein<T, V, D>
where T: Freeze, V: Freeze, D: Freeze,

§

impl<T, V, D> RefUnwindSafe for Milstein<T, V, D>

§

impl<T, V, D> Send for Milstein<T, V, D>
where V: Send, D: Send,

§

impl<T, V, D> Sync for Milstein<T, V, D>
where V: Sync, D: Sync,

§

impl<T, V, D> Unpin for Milstein<T, V, D>
where T: Unpin, V: Unpin, D: Unpin,

§

impl<T, V, D> UnwindSafe for Milstein<T, V, D>
where T: UnwindSafe, V: UnwindSafe, D: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.