Page 111
Matlab: Dice Rolls via Markov Chain Monte Carlo
f=[0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1];
d=zeros(1,20000); % for histogramming
x=5;
for i = 1:20000
U = rand;
if x == 2
if U < 0.5
y = 3;
else
y = 2;
end
elseif x == 12
if U < 0.5
y = 11;
else
y = 12;
end
else
if U < 0.5
y = x-1;
else
y = x+1;
end
end
h = min(1,f(y)/f(x));
U = rand;
if U < h
x = y;
end
d(i) = x; % record the state
end
a = 1:1:12;
hist(d,a)
[N,h] = hist(d,a)
Page 122
Java: Ising Simulation
import java.io.*;
import java.util.*;
public class isingModel
{
static String[] helptext =
{
"Usage:\n\t < invoke program>",
""};
int nTrials = 9900;
int startUp = 3000;
int width = 16, hghth = 16;
double beta = .01; //beta=1/(kT), beta=1 low temp, .06 high temp
static Random r;
static long seed;
//ccc===
public
isingModel()
{
double magMoment = 0;
//create a random starting +1/-1 vector
isingCritter wCrit = new isingCritter(width,hghth,1,0,'r');
isingCritter tCrit = new isingCritter(width,hghth,1,0,'r');
isingCritter x, y; //pointers
int k, row, col;
double a=0;
//main loop
x = tCrit; //random start
for(int i=0; i < nTrials+startUp; ++i)
{
//x.printSpins();
//x = current, y = proposed
if( x == tCrit )
y = wCrit;
else
y = tCrit;
//select site to flip
k = (int)(x.sigma.length*r.nextDouble());
for( int j=0; j < x.sigma.length; ++j ) y.sigma[j] = x.sigma[j];
y.sigma[k] *= -1; //flip bit k
y.calcHamiltonian();
//System.out.format("Delta E= %.1f\n",y.E - x.E);
a = Math.min(1,Math.exp(-beta*(y.E - x.E)));
//decide to accept or not
if( r.nextDouble() < a ) x = y;
//update the magnetic moment
if( i > startUp )
{
magMoment += (double)x.calcMagneticMoment();
}
}
x.printSpins();
magMoment /= nTrials;
System.out.format("avg mag. moment per spin= %.3f\n",
magMoment/(width*hghth));
}
/*=====mmm=====*/
public static void
main(String[] argv)
{
seed = System.currentTimeMillis();
//seed = 17; // remove // for testing
r = new Random(seed);
isingModel im = new isingModel();
}
}
//kkk===
class isingCritter
{
int width, hghth;
byte[] sigma; //up = +1, down = -1
double J, H; //J=spin-spin interaction, H=external field
double E; //hamiltonian (= energy)
char boundaryType = 'p'; //p=periodic, f=free
int M; //magnetic moment
//ccc===
public
isingCritter(int w, int h)
{
hghth = h; width = w;
sigma = new byte[w*h];
J = 1; H = 0;
randomInit();
calcHamiltonian();
}
//ccc===
public
isingCritter(int w, int h, double J, double H, char initType)
{
hghth = h; width = w;
sigma = new byte[w*h];
this.J = J; this.H = H;
if( initType == 'u' )
spinUpInit();
else
randomInit();
calcHamiltonian();
}
//===
void
randomInit()
{
for( int i=0; i < sigma.length; ++i)
{
if( isingModel.r.nextDouble() < .5 )
sigma[i] = 1;
else
sigma[i] = -1;
}
}
//===
void
spinUpInit()
{
for( int i=0; i < sigma.length; ++i)
{
sigma[i] = 1;
}
}
//===
/**
* Here we use the free boundary condition, i.e. the spins
* on the boundary are coupled only to spins of the interior
* and not to spins on the opposite end of the lattice
*/
void
calcHamiltonian()
{
int r,c;
//printSpins();
E=0;
/**
* free boundary calculation
*/
//go along the columns first between each row
for( r=0; r < hghth-1; ++r)
{
for( c=0; c < width; ++c)
{
E += -J*(sigma[c+r*width]*sigma[c+(r+1)*width]);
}
}
//now go along the rows between each column
for( c=0; c < width-1; ++c)
{
for( r=0; r < hghth; ++r)
{
E += -J*(sigma[c+r*width]*sigma[c+1+r*width]);
}
}
/**
* if boundary condition is periodic, do this too
*/
if( boundaryType == 'p' )
{
r = (hghth-1)*width;
for( c=0; c < width; ++c)
E += -J*sigma[c]*sigma[c+r];
c= width-1;
for( r=0; r < width*hghth; r += width)
E += -J*sigma[r]*sigma[c+r];
}
/**
* now figure in the external field
* assume aligned with 'up'
*/
if( H != 0)
{
for( int i=0; i < sigma.length; ++i)
E += -H*sigma[i];
}
//System.out.println("total: E= "+E+"\n");
}
//===
/**
* M(x) = net up vs down spins in absence of external field
*/
int
calcMagneticMoment()
{
M = 0;
for( int i=0; i < sigma.length; ++i)
M += sigma[i];
//System.out.println("magnet moment: M= "+M+"\n");
return M;
}
//===
void
printSpins()
{
int j=0;
for( int k=0; k < sigma.length; ++k)
{
System.out.format("%c ",(sigma[k]==1)?'+':'-');
//System.out.format("%2d ",sigma[k]);
if( ++j==width )
{
System.out.println("");
j=0;
}
}
System.out.println("");
}
}
Page 125
Matlab: Ising Simulation
nTrials=2000; startup=3000;
d=zeros(1,nTrials); %to histogram
beta=.01; M=0;
x=2*round(rand(1,4))-1; %random 4-vector of +/-1
Hx = -(x(1)*x(2)+x(3)*x(4)+x(1)*x(3)+x(2)*x(4));
for t = 1:startup+nTrials
k = fix(1+4*rand); %index to flip
y = x; y(k)= -x(k);
Hy = -(y(1)*y(2)+y(3)*y(4)+y(1)*y(3)+y(2)*y(4));
h = min(1,exp(-beta*(Hy-Hx)));
if rand < h
x = y;
end
if t > startup
Mx = x(1)+x(2)+x(3)+x(4);
M = M + Mx; % to obtain avg mag. mom.
d(t-startup) = Mx;
end
end
r = -4:1:4;
hist(d,r)
% compute avg moment per spin
M = (M/nTrials)/4;
Page 128
Matlab: Metropolis Algorithm for Counting, Monomer/Dimer Problem
% this pertains to figure 3.8; in the figure the vertices are "a"
% through "f" on the left and "1" through "6" on the right but here
% we use 1 through 6 for the left vertices and 7 through 12 for the
% right ones. E(i,j)=k means this: j designates the edge so j runs
% from 1 to 14, i=1 is for the left vertex of the edge and i=2 is
% for the right vertex and k is which vertex in the figure. Edge 1
% runs from "a" to "1" so E(1,1)=1 and E(2,1)=7. Edge 2 runs from "a"
% to "3" so E(1,2)=1 and E(2,2)=9 and so on.
% initialize the first two rows of E to the given graph, a 3x14 matrix
% initialize third row to 0, start with an empty match set
E=zeros(3,14);
E(1,1)=1; E(2,1)=7; E(1,2)=1; E(2,2)=9;
E(1,3)=1; E(2,3)=11; E(1,4)=2; E(2,4)=8;
E(1,5)=2; E(2,5)=11; E(1,6)=3; E(2,6)=10;
E(1,7)=3; E(2,7)=12; E(1,8)=4; E(2,8)=7;
E(1,9)=4; E(2,9)=9; E(1,10)=4; E(2,10)=12;
E(1,11)=5; E(2,11)=11; E(1,12)=5; E(2,12)=12;
E(1,13)=6; E(2,13)=8; E(1,14)=6; E(2,14)=10;
s=zeros(1,14); % array to count # matches of size k
s0=0; % need to get size 0 too
k=0; % the initial match set is empty
for t=1:990000 % 990000 trials
i=1+floor(14*rand); % select edge unif. at random
if E(3,i) == 1 %check if i is in the current match set
E(3,i)=0; % remove it
k=k - 1; % decrement matching size
else
l=E(1,i); r=E(2,i); % left, right ends of i
kl=0; kr=0; %search current match set for l and r
for j=1:14 % loop over all edges
if E(3,j) == 1 %this edge is in the match set
if l == E(1,j) | l == E(2,j) % l is covered
kl=j;
end
if r == E(1,j) | r == E(2,j) % r is covered
kr == j;
end
end % if j in match set
end %loop over edges
if kl == 0 & kr == 0 % neither l or r covered
E(3,i)=1; %add edge i to match
k=k+1; % increment match set size
elseif kl ~= 0 & kr == 0 % only left end covered
E(3,kl)=0; E(3,i)=1; % swap edges
elseif kl == 0 & kr ~= 0 % only right end covered
E(3,kr)=0; E(3,i)=1; % swap edges
end
end % check i in current match set
% increment the count for the current size
if k == 0
s0=s0+1;
else
s(k)=s(k)+1;
end
end % loop over trials
s0 % print results
s