Algorithm 3.1 MCMC for Dice Rolls
import numpy as np
import random
import matplotlib.pyplot as plt
# target density
f = [0,0,1,2,3,4,5,6,5,4,3,2,1]
nTrials = 5000; #20000
d = [0]*nTrials
x = 5 # starting state
for i in range(nTrials):
# do the proposal
u = random.random()
if( x == 2):
if( u < 0.5):
y = 3
else:
y = 2
elif( x == 12):
if( u < 0.5):
y=11
else:
y = 12
else:
if( u < 0.5):
y = x+1
else:
y = x-1
# now do the acceptance
h = min(1,f[y]/f[x])
u = random.random()
if( u < h ):
x=y #move to y, else stay in x
d[i] = x
plt.hist(d,bins = 11)
plt.savefig("tentfig.png")
plt.show()
Algorithm 3.2 Annealing the Ising Model
import numpy as np
import matplotlib.pyplot as plt
def flipk(x,k):
y = [0]*len(x)
for i in range(len(x)):
y[i] = x[i]
y[k] = -x[k]
return y
nTrials=2000; burnin=3000;
d = [0]*nTrials
beta=.01; M=0;
#beta=1; M=0;
x = 2*np.random.randint(0,2,4)-1 #random 4-vector of +/-1
Hx = -(x[0]*x[1]+x[2]*x[3]+x[0]*x[2]+x[1]*x[3]);
for t in range(burnin+nTrials):
k = np.random.randint(0,4) # index to flip
y = flipk(x,k)
Hy = -(y[0]*y[1]+y[2]*y[3]+y[0]*y[2]+y[1]*y[3]);
h = min(1,np.exp(-beta*(Hy-Hx)));
#print(x)
#print(y)
#print(
#"Hx "+str(Hx)+" Hy "+str(Hy)+", beta*deltH "+str(beta*(Hy-Hx))+" h="+str(h))
if( np.random.rand() < h ):
x = y
Hx = Hy
if( t > burnin):
Mx = x[0]+x[1]+x[2]+x[3];
#print("Mx= "+str(Mx))
M = M + Mx; # to obtain avg mag moment
d[t-burnin] = Mx;
# compute avg moment per spin
M = (M/float(nTrials))/4.0;
print(M)
def countElements(seq) -> dict:
hist = {}
for i in seq:
hist[i] = hist.get(i, 0) + 1
return hist
counts = countElements(d)
plt.bar(counts.keys(),counts.values())
plt.show()
Algorithm 3.3 Hastings Modification of MCMC
import numpy as np
import random
import matplotlib.pyplot as plt
def g(x,y):
if( x == 2 or x == 12):
return 0.5
if( y == x+1 ):
return 0.67
else:
return 0.33
def run(hastings):
d = [0]*nTrials
x = 5 # starting state
nAccept = 0
for i in range(nTrials):
# do the proposal
u = random.random()
if( x == 2):
if( u < 0.5):
y = 3
else:
y = 2
elif( x == 12):
if( u < 0.5):
y=11
else:
y = 12
else:
if( u < 0.67):
y = x+1
else:
y = x-1
gxy = g(x,y)
gyx = g(y,x)
# now do the acceptance
if( hastings ):
h = min(1,f[y]*gyx/(f[x]*gxy))
else:
h = min(1,f[y]/f[x])
u = random.random()
if( u < h ):
x=y #move to y, else stay in x
nAccept += 1
d[i] = x
return d,nAccept
# target density
f = [0,0,1,2,3,4,5,6,5,4,3,2,1]
nTrials = 20000
"""
d,nAccept = run(True) #with hastings
print("acceptanceRate= "+str(nAccept/float(nTrials)))
plt.hist(d,bins=11,density=True)
plt.title('Metropolis-Hastings Dice Roll Calculation')
plt.savefig('mhDiceRollfig.png')
"""
#fig,axs = plt.subplots(nrows=1, ncols=2)
#axs[0].hist(d,bins = 11)
d,nAccept = run(False) #w/o hastings
print("acceptanceRate= "+str(nAccept/float(nTrials)))
#axs[1].hist(d,bins = 11)
plt.hist(d,bins=11,density=True)
plt.title('Metropolis Dice Roll Calculation')
plt.savefig('metroDiceRollfig.png')
plt.show()
Algorithm 3.4 MCMC for Graph Matching
import numpy as np
import random
import matplotlib.pyplot as plt
# initialize the first two rows of E to the given graph, a 3x24 matrix
# 1st item in a column is one end of the edge, 2nd is the other end
# initialize third row to 0, start with an empty match set
E = [[0]*14, [0]*14, [0]*14]
E[0][0]=0; E[1][0]=6; E[0][1]=0; E[1][1]=8;
E[0][2]=0; E[1][2]=10; E[0][3]=1; E[1][3]=7;
E[0][4]=1; E[1][4]=10; E[0][5]=2; E[1][5]=9;
E[0][6]=2; E[1][6]=11; E[0][7]=3; E[1][7]=6;
E[0][8]=3; E[1][8]=8; E[0][9]=3; E[1][9]=11;
E[0][10]=4; E[1][10]=10; E[0][11]=4; E[1][11]=11;
E[0][12]=5; E[1][12]=7; E[0][13]=5; E[1][13]=9;
s = [0]*14; # array to count no. matches of size k
k=0; # match set size, initially empty
nTrials = 990000
for t in range(nTrials):
i=np.random.randint(14) # select edge unif. at random
if( E[2][i] == 1): #check if i is in the current match set
E[2][i]=0; # remove it
k=k-1; # decrement matching size
else:
l=E[0][i]; r=E[1][i]; # left, right ends of i
kl=-1; kr=-1; #search current match set for l and r
for j in range(14): # loop over all edges
if( E[2][j] == 1): # this edge is in the match set
if( l == E[0][j] or l == E[1][j]): # l is covered
kl=j;
if( r == E[0][j] or r == E[1][j]): # r is covered
kr = j;
#end if j in match set}
#end loop over edges}
if( kl == -1 and kr == -1): # neither l or r covered
E[2][i]=1; #add edge i to the match set
k=k+1; # increment match set size
elif( kl >= 0 and kr == -1): # only left end covered
E[2][kl]=0; E[2][i]=1; # swap edges
elif( kl == -1 and kr >= 0): # only right end covered
E[2][kr]=0; E[2][i]=1; # swap edges
#end check covered
#end check i in current match set}
#increment the count for the current size}
s[k] += 1;
#end loop over trials
print("number of matchings of size k = 0,1,...: "+str(s));