Algorithm 4.1 30 step random walk
import numpy as np
import matplotlib.pyplot as plt
nSteps = 30;
nTrials = 200000;
H = [0]*nTrials;
for j in range(nTrials):
# do all nSteps coin tosses
T = 2*(np.random.rand(nSteps) < 0.5 )-1;
H[j] = sum(T);
plt.hist(H)
plt.show()
Algorithm 4.2 2d random walk
import numpy as np
import random
import matplotlib.pyplot as plt
sig=2; #step size std dev
nSteps = 2000; #steps each walk
nSteps = 2*int(nSteps/2); # assure even}
x = [0]*nSteps; y = [0]*nSteps;
for i in range(1,nSteps):
#print(x[i-1],y[i-1])
theta = 2*np.pi*np.random.random()
N = np.random.normal(0,sig)
x[i]= x[i-1]+N*np.cos(theta);
y[i]= y[i-1]+N*np.sin(theta);
#typical walk
plt.subplot(2,2,1); #1st in 2x2 plots, upper left
plt.plot(x,y);
plt.title('(A) Typical walk for '+str(nSteps)+' steps');
plt.xlabel('X position');
plt.ylabel('Y position');
#do the walk from subStart to subEnd}
sub1Start = 500;
sub1End = 1500;
xsub1 = [0]*(sub1End-sub1Start)
ysub1 = [0]*(sub1End-sub1Start)
k = 0;
for i in range(sub1Start,sub1End):
xsub1[k] = x[i];
ysub1[k] = y[i];
k = k+1;
plt.subplot(2,2,2); #2nd in 2x2 plots, upper right
plt.title("Walk (A) from step 500 to 1500");
plt.plot(xsub1,ysub1);
sub2Start = 1000;
sub2End = 1300;
xsub2 = [0]*(sub2End-sub2Start)
ysub2 = [0]*(sub2End-sub2Start)
k = 0;
for i in range(sub2Start,sub2End):
xsub2[k] = x[i];
ysub2[k] = y[i];
k = k+1;
plt.subplot(2,2,3);
plt.title("Walk (A) from step 1000 to 1300");
plt.plot(xsub2,ysub2);
nWalks = 400; # walks for density
Endx = [0]*nWalks; Endy = [0]*nWalks;
for j in range(nWalks):
x = [0]*nSteps; y = [0]*nSteps;
for i in range(1,nSteps):
theta = 2*np.pi*np.random.random()
N = np.random.normal(0,sig)
x[i]= x[i-1]+N*np.cos(theta);
y[i]= y[i-1]+N*np.sin(theta);
Endx[j] = x[-1];
Endy[j] = y[-1];
#density plot
plt.subplot(2,2,4);
plt.scatter(Endx,Endy,s=3);
plt.title("Density Plot for "+str(nSteps)+" steps");
plt.xlabel('X end');
plt.ylabel('Y end');
plt.tight_layout();
plt.show()
Algorithm 4.3 Pricing a Call Option
import numpy as np
import matplotlib.pyplot as plt
nDays = 90;
dt = 1/365.0; # use time in years
T = nDays*dt; # expiry in years
S0=20; # starting stock price
X=25; # strike price
r = .031; # risk-free rate
sigma = .6; # volatility
expTerm = r*dt;
stddev = sigma*np.sqrt(dt);
nTrials = 10000;
S90 = [0]*nTrials;
value=0;
for j in range(nTrials):
# make a vector of N(0,1) random numbers
N = np.random.randn(nDays);
S = S0;
for i in range(nDays):
dS = S*(expTerm + stddev*N[i]);
S = S + dS;
S90[j] = S; # to histogram
value = value + max(S-X,0);
value = value/float(nTrials); # expected value
price = np.exp(-r*T)*value # discount back
print("price= "+str(Price))
plt.hist(S90,bins=30)
plt.show()
Algorithm 4.4 Fortune under Kelly Bets
import numpy as np
import matplotlib.pyplot as plt
def kellyEval(nPlays,bf):
F = 1 # starting fortune
# save the history
h = [0]*nPlays; h[0] = F;
for i in range(1,nPlays):
w = F*bf # wager}
r = np.random.random()
if( r < 0.6):
F += w
else:
F -= w
h[i] = F
return h
nPlays = 300
bf = [0.05,0.1,0.2,0.25]; # betting fraction
for i in range(len(bf)):
h = kellyEval(N,bf[i])
eF = h[-1]; # ending fortune
gain = np.exp((1/float(N))*np.log(h[-1]))}
print("betting fraction: "+str(bf[i])+
" ending fortune= "+str(eF)+" gain= "+str(gain))
plt.subplot(2,2,i+1)
plt.plot(range(N),h)
plt.tight\_layout();
plt.show()
Algorithm 4.5 Calculating the Fundamental Matrix
import numpy as np
I = np.identity(5)
p = 0.25
Ph = np.zeros((5,5))
for i in range(5):
if( i == 0):
Ph[i][1] = p
elif( i == 1):
Ph[i][0] = Ph[i][2] = Ph[i][3] = p
elif( i == 2):
Ph[i][1] = Ph[i][4] = p
elif( i == 3 ):
Ph[i][1] = Ph[i][4] = p
else:
Ph[i][2] = Ph[i][3] = p
N = np.linalg.inv(I-Ph)
R = np.array([[2*p,p],[0,p],[0,2*p],[2*p,0],[2*p,0]])
B = np.matmul(N,R)
print(B)
Algorithm 4.6 Kinetic MC for a Lattice of "Grains"
import numpy as np
def setRates(stateVec):
rates = [0]*nSites
for i in range(nSites):
if( stateVec[i] == 0 ):
rates[i] = 1 #A to B
else:
rates[i] = 5 #B to A
return rates
def makeBreakPts(rates):
bPts = [0]*nSites
bPts[0] = rates[0]
for i in range(1,nSites):
bPts[i] = bPts[i-1]+rates[i]
return bPts
def rouletteSelect(rates):
bPts = makeBreakPts(rates)
U = np.random.uniform(0,bPts[-1])
k=0;
while( U >= bPts[k]):
k += 1;
#k is selected
return k
#---main---
nSites = 8 # 0 for A, 1 for B
stateVec = [0]*nSites # initial state, all A's
rates = setRates(stateVec) # set the rates
R = sum(rates)
nIts = 64
avgFracB = 0 #average fraction of B sites
# track the accumulated number of B sites
accnBsites = 0
t = 0
for i in range(nIts):
# time to next event
deltT = (-1/R)*np.log(np.random.uniform())
t += deltT
# choose a site to flip
k = rouletteSelect(rates)
stateVec[k] = 1-stateVec[k] # flip site k
# update rates
if( stateVec[k] == 0 ):
rates[k] = 1 # rates[k] used to be 5
R = R-5+1
else:
rates[k] = 5
R = R-1+5 # rates[k] used to be 1
nBsites = sum(stateVec)
accnBsites += nBsites
avgFracB += nBsites/float(nSites)
print("ending time: ",t)
avgFracB /= nIts
print("avg.Frac. of B sites",avgFracB)
accnAsites = nSites*nIts - accnBsites
print("ratio A to B sites= ",
accnAsites/float(accnBsites))