Skip to content

Instantly share code, notes, and snippets.

@delta2323
Created March 13, 2016 11:23
Show Gist options
  • Save delta2323/6bb572d9473f3b523e6e to your computer and use it in GitHub Desktop.
Save delta2323/6bb572d9473f3b523e6e to your computer and use it in GitHub Desktop.
Brownian Bridge sample code
#!/usr/bin/env python
import numpy
import six
from matplotlib import pyplot
seed = 0
N = 100
M = 10
numpy.random.seed(seed)
def sample_path_batch(M, N):
dt = 1.0 / N
dt_sqrt = numpy.sqrt(dt)
B = numpy.empty((M, N), dtype=numpy.float32)
B[:, 0] = 0
for n in six.moves.range(N - 1):
t = n * dt
xi = numpy.random.randn(M) * dt_sqrt
B[:, n + 1] = B[:, n] * (1 - dt / (1 - t)) + xi
return B
B = sample_path_batch(M, N)
pyplot.plot(B.T)
pyplot.show()
@CyBu
Copy link

CyBu commented Feb 14, 2018

This is useful thanks!
Generally, brownian bridge is such that: Z0 = Z1 = 0, which is not true here.
So I suggest amending to:

def sample_path_batch(M, N):
    dt = 1.0 / (N -1)                                                          #  changed from 1.0 / N
    dt_sqrt = numpy.sqrt(dt)
    B = numpy.empty((M, N), dtype=numpy.float32)
    B[:, 0] = 0
    for n in six.moves.range(N - 2):                                           # changed from "for n in six.moves.range(N - 1)"
         t = n * dt
         xi = numpy.random.randn(M) * dt_sqrt
         B[:, n + 1] = B[:, n] * (1 - dt / (1 - t)) + xi
    B[:, -1] = 0                                                               # added: set the last B to Zero
    return B

Which avoids the last B to be truncated as shown in the attached plot.
Let me know what you think please.
figure_1

@acse-zrw20
Copy link

acse-zrw20 commented Aug 12, 2021

I was using this code but needed it to work with an arbitrary shape so I made that and thought to share it here

in_shape = (60, 20, 20)
N = 10

def sample_path_batch_shape(N, in_shape):
    dt = 1.0 / (N -1)           
    dt_sqrt = np.sqrt(dt)
    B = np.empty((N,) + in_shape, dtype=np.float32)
    B[0, :, :, :] = 0
    for n in six.moves.range(N - 2):                
         t = n * dt
         xi = np.random.randn(*in_shape) * dt_sqrt
         B[n + 1] = B[n] * (1 - dt / (1 - t)) + xi
    B[-1] = 0                                                 
    return B

@Kuo-TingKai
Copy link

I was using this code but needed it to work with an arbitrary shape so I made that and thought to share it here

in_shape = (60, 20, 20)
N = 10

def sample_path_batch_shape(N, in_shape):
    dt = 1.0 / (N -1)           
    dt_sqrt = np.sqrt(dt)
    B = np.empty((N,) + in_shape, dtype=np.float32)
    B[0, :, :, :] = 0
    for n in six.moves.range(N - 2):                
         t = n * dt
         xi = np.random.randn(*in_shape) * dt_sqrt
         B[n + 1] = B[n] * (1 - dt / (1 - t)) + xi
    B[-1] = 0                                                 
    return B

You inspire me that a brownian bridges with arbitrary boundary condition may be an interesting problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment