Unidimensional Brownian Bridges

The idea behind the construction of a (unidimensional) Brownian Bridge it is very simple. We simulate two Brownian motions, one moving forward in time and the other in the reverse time direction. If there is an intersection between these two paths, from that point we build a Bridge.

In [12]:
using Plots
In [13]:
nsteps = 1000
initial_t = 0 ;
final_t = 10 ;
x = linspace(initial_t,final_t,nsteps) ;
sigma = sqrt((final_t - initial_t)/nsteps)
y = sigma * randn(nsteps);
y[1] = 0;
z = cumsum(y) ;
plot(x,z,legend = false)
Out[13]:
0.0 2.5 5.0 7.5 10.0 -4 -2 0 2
In [14]:
# The Forward Process
nsteps = 1000;   # the number of points in each path

# the parameters of the Brownian motion with a drift
initial_t = 0 ;
final_t = 10 ;
# delta is the time jump (or step size)
delta = (final_t - initial_t)/nsteps
Delta = final_t - initial_t

# the parameters of a hyperbolic diffusion 
theta = 4 
sigma = 2
sqsigma = 4

# the initial value of the process
x0 = 1

# nonconstant drift and nonconstant diffusion coefficient
driftfunc(t) = -(theta * t)/sqrt(1+t^2)
volfunc(t) = sigma

# the time grid
time_array = linspace(initial_t,final_t,nsteps)
# the standard gaussian values
gauss = sqrt(delta) * randn(nsteps) 

hypdiff = zeros(nsteps)
hypdiff[1] = x0

for i in 2:nsteps
    
    hypdiff[i] = hypdiff[i-1] + driftfunc(hypdiff[i-1]) * delta + volfunc(hypdiff[i-1]) * gauss[i]
    
end

plot(time_array,hypdiff,legend = false)
Out[14]:
0.0 2.5 5.0 7.5 10.0 -2 -1 0 1 2
In [15]:
# The Backward Process
nsteps = 1000;   # the number of points in each path

# the parameters of the Brownian motion with a drift
initial_t = 0 ;
final_t = 10 ;
# delta is the time jump (or step size)
delta = (final_t - initial_t)/nsteps

# the parameters of a hyperbolic diffusion 
theta = 4 
sigma = 2
sqsigma = 4

# the initial value of the process
x0 = 2

# nonconstant drift and nonconstant diffusion coefficient
driftfunc(t) = -(theta * t)/sqrt(1+t^2)
volfunc(t) = sigma

# the time grid
time_array = linspace(initial_t,final_t,nsteps)
# the standard gaussian values
gauss = sqrt(delta) * randn(nsteps) 

hypdiff = zeros(nsteps)
hypdiff[1] = x0

for i in 2:nsteps
    
    hypdiff[i] = hypdiff[i-1] + driftfunc(hypdiff[i-1]) * delta + volfunc(hypdiff[i-1]) * gauss[i]
    
end
# just reverse the solution.
reversed = flipdim(hypdiff,1)

plot(time_array,reversed,legend = false)
Out[15]:
0.0 2.5 5.0 7.5 10.0 -2 -1 0 1 2
In [16]:
# nonconstant drift and nonconstant diffusion coefficient
driftfunc(t) = -(theta * t)/sqrt(1+t^2)
volfunc(t) = sigma

function hypdiffusion(t_init, t_finit , nsteps , theta , sigma , x_init)
   
    delta = (t_finit - t_init)/nsteps
    tarray = linspace(t_init , t_finit , nsteps)
    gauss = sqrt(delta) * randn(nsteps)
    
    diff = zeros(nsteps)
    diff[1] = x_init
    
    for i in 2:nsteps
        
         diff[i] = diff[i-1] + driftfunc(diff[i-1]) * delta + volfunc(diff[i-1]) * gauss[i]
    
    end
    
    return tarray , diff
end
Out[16]:
hypdiffusion (generic function with 1 method)
In [17]:
# the parameters of the Brownian motion with a drift
nsteps = 1000
initial_t = 0 ;
final_t = 5 ;

# the parameters of a hyperbolic diffusion 
theta = 4 
sigma = 2

# the initial value of the process
x0 = 10

t_array , forward = hypdiffusion(initial_t , final_t , nsteps , theta , sigma , x0)

plot(t_array,forward, label = "Forward Process")

xf = -10
# exactly as before but we reverse the time orientation
backward = flipdim(hypdiffusion(initial_t , final_t , nsteps , theta , sigma , xf)[2],1)

plot!(t_array,backward, label = "Backward Process" , legend = :topright)
Out[17]:
0 1 2 3 4 5 -10 -5 0 5 10 Forward Process Backward Process
In [18]:
# this function returns 0 if a > b and 1 otherwise
function zeroum(a,b)
    out = 1
    
    if a > b
        out = 0 
    end
    
    return out
    
end

function intersectionBM(forward , backward)
    
    nsteps = size(forward,1)
    diff  = zeros(nsteps)
    
    if (forward[1] > backward[nsteps])
        diff = zeroum.(forward,backward)
    else
        diff = zeroum.(backward,forward)
    end
    
    return diff
end

function findBMbridge(forward , backward)
   
    nsteps = size(forward,1)
    
    diff = intersectionBM(forward , backward)
    index = findfirst(diff,1)
    
    if index > nsteps -1 
        println("there are no bridge")
    else
        println("there is a bridge!!!")
        println("$(index)")
    end
    
    bridge = cat(1,forward[1:index-1],backward[index:nsteps])
    
    return bridge
end
Out[18]:
findBMbridge (generic function with 1 method)
In [19]:
plot(t_array,forward, title = "BrownianBridge between $x0 and $xf.", label = "Forward Process")
plot!(t_array,backward, label = "Backward Process" , legend = :topright)
plot!(t_array,findBMbridge(forward,backward),lw = 2, label = "The Bridge")

#savefig("HelloBridge.pdf")
there is a bridge!!!
413
Out[19]:
0 1 2 3 4 5 -10 -5 0 5 10 BrownianBridge between 10 and -10. Forward Process Backward Process The Bridge
In [20]:
findfirst(intersectionBM(forward,backward),1)
Out[20]:
413