From bf1903206371ce09fc7412c137032f4abab7e162 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Fri, 28 Jul 2023 15:05:02 -0600 Subject: [PATCH] poisson --- core/src/lib.rs | 1 - core/src/math/stochastic_new.rs | 45 ++++++++++++--------------- core/src/math/stochastic_process.rs | 39 ++++++++++++++++++++++-- core/src/time.rs | 47 ----------------------------- 4 files changed, 56 insertions(+), 76 deletions(-) delete mode 100644 core/src/time.rs diff --git a/core/src/lib.rs b/core/src/lib.rs index f97a4707e..132558dee 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -8,7 +8,6 @@ pub mod environment; pub mod manager; pub mod math; pub mod middleware; -pub mod time; #[cfg(test)] pub mod tests; pub mod utils; diff --git a/core/src/math/stochastic_new.rs b/core/src/math/stochastic_new.rs index 821cbbbd3..58f084a6c 100644 --- a/core/src/math/stochastic_new.rs +++ b/core/src/math/stochastic_new.rs @@ -1,4 +1,4 @@ -use RustQuant::{stochastics::{BrownianMotion, OrnsteinUhlenbeck, StochasticProcess, Trajectories}, statistics::distributions::Poisson }; +use RustQuant::{stochastics::{BrownianMotion, OrnsteinUhlenbeck, StochasticProcess, Trajectories}, statistics::distributions::{Poisson, Distribution} }; use anyhow::Result; @@ -11,12 +11,18 @@ pub enum StochasticProcessType { } /// Struct for all processes init parameters. pub struct EulerMaruyamaInput { - pub x_0: f64, // initial value at t_0 - pub t_0: f64, // initial time point - pub t_n: f64, // terminal time point - pub n_steps: usize, // number of time steps between t_0 and t_n - pub m_paths: usize, // how many process trajectories to simulate - pub parallel: bool, // run in parallel or not (recommended for > 1000 paths) + /// initial value at t_0 + pub x_0: f64, + /// initial time point + pub t_0: f64, + /// terminal time point + pub t_n: f64, + /// number of time steps between t_0 and t_n + pub n_steps: usize, + /// how many process trajectories to simulate + pub m_paths: usize, + /// run in parallel or not (recommended for > 1000 paths) + pub parallel: bool, } /// Create new process and run euler maruyama. @@ -34,24 +40,13 @@ pub fn new_procces(proccess_type: StochasticProcessType, config: EulerMaruyamaIn Ok(trajectories) } -// impl StochasticProcess { -// pub fn new_brownian_motion() -> Self { -// Self::BrownianMotion(BrownianMotion::new()) -// } -// pub fn new_ornstein_uhlenbeck() -> Self { -// Self::OrnsteinUhlenbeck(OrnsteinUhlenbeck::new()) -// } -// pub fn new_poisson() -> Self { -// Self::Poisson(Poisson::new()) -// } -// pub fn generate(&self, length: usize, seed: usize) -> Vec { -// match self { -// Self::BrownianMotion(brownian_motion) => brownian_motion.generate(length), -// Self::OrnsteinUhlenbeck(ornstein_uhlenbeck) => ornstein_uhlenbeck.generate(length), -// Self::Poisson(poisson) => poisson.generate(length), -// } -// } -// } +/// Sample Poisson process. +pub fn poisson_process(lambda: f64) { + let poisson = Poisson::new(lambda); + let sample = poisson.sample(10); + println!("{:#?} Poisson samples with lambda = {}", sample, lambda); + +} #[cfg(test)] mod tests { diff --git a/core/src/math/stochastic_process.rs b/core/src/math/stochastic_process.rs index 77230046f..e3788060b 100644 --- a/core/src/math/stochastic_process.rs +++ b/core/src/math/stochastic_process.rs @@ -170,6 +170,38 @@ impl OU { } } +use statrs::distribution::Poisson as PoissonDist; + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct Poisson_dist { + pub lambda: i64, +} + +impl Poisson_dist { + fn new(lambda: i64) -> Self { + Poisson_dist { lambda } + } + fn default() -> Self { + Poisson_dist { lambda: 1 } + } + fn generate(&self, length: usize) -> Result> { + + let dist = PoissonDist::new(self.lambda as f64)?; + let values = dist.sample_iter(&mut rand::thread_rng()).take(length).collect::>(); + let index = (0..values.len()).collect::>(); + + // convert usize to i32 and round f64 to i32 + let index_i32: Vec = index.into_iter().map(|x| x as i64).collect(); + let values_i32: Vec = values.into_iter().map(|x| x.round() as i64).collect(); + + // combine into a vector of tuples + let result: Vec<(i64, i64)> = index_i32.into_iter().zip(values_i32.into_iter()).collect(); + Ok(result) + } + +} + + #[cfg(test)] mod tests { @@ -177,10 +209,11 @@ mod tests { use super::*; #[test] - pub fn add_test() { - assert_eq!(2 + 2, 4); + pub fn small_distribution() { + let poisson = Poisson_dist::new(1); + let result = poisson.generate(100).unwrap(); + println!("{:?}", result); } - #[test] fn seeded_randomness_test() -> Result<()> { let gbm = GBM::new(0.05, 0.3); diff --git a/core/src/time.rs b/core/src/time.rs deleted file mode 100644 index bd7acb98f..000000000 --- a/core/src/time.rs +++ /dev/null @@ -1,47 +0,0 @@ -use rand_distr::Distribution; -use serde::{Serialize, Deserialize}; -use statrs::distribution::Poisson as PoissonDist; -use anyhow::{Result, Ok}; - - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub struct Poisson_dist { - pub lambda: i64, -} - -impl Poisson_dist { - fn new(lambda: i64) -> Self { - Poisson_dist { lambda } - } - fn default() -> Self { - Poisson_dist { lambda: 1 } - } - fn generate(&self, length: usize) -> Result> { - - let dist = PoissonDist::new(self.lambda as f64)?; - let values = dist.sample_iter(&mut rand::thread_rng()).take(length).collect::>(); - let index = (0..values.len()).collect::>(); - - // convert usize to i32 and round f64 to i32 - let index_i32: Vec = index.into_iter().map(|x| x as i64).collect(); - let values_i32: Vec = values.into_iter().map(|x| x.round() as i64).collect(); - - // combine into a vector of tuples - let result: Vec<(i64, i64)> = index_i32.into_iter().zip(values_i32.into_iter()).collect(); - Ok(result) - } - -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - pub fn small_distribution() { - let poisson = Poisson_dist::new(1); - let result = poisson.generate(100).unwrap(); - println!("{:?}", result); - } -} \ No newline at end of file