Skip to content

Commit

Permalink
make sample abstract
Browse files Browse the repository at this point in the history
  • Loading branch information
lsbardel committed Jul 8, 2023
1 parent ceb81d4 commit 55d6b2d
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
2 changes: 1 addition & 1 deletion quantflow/sp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ class StochasticProcess(BaseModel, ABC):
Base class for stochastic processes in continuous time
"""

@abstractmethod
def sample(self, n: int, t: float = 1, steps: int = 0) -> np.ndarray:
"""Generate random paths from the process
:param n: Number of paths
:param t: time horizon
:param steps: number of time steps to arrive at horizon
"""
raise NotImplementedError

def sample_dt(self, t: float, steps: int = 0) -> Tuple[int, float]:
"""Time delta for sampling paths
Expand Down
6 changes: 2 additions & 4 deletions quantflow/sp/heston.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ def characteristic(self, t: float, u: Vector) -> Vector:
a = theta_kappa * (2 * np.log(c) + (gamma - kappa) * t) / eta2
return np.exp(-a - b * self.variance_process.rate)

def pdf(self, t: float, n: Vector) -> Vector:
raise NotImplementedError

def cdf(self, t: float, n: Vector) -> Vector:
def sample(self, n: int, t: float = 1, steps: int = 0) -> np.ndarray:
# TODO: implement
raise NotImplementedError
9 changes: 9 additions & 0 deletions quantflow/sp/weiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from functools import lru_cache

import numpy as np
from numpy.random import normal
from pydantic import Field
from scipy.stats import norm

Expand Down Expand Up @@ -32,6 +33,14 @@ def characteristic(self, t: float, u: Vector) -> Vector:
su = self.sigma * u
return np.exp(-0.5 * su * su * t)

def sample(self, n: int, t: float = 1, steps: int = 0) -> np.ndarray:
time_steps, dt = self.sample_dt(t, steps)
sdt = self.sigma * np.sqrt(dt)
paths = np.zeros((time_steps + 1, n))
for t in range(time_steps):
paths[t + 1, :] = paths[t, :] + normal(scale=sdt, size=n)
return paths


class WeinerMarginal(StochasticProcess1DMarginal[WeinerProcess]):
def mean(self) -> float:
Expand Down
8 changes: 8 additions & 0 deletions tests/test_weiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ def test_characteristic(weiner: WeinerProcess) -> None:
assert marginal.mean_from_characteristic() == 0
assert marginal.std() == 0.5
assert marginal.variance_from_characteristic() == pytest.approx(0.25)


def test_sampling(weiner: WeinerProcess) -> None:
paths = weiner.paths(1000, t=1, steps=1000)
mean = paths.mean()
assert mean[0] == 0
std = paths.std()
assert std[0] == 0

0 comments on commit 55d6b2d

Please sign in to comment.