function [count] = KRS(n,prob_add,prob_del,prob_swap,interval,total_count) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This program solves Challenge 18.4 (b) % in Homework #2 % SUNGWOO PARK % KRS.m OCT 2006 % Minor changes: DPO 10/2006 (to comments and to normalization) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function [count] = KRS(n,prob_add,prob_del,prob_swap,interval,total_count) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % For an n by n lattice, we consider covering it with a mixture of % monomers and dimers. This function estimates the number of distinct % arrangements of k dimers using the KRS algorithm. % This algorithm is Monte Carlo based, and forms a sequence of % dimer arrangements. At each step, we either add a dimer, delete % a dimer, swap a dimer, or make a null move. % % This function KRS has six input parameters % % n - size of lattice % prob_add - a probability to add a new dimer. % prob_del - a probability to delete an existent dimer. % prob_swap - a probability to swap a dimer with a new one. % interval - how many steps to change arrangement of dimers. % before counting a new arrangement % total_count % % There is one output parameter: % % The array count stores the desired coefficients: % count(j) is the estimate of the number of distinct arrangements % of j-1 dimers in the nxn lattice, j=1,...,n(n-1)+1. % % Reference: % C. Kenyon, D. Randall, and A. Sinclair, % Approximating the number of monomer-dimer coverings of a lattice % J. Stat. Phys. 83, 637 (1996) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% close all; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (1) Initialization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Construct n by n array called lattice corresponding to the nodes % of the monomer-dimer lattice. % The element is 0 if it is a monomer, % 1 if it is a dimer connected to its right neighbor, % -1 if it is a dimer connected to its left neighbor, % 2 if it is a dimer connected to its upper neighbor, % -2 if it is a dimer connected to its lower neighbor, % Initially, the lattice is filled with monomers. lattice = zeros(n,n); % E = number of edges. E = 2* n*(n-1); % upper bound of # of dimers max_dimer = E/2; % Initialize the counts to zero. count = zeros(max_dimer+1,1); numOfDimer = 0; for i=1:total_count % We will rearrange a dimer interval times after counting for j=1:interval, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (1) Choose an adjacent pair of sites %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if(rand(1,1)>0.5) % create horizontal edge x = ceil(n * rand(1,1)); y = ceil((n-1)* rand(1,1)); p1 = [x y]; p2 = [x y+1]; else % create vertical edge x = ceil((n-1)* rand(1,1)); y = ceil(n * rand(1,1)); p1 = [x y]; p2 = [x+1 y]; end statusP1 = lattice(p1(1),p1(2)); statusP2 = lattice(p2(1),p2(2)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (2) - (a) when both sites have monomers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if statusP1 == 0 && statusP2 == 0 if(rand(1) < prob_add) % decide to add with prob_add numOfDimer = numOfDimer +1; if p1(1) == p2(1) %if a new edge is horizontal lattice(p1(1),p1(2)) = 1; lattice(p2(1),p2(2)) = -1; else %if a new edge is vertical lattice(p1(1),p1(2)) = 2; lattice(p2(1),p2(2)) = -2; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (2) - (b) when the sites are occupied by a single dimer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% elseif ((statusP1 == 1 && statusP2 == -1 && p1(1)==p2(1)) ||(statusP1 == 2 && statusP2 == -2 && p1(2)==p2(2)) ) if(rand(1) < prob_del) % decide to delete with prob_del numOfDimer = numOfDimer -1; lattice(p1(1),p1(2)) = 0; lattice(p2(1),p2(2)) = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (2) - (c) when one site is occupied by a dimer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% elseif statusP1 ==0 || statusP2 ==0 if(rand(1) < prob_swap) % decide to swap with prob_swap %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % * delete the overlapped dimer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if statusP2==0 switch(statusP1) case 1 lattice(p1(1),p1(2)+1)=0; case -1 lattice(p1(1),p1(2)-1)=0; case 2 lattice(p1(1)+1,p1(2))=0; case -2 lattice(p1(1)-1,p1(2))=0; end elseif statusP1 ==0 switch(statusP2) case 1 lattice(p2(1),p2(2)+1)=0; case -1 lattice(p2(1),p2(2)-1)=0; case 2 lattice(p2(1)+1,p2(2))=0; case -2 lattice(p2(1)-1,p2(2))=0; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % * add a new dimer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if p1(1) == p2(1) %if a new edge is horizontal lattice(p1(1),p1(2)) = 1; lattice(p2(1),p2(2)) = -1; else %if a new edge is vertical lattice(p1(1),p1(2)) = 2; lattice(p2(1),p2(2)) = -2; end end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (3) count the current configuration %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% count(numOfDimer+1) = count(numOfDimer+1)+1; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (4) DPO: Normalize the counts using the fact % that C(1) = n(n-1)*2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if count(2)~=0 count = n*(n-1)*2*floor( count./count(2) ); end sum =0; % Print the result and plot the function C(k). for i=0:max_dimer fprintf('C(%d)=\t%d\n',i,count(i+1)); plot(i,count(i+1),'r+'); sum = sum + count(i+1); hold on ; end fprintf('Sum of C(k) = %d\n',sum); xlabel('k'); ylabel('C(k)'); title('KRS algorithm');