Skip to content

Commit

Permalink
feat: update package and cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
dancixx committed Oct 6, 2024
1 parent f0cb3d5 commit 75f817d
Show file tree
Hide file tree
Showing 42 changed files with 263 additions and 969 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ candle-datasets = "0.7.2"
candle-nn = "0.7.2"
candle-transformers = "0.7.2"
chrono = "0.4.38"
impl-new-derive = "0.1.0"
indicatif = "0.17.8"
levenberg-marquardt = "0.14.0"
linreg = "0.2.0"
Expand All @@ -45,7 +46,6 @@ rand_distr = "0.4.3"
rayon = "1.10.0"
scilib = "1.0.0"
statrs = "0.17.1"
stochastic-rs-macros = { version = "0.1.0", path = "stochastic-rs-macros" }
tikv-jemallocator = { version = "0.6.0", optional = true }
time = { version = "0.3.36", features = [
"formatting",
Expand Down
2 changes: 1 addition & 1 deletion src/stats/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl FractalDim {
mod tests {
use approx::assert_relative_eq;

use crate::stochastic::{process::fbm::Fbm, Sampling};
use crate::stochastic::{process::fbm::FBM, Sampling};

use super::*;

Expand Down
5 changes: 3 additions & 2 deletions src/stochastic/diffusion/cev.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#[cfg(feature = "malliavin")]
use std::sync::Mutex;

use impl_new_derive::ImplNew;
use ndarray::Array1;
use ndarray_rand::RandomExt;
use rand_distr::Normal;
use stochastic_rs_macros::ImplNew;

use crate::stochastic::Sampling;

Expand All @@ -24,7 +25,7 @@ pub struct CEV {
impl Sampling<f64> for CEV {
/// Sample the CEV process
fn sample(&self) -> Array1<f64> {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let gn = Array1::random(self.n - 1, Normal::new(0.0, dt.sqrt()).unwrap());

let mut cev = Array1::<f64>::zeros(self.n);
Expand Down
4 changes: 2 additions & 2 deletions src/stochastic/diffusion/cir.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use impl_new_derive::ImplNew;
use ndarray::Array1;
use ndarray_rand::RandomExt;
use rand_distr::Normal;
use stochastic_rs_macros::ImplNew;

use crate::stochastic::Sampling;

Expand All @@ -28,7 +28,7 @@ impl Sampling<f64> for CIR {
"2 * theta * mu < sigma^2"
);

let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let gn = Array1::random(self.n - 1, Normal::new(0.0, dt.sqrt()).unwrap());

let mut cir = Array1::<f64>::zeros(self.n);
Expand Down
8 changes: 4 additions & 4 deletions src/stochastic/diffusion/fcir.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ndarray::{s, Array1};
use stochastic_rs_macros::ImplNew;
use impl_new_derive::ImplNew;
use ndarray::Array1;

use crate::stochastic::{noise::fgn::FGN, Sampling};

Expand Down Expand Up @@ -28,7 +28,7 @@ impl Sampling<f64> for FCIR {
);

let fgn = self.fgn.sample();
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;

let mut fcir = Array1::<f64>::zeros(self.n);
fcir[0] = self.x0.unwrap_or(0.0);
Expand All @@ -43,7 +43,7 @@ impl Sampling<f64> for FCIR {
};
}

fcir.slice(s![..self.n()]).to_owned()
fcir
}

/// Number of time steps
Expand Down
8 changes: 4 additions & 4 deletions src/stochastic/diffusion/fgbm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ndarray::{s, Array1};
use stochastic_rs_macros::ImplNew;
use impl_new_derive::ImplNew;
use ndarray::Array1;

use crate::stochastic::{noise::fgn::FGN, Sampling};

Expand All @@ -17,7 +17,7 @@ pub struct FGBM {
impl Sampling<f64> for FGBM {
/// Sample the Fractional Geometric Brownian Motion (FGBM) process
fn sample(&self) -> Array1<f64> {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let fgn = self.fgn.sample();

let mut fgbm = Array1::<f64>::zeros(self.n);
Expand All @@ -27,7 +27,7 @@ impl Sampling<f64> for FGBM {
fgbm[i] = fgbm[i - 1] + self.mu * fgbm[i - 1] * dt + self.sigma * fgbm[i - 1] * fgn[i - 1]
}

fgbm.slice(s![..self.n()]).to_owned()
fgbm
}

/// Number of time steps
Expand Down
8 changes: 4 additions & 4 deletions src/stochastic/diffusion/fjacobi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ndarray::{s, Array1};
use stochastic_rs_macros::ImplNew;
use impl_new_derive::ImplNew;
use ndarray::Array1;

use crate::stochastic::{noise::fgn::FGN, Sampling};

Expand All @@ -23,7 +23,7 @@ impl Sampling<f64> for FJacobi {
assert!(self.sigma > 0.0, "sigma must be positive");
assert!(self.alpha < self.beta, "alpha must be less than beta");

let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let fgn = self.fgn.sample();

let mut fjacobi = Array1::<f64>::zeros(self.n);
Expand All @@ -41,7 +41,7 @@ impl Sampling<f64> for FJacobi {
}
}

fjacobi.slice(s![..self.n()]).to_owned()
fjacobi
}

/// Number of time steps
Expand Down
8 changes: 4 additions & 4 deletions src/stochastic/diffusion/fou.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ndarray::{s, Array1};
use stochastic_rs_macros::ImplNew;
use impl_new_derive::ImplNew;
use ndarray::Array1;

use crate::stochastic::{noise::fgn::FGN, Sampling};

Expand All @@ -18,7 +18,7 @@ pub struct FOU {
impl Sampling<f64> for FOU {
/// Sample the Fractional Ornstein-Uhlenbeck (FOU) process
fn sample(&self) -> Array1<f64> {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let fgn = self.fgn.sample();

let mut fou = Array1::<f64>::zeros(self.n);
Expand All @@ -28,7 +28,7 @@ impl Sampling<f64> for FOU {
fou[i] = fou[i - 1] + self.theta * (self.mu - fou[i - 1]) * dt + self.sigma * fgn[i - 1]
}

fou.slice(s![..self.n()]).to_owned()
fou
}

/// Number of time steps
Expand Down
12 changes: 6 additions & 6 deletions src/stochastic/diffusion/gbm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(feature = "malliavin")]
use std::sync::Mutex;

use impl_new_derive::ImplNew;
use ndarray::Array1;
use ndarray_rand::RandomExt;
use num_complex::Complex64;
Expand All @@ -9,7 +10,6 @@ use statrs::{
distribution::{Continuous, ContinuousCDF, LogNormal},
statistics::{Distribution as StatDistribution, Median, Mode},
};
use stochastic_rs_macros::ImplNew;

use crate::stochastic::{Distribution, Sampling};

Expand All @@ -31,7 +31,7 @@ pub struct GBM {
impl Sampling<f64> for GBM {
/// Sample the GBM process
fn sample(&self) -> Array1<f64> {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let gn = Array1::random(self.n - 1, Normal::new(0.0, dt.sqrt()).unwrap());

let mut gbm = Array1::<f64>::zeros(self.n);
Expand Down Expand Up @@ -186,26 +186,26 @@ mod tests {
use super::*;

#[test]
fn gmb_length_equals_n() {
fn gbm_length_equals_n() {
let gbm = GBM::new(0.25, 0.5, N, Some(X0), Some(1.0), None, None, None);
assert_eq!(gbm.sample().len(), N);
}

#[test]
fn gmb_starts_with_x0() {
fn gbm_starts_with_x0() {
let gbm = GBM::new(0.25, 0.5, N, Some(X0), Some(1.0), None, None, None);
assert_eq!(gbm.sample()[0], X0);
}

#[test]
fn gmb_plot() {
fn gbm_plot() {
let gbm = GBM::new(0.25, 0.5, N, Some(X0), Some(1.0), None, None, None);
plot_1d!(gbm.sample(), "Geometric Brownian Motion (GBM) process");
}

#[test]
#[cfg(feature = "malliavin")]
fn gmb_malliavin() {
fn gbm_malliavin() {
let gbm = GBM::new(0.25, 0.5, N, Some(X0), Some(1.0), None, None, Some(true));
let process = gbm.sample();
let malliavin = gbm.malliavin();
Expand Down
4 changes: 2 additions & 2 deletions src/stochastic/diffusion/jacobi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use impl_new_derive::ImplNew;
use ndarray::Array1;
use ndarray_rand::RandomExt;
use rand_distr::Normal;
use stochastic_rs_macros::ImplNew;

use crate::stochastic::Sampling;

Expand All @@ -24,7 +24,7 @@ impl Sampling<f64> for Jacobi {
assert!(self.sigma > 0.0, "sigma must be positive");
assert!(self.alpha < self.beta, "alpha must be less than beta");

let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let gn = Array1::random(self.n, Normal::new(0.0, dt.sqrt()).unwrap());

let mut jacobi = Array1::<f64>::zeros(self.n + 1);
Expand Down
4 changes: 2 additions & 2 deletions src/stochastic/diffusion/ou.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use impl_new_derive::ImplNew;
use ndarray::Array1;
use ndarray_rand::RandomExt;
use rand_distr::Normal;
use stochastic_rs_macros::ImplNew;

use crate::stochastic::Sampling;

Expand All @@ -19,7 +19,7 @@ pub struct OU {
impl Sampling<f64> for OU {
/// Sample the Ornstein-Uhlenbeck (OU) process
fn sample(&self) -> Array1<f64> {
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;
let gn = Array1::random(self.n, Normal::new(0.0, dt.sqrt()).unwrap());

let mut ou = Array1::<f64>::zeros(self.n + 1);
Expand Down
44 changes: 6 additions & 38 deletions src/stochastic/interest/duffie_kan.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use impl_new_derive::ImplNew;
use ndarray::Array1;

use crate::stochastic::{noise::cgns::CGNS, Sampling2D};

#[derive(Default)]
#[derive(ImplNew)]

pub struct DuffieKan {
pub alpha: f64,
Expand All @@ -25,52 +26,19 @@ pub struct DuffieKan {
pub cgns: CGNS,
}

impl DuffieKan {
#[must_use]
pub fn new(params: &Self) -> Self {
let cgns: CGNS = CGNS::new(&CGNS {
rho: params.rho,
n: params.n,
t: params.t,
m: params.m,
});

Self {
alpha: params.alpha,
beta: params.beta,
gamma: params.gamma,
rho: params.rho,
a1: params.a1,
b1: params.b1,
c1: params.c1,
sigma1: params.sigma1,
a2: params.a2,
b2: params.b2,
c2: params.c2,
sigma2: params.sigma2,
n: params.n,
r0: params.r0,
x0: params.x0,
t: params.t,
m: params.m,
cgns,
}
}
}

impl Sampling2D<f64> for DuffieKan {
/// Sample the Duffie-Kan process
fn sample(&self) -> [Array1<f64>; 2] {
let [cgn1, cgn2] = self.cgns.sample();
let dt = self.t.unwrap_or(1.0) / self.n as f64;
let dt = self.t.unwrap_or(1.0) / (self.n - 1) as f64;

let mut r = Array1::<f64>::zeros(self.n + 1);
let mut x = Array1::<f64>::zeros(self.n + 1);
let mut r = Array1::<f64>::zeros(self.n);
let mut x = Array1::<f64>::zeros(self.n);

r[0] = self.r0.unwrap_or(0.0);
x[0] = self.x0.unwrap_or(0.0);

for i in 1..=self.n {
for i in 1..self.n {
r[i] = r[i - 1]
+ (self.a1 * r[i - 1] + self.b1 * x[i - 1] + self.c1) * dt
+ self.sigma1 * (self.alpha * r[i - 1] + self.beta * x[i - 1] + self.gamma) * cgn1[i - 1];
Expand Down
3 changes: 2 additions & 1 deletion src/stochastic/interest/fvasicek.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use impl_new_derive::ImplNew;
use ndarray::Array1;
use stochastic_rs_macros::ImplNew;

use crate::stochastic::{diffusion::fou::FOU, Sampling};

Expand All @@ -17,6 +17,7 @@ pub struct FVasicek {
}

impl Sampling<f64> for FVasicek {
/// Sample the Fractional Vasicek process
fn sample(&self) -> Array1<f64> {
self.fou.sample()
}
Expand Down
Loading

0 comments on commit 75f817d

Please sign in to comment.