Classical Brownian Motion
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML
np.random.seed(140)
Lets begin by defining Brownian Motion.
Definition: Brownian motion, denoted $B_t$ for $t>0$, is a stochastic process such that
- $B_0$ = 0
- $B_t$ is continous almost surely
- The increments of the process are normally distributed. $B_t - B_s \sim N(0, |t-s|)$
- If $0 \leq t_1 < t_2 < t_3 $ then $B_{t_2} - B_{t_1}$ is independent of $B_{t_3} - B_{t_2}$
Suppose we want to simulate Brownian Motion from $0$ to $t_{\text{max}} = 2$ with 500 frames.
t_max = 2
frames = 500
This means we will update our time every $\frac{t_{max}}{\text{frames}}$ seconds for $0 \leq t \leq t_{\text{max}}$
t = np.linspace(0, t_max, frames)
Next we create an array of normally distributed numbers which will represent the increments at each time step. The variance of these numbers is $\frac{t_{\text{max}}}{\text{frames}}$.
interval_displacement = np.random.normal(scale = np.sqrt(t_max/frames), size=len(t))
The motion of our process is simply the cumulative sum of this array. After all, the position of a sequence is the sequence of partial sums of displacement.
BM = np.cumsum(interval_displacement)
BM[:4]
We can plot the process evolve through time
fig, ax = plt.subplots()
ax.set_xlim((0, t_max))
vertical_height = max(abs(max((BM))), abs(min(BM)))
ax.set_ylim(min(BM),max(BM))
plt.title("Path of Brownian Motion")
plt.xlabel("t")
plt.ylabel("$B_t$")
plt.close();
line, = ax.plot([], [], lw=2)
def BM_path(time):
line.set_data(t[:time], BM[:time])
return (line,)
path_animation = animation.FuncAnimation(fig, BM_path, frames=frames, interval=10, blit=True)
HTML(path_animation.to_html5_video())