Skip to content

Time Series Data Generating Process: Langevin Equation

Among the many data generating processes (DGP), the Langevin equation is one of the most interesting DGP.

Brownian Motion

Brownian motion as a very simple stochastic process can be described by the Langevin equation1. In this section, we simulate a time series dataset from Brownian motion.

Macroscopically, Brownian Motion can be described by the notion of random forces on the particles,

\[ \frac{d}{dt} v(t) + \gamma v(t) = R(t), \]

where \(v(t)\) is the velocity at time \(t\) and \(R(t)\) is the stochastic force density from the reservoir particles. Solving the equation, we get

\[ v(t) = v(0)e^{-\gamma t} + \int_0^t dt' e^{-\gamma (t-t')} R(t') . \]

To generate a dataset numerically, we discretize it by replacing the integral with a sum,

\[ v(t) = v(0) e^{-\gamma t} + \sum_{n=0}^N \Delta t e^{-\gamma (t - t_n)} R(t_n) \]

where \(t_i = i * \Delta t\) and \(t = t_n\), thus the equation is further simplified,

\[ v(N\Delta t) = v(0) e^{-\gamma N\Delta t} + \sum_{n=0}^N e^{-\gamma (N - n)\Delta t} R(n\Delta t) \Delta t. \]

The first term in the solution is responsible for the exponential decay and the second term calculates the effect of the stochastic force.

To simulate a Brownian motion, we can either use the formal solution or the differential equation itself. Here we choose to use the differential equation itself. To simulate the process numerically, we rewrite

\[ \frac{d}{dt} v(t) + \gamma v(t) = R(t), \]


\[ \Delta v (t+1) = R(t) \Delta t - \gamma v(t) \Delta t. \]

The following is a simulated 1D Brownian motion.

Brownian Motion example

We create a stepper to calculate the next steps.

import numpy as np
import copy
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()

## Define Brownian Motion
class GaussianForce:
"""A Gaussian stochastic force iterator.
Each iteration returns a single sample from the corresponding
Gaussian distribution.

:param mu: mean of the Gaussian distribution
:param std: standard deviation of the Gaussian distribution
:param seed: seed for the random generator

def __init__(self, mu: float, std: float, seed: Optional[float] = None): = mu
    self.std = std
    self.rng = np.random.default_rng(seed=seed)

def __next__(self) -> float:
    return self.rng.normal(, self.std)

class BrownianMotionStepper:
    """Calculates the next step in a brownian motion.

    :param gamma: the damping factor $\gamma$ of the Brownian motion.
    :param delta_t: the minimum time step $\Delta t$.
    :param force_densities: the stochastic force densities, e.g. [`GaussianForce`][].
    :param initial_state: the initial velocity $v(0)$.

    def __init__(
        gamma: float,
        delta_t: float,
        force_densities: Iterator,
        initial_state: Dict[str, float],
        self.gamma = gamma
        self.delta_t = delta_t
        self.forece_densities = copy.deepcopy(force_densities)
        self.current_state = copy.deepcopy(initial_state)

    def __iter__(self):
        return self

    def __next__(self) -> Dict[str, float]:

        force_density = next(self.forece_densities)
        v_current = self.current_state["v"]

        v_next = v_current + force_density * self.delta_t - self.gamma * v_current * self.delta_t

        self.current_state["force_density"] = force_density
        self.current_state["v"] = v_next

        return copy.deepcopy(self.current_state)

## Generating time series
delta_t = 0.1
stepper = BrownianMotionStepper(
    force_densities=GaussianForece(mu=0, std=1),
    initial_state={"v": 0},

length = 200

history = []
for _ in range(length):

df = pd.DataFrame(history)

fig, ax = plt.subplots(figsize=(10, 6.18))
    x=np.linspace(0, length-1, length) * delta_t,

ax.set_title("Brownian Motion")

  1. Ma L. Brownian Motion — Statistical Physics Notes. In: Statistical Physics [Internet]. [cited 17 Nov 2022]. Available: 

Contributors: LM