# Euler–Maruyama method

In Itô calculus, the Euler–Maruyama method (also called the Euler method) is a method for the approximate numerical solution of a stochastic differential equation (SDE). It is an extension of the Euler method for ordinary differential equations to stochastic differential equations. It is named after Leonhard Euler and Gisiro Maruyama. Unfortunately, the same generalization cannot be done for any arbitrary deterministic method.[1]

Consider the stochastic differential equation (see Itô calculus)

${\displaystyle \mathrm {d} X_{t}=a(X_{t},t)\,\mathrm {d} t+b(X_{t},t)\,\mathrm {d} W_{t},}$

with initial condition X0 = x0, where Wt stands for the Wiener process, and suppose that we wish to solve this SDE on some interval of time [0, T]. Then the Euler–Maruyama approximation to the true solution X is the Markov chain Y defined as follows:

• partition the interval [0, T] into N equal subintervals of width ${\displaystyle \Delta t>0}$:
${\displaystyle 0=\tau _{0}<\tau _{1}<\cdots <\tau _{N}=T{\text{ and }}\Delta t=T/N;}$
• set Y0 = x0
• recursively define Yn for 1 ≤ n ≤ N by
${\displaystyle \,Y_{n+1}=Y_{n}+a(Y_{n},\tau _{n})\,\Delta t+b(Y_{n},\tau _{n})\,\Delta W_{n},}$
where
${\displaystyle \Delta W_{n}=W_{\tau _{n+1}}-W_{\tau _{n}}.}$

The random variables ΔWn are independent and identically distributed normal random variables with expected value zero and variance ${\displaystyle \Delta t}$.

## Example

### Numerical simulation

Gene expression modelled as stochastic process

An area that has benefited significantly from SDE is biology or more precisely mathematical biology. Here the number of publications on the use of stochastic model grew, as most of the models are nonlinear, demanding numerical schemes.

The graphic depicts a stochastic differential equation being solved using the Euler Scheme. The deterministic counterpart is shown as well.

### Computer implementation

The following Python code implements the Euler–Maruyama method and uses it to solve the Ornstein–Uhlenbeck process defined by

${\displaystyle dY_{t}=\theta \cdot (\mu -Y_{t})\,{\mathrm {d} }t+\sigma \,{\mathrm {d} }W_{t}}$
${\displaystyle Y_{0}=Y_{\mathrm {init} }.}$

The random numbers for ${\displaystyle {\mathrm {d} }W_{t}}$ are generated using the NumPy mathematics package.

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

num_sims = 5  # Display five runs

t_init = 3
t_end  = 7
N      = 1000  # Compute 1000 grid points
dt     = float(t_end - t_init) / N
y_init = 0

c_theta = 0.7
c_mu    = 1.5
c_sigma = 0.06

def mu(y, t):
"""Implement the Ornstein–Uhlenbeck mu."""  # = \theta (\mu-Y_t)
return c_theta * (c_mu - y)

def sigma(y, t):
"""Implement the Ornstein–Uhlenbeck sigma."""  # = \sigma
return c_sigma

def dW(delta_t):
"""Sample a random number at each call."""
return np.random.normal(loc=0.0, scale=np.sqrt(delta_t))

ts = np.arange(t_init, t_end + dt, dt)
ys = np.zeros(N + 1)

ys[0] = y_init

for _ in range(num_sims):
for i in range(1, ts.size):
t = t_init + (i - 1) * dt
y = ys[i - 1]
ys[i] = y + mu(y, t) * dt + sigma(y, t) * dW(dt)
plt.plot(ts, ys)

plt.xlabel("time (s)")
h = plt.ylabel("y")
h.set_rotation(0)
plt.show()


The following is simply the translation of the above code into the MATLAB (R2019b) programming language:

%% Initialization and Utility
close all;
clear all;

numSims = 5;            % display five runs
tBounds = [3 7];        % The bounds of t
N      = 1000;          % Compute 1000 grid points
dt     = (tBounds(2) - tBounds(1)) / N ;
y_init = 1;             % Initial y condition

pd = makedist('Normal',0,sqrt(dt)); % Initialize the probability distribution for our
% random variable with mean 0 and
% stdev of sqrt(dt)

c = [0.7, 1.5, 0.06];   % Theta, Mu, and Sigma, respectively

ts    = linspace(tBounds(1), tBounds(2), N); % From t0-->t1 with N points
ys    = zeros(1,N);     % 1xN Matrix of zeros

ys(1) = y_init;
%% Computing the Process
for j = 1:numSims
for i = 2:numel(ts)
t = tBounds(1) + (i-1) .* dt;
y = ys(i-1);
mu      = c(1) .* (c(2) - y);
sigma   = c(3);
dW      = random(pd);

ys(i) = y + mu .* dt + sigma .* dW;
end
figure()
hold on;
plot(ts, ys, 'o')
end