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))