stochastic_processes/processes/
mod.rs1mod cir;
4pub use cir::*;
5
6mod gbm;
7pub use gbm::*;
8
9mod ornstein_uhlenbeck;
10pub use ornstein_uhlenbeck::*;
11
12pub trait StochasticProcess {}
14
15pub trait NonautonomousStochasticProcess: StochasticProcess {
20 fn drift(&self, t: f32, x: f32) -> f32;
21
22 fn diffusion(&self, t: f32, x: f32) -> f32;
23
24 fn run_euler_maruyama(&self, x_0: f32, t_0: f32, t_n: f32, n: usize) -> crate::SimulatedPath {
25 use rand::prelude::Distribution;
26
27 let dt: f32 = (t_n - t_0) / (n as f32);
28
29 let mut rng = rand::thread_rng();
31 let increments: Vec<f32> = match statrs::distribution::Normal::new(0.0, 1.0) {
32 Ok(dist) => dist,
33 Err(_) => panic!("Bad parameters."),
34 }
35 .sample_iter(&mut rng)
36 .take(n)
37 .map(|x| (x as f32) * dt.sqrt())
38 .collect();
39
40 let mut path = crate::SimulatedPath::zeros_generic(
42 nalgebra::Dim::from_usize(n + 1),
43 nalgebra::Dim::from_usize(2),
44 );
45
46 path[(0, 0)] = t_0;
48 path[(n, 0)] = t_n;
49 for t in 1..(n + 1) {
50 path[(t, 0)] = t_0 + dt * (t as f32);
51 }
52
53 path[(0, 1)] = x_0;
55 for t in 0..n {
56 path[(t + 1, 1)] = path[(t, 1)]
57 + self.drift(path[(t, 0)], path[(t, 1)]) * (path[(t + 1, 0)] - path[(t, 0)])
58 + self.diffusion(path[(t, 0)], path[(t, 1)]) * increments[t];
59 }
60 path
61 }
62}
63
64pub trait AutonomousStochasticProcess: StochasticProcess {
69 fn drift(&self, x: f32) -> f32;
70
71 fn diffusion(&self, x: f32) -> f32;
72
73 fn run_euler_maruyama(&self, x_0: f32, t_0: f32, t_n: f32, n: usize) -> crate::SimulatedPath {
74 use rand::prelude::Distribution;
75
76 let dt: f32 = (t_n - t_0) / (n as f32);
77
78 let mut rng = rand::thread_rng();
80 let increments: Vec<f32> = match statrs::distribution::Normal::new(0.0, 1.0) {
81 Ok(dist) => dist,
82 Err(_) => panic!("Bad parameters."),
83 }
84 .sample_iter(&mut rng)
85 .take(n)
86 .map(|x| (x as f32) * dt.sqrt())
87 .collect();
88
89 let mut path = crate::SimulatedPath::zeros_generic(
91 nalgebra::Dim::from_usize(n + 1),
92 nalgebra::Dim::from_usize(2),
93 );
94
95 path[(0, 0)] = t_0;
97 path[(n, 0)] = t_n;
98 for t in 1..(n + 1) {
99 path[(t, 0)] = t_0 + dt * (t as f32);
100 }
101
102 path[(0, 1)] = x_0;
104 for t in 0..n {
105 path[(t + 1, 1)] = path[(t, 1)]
106 + self.drift(path[(t, 1)]) * (path[(t + 1, 0)] - path[(t, 0)])
107 + self.diffusion(path[(t, 1)]) * increments[t];
108 }
109 path
110 }
111}