Source code for geomstats.distributions.brownian_motion

"""Brownian motion defined on a manifold."""

import geomstats.backend as gs


[docs] class BrownianMotion: """Class to generate a realization of Brownian motion on a manifold. Parameters ---------- space : Manifold Manifold to generate Brownian motion on. Example -------- >>> import os >>> os.environ["GEOMSTATS_BACKEND"] = "pytorch" >>> import geomstats.backend as gs >>> from geomstats.geometry.euclidean import Euclidean >>> from geomstats.distributions.brownian_motion import BrownianMotion >>> manifold = Euclidean(dim=3) >>> euclidean_brownian_motion = BrownianMotion(manifold) >>> sample_path = euclidean_brownian_motion.sample_path( end_time=1, n_steps=50, initial_point=gs.array([0.0, 0.0, 0.0]) ) References ---------- .. [H2022] Elton P. Hsu, "Stochastic Analysis On Manifolds", American Mathematical Soc. (2002): 71-99. """ def __init__(self, space): self.space = space self._check_coordinates(space) def _check_coordinates(self, space): """Check the manifold is defined in intrinsic coordinates.""" if not space.intrinsic: raise ValueError( "Space should be equipped with intrinsic coordinates to create Brownian" "motion over the local parametrization." )
[docs] def sample_path(self, end_time, n_steps, initial_point): """Generate a sample path of Brownian motion. Parameters ---------- end_time : float Final time of the path. n_steps : int Number of steps in the path. initial_point : array-like, shape=[..., dim] Initial point of the path at time 0. Returns ------- path : array-like, shape=[..., n_steps, dim] Sample path of Brownian motion. """ step_size = end_time / n_steps paths = [initial_point] for _ in range(1, n_steps): paths.append(self._step(step_size, paths[-1])) return gs.stack(paths)
def _step(self, step_size, current_point): """Calulate one increment of a Brownian motion path. Parameters ---------- step_size : float Size of the step to be taken in the Brownian motion. current_point : array-like, shape=[..., dim] Current point in the Brownian motion path. Returns ------- next_point : array-like, shape=[..., dim] Next point in the Brownian motion path after taking the step. Notes ----- Method uses the Euler-Maruyama integration scheme. Brownian motion is described in the Ito form in intrinsic coordinates as a stochastic differential equation, [H2022] (example 3.3.5). """ sigma = gs.linalg.sqrtm(self.space.metric.cometric_matrix(current_point)) christoffels = self.space.metric.christoffels(current_point) cometric_matrix = self.space.metric.cometric_matrix(current_point) drift = ( -0.5 * gs.einsum("...klm,...lm->...k", christoffels, cometric_matrix) * step_size ) batch_shape = current_point.shape[: -self.space.point_ndim] diffusion = gs.einsum( "...ij,...j->...i", sigma, gs.random.normal(size=batch_shape + (self.space.dim,)) * gs.sqrt(step_size), ) return current_point + drift + diffusion