use crate::errors::QlResult;
use crate::math::randomnumbers::rngtraits::SequenceGenerator;
use crate::math::timegrid::TimeGrid;
use crate::methods::montecarlo::{MultiPath, MultiPathGenerator, Path, PathGen, PathGenerator};
use crate::patterns::observable::Observable;
use crate::shared::Shared;
use crate::stochasticprocess::{StochasticProcess, StochasticProcess1D};
use crate::time::date::Date;
use crate::types::{Size, Time};
pub trait McTraits {
type Process: Clone;
type PathType;
type Generator<RSG: SequenceGenerator>: PathGen<PathType = Self::PathType>;
fn observable(process: &Self::Process) -> &Observable;
fn time(process: &Self::Process, date: &Date) -> QlResult<Time>;
fn factors(process: &Self::Process) -> Size;
fn path_generator<RSG: SequenceGenerator>(
process: Self::Process,
grid: TimeGrid,
generator: RSG,
brownian_bridge: bool,
) -> QlResult<Self::Generator<RSG>>;
}
pub struct SingleVariate;
impl McTraits for SingleVariate {
type Process = Shared<dyn StochasticProcess1D>;
type PathType = Path;
type Generator<RSG: SequenceGenerator> = PathGenerator<RSG>;
fn observable(process: &Self::Process) -> &Observable {
process.observable()
}
fn time(process: &Self::Process, date: &Date) -> QlResult<Time> {
process.time(date)
}
fn factors(_process: &Self::Process) -> Size {
1
}
fn path_generator<RSG: SequenceGenerator>(
process: Self::Process,
grid: TimeGrid,
generator: RSG,
brownian_bridge: bool,
) -> QlResult<Self::Generator<RSG>> {
PathGenerator::from_time_grid(process, grid, generator, brownian_bridge)
}
}
pub struct MultiVariate;
impl McTraits for MultiVariate {
type Process = Shared<dyn StochasticProcess>;
type PathType = MultiPath;
type Generator<RSG: SequenceGenerator> = MultiPathGenerator<RSG>;
fn observable(process: &Self::Process) -> &Observable {
process.observable()
}
fn time(process: &Self::Process, date: &Date) -> QlResult<Time> {
process.time(date)
}
fn factors(process: &Self::Process) -> Size {
process.factors()
}
fn path_generator<RSG: SequenceGenerator>(
process: Self::Process,
grid: TimeGrid,
generator: RSG,
brownian_bridge: bool,
) -> QlResult<Self::Generator<RSG>> {
MultiPathGenerator::new(process, grid, generator, brownian_bridge)
}
}