% PILES
% copyright by Robert J. Marks II
% "My code isn't pretty - but it works!"
% A pile of sand is emulated.  Pieces of sand are dropped in the center of a sandbox.  They
% can only stack so high.  Above a certain threshold, some of the sand falls onto an adjacent
% pixel where there is less sand.  This new pixel may exceed the stack height and is force to
% shed some of its sand onto adjacent pixels, etc.  An avalanche can occur.  This process follows
% the power law described in Mark Buchanan's book, "Ubiquity".
%
% PARAMETERS (must be changed in the m-file)
% NX, XY = dimensions of the sandbox
% generations = number of times sand is dropped
% grains = number of drops before imaging.  Used to quickly reach steady state.
% stack = how high the sand is stacked before it tumbles
% drop = number of grains of sand dropped each iteration
% flicks = number of times end movie is played.  If zero, no movie is recorded.
% After the iterations are over, you can plot the following:
%		plot(sandboxsize)   gives the number of grains of sand on the table as a function of iteration
% 		plot(fell) gives the number of grains that fall as a function of generation
%		plot(his) gives a log-log histogram of fell
close all 
clear all
%
% PARAMETERS
NX=25; NY=25;			% This is the size of the sand box 
generations=26101;		% The number of times sand is dropped
grains=1;				% Sand drops before display.  Should be less than 'generations'
stack=5;					% How big the stack gets before falling onto neighbors
drop=100;				% Number of grains dropped at a time
flicks=0;				% When the program is over, this is how many times the movie is played.
%							% If zero, no movie is made
mesher=1;				% If =1, display will be a mesh (looks best).  Otherwise, imagesc.
tries=500;				% Max iterations to avoid infinite loop
bins=100;				% Bins between low and high
genstart=100;			% Deletes points earlier during transient
%
% INITIALIZE
frame=0;
pile=zeros(NX,NY);
xo=ceil(NX/2);    yo=ceil(NY/2);
fell=ones(1,generations);
sandboxsize=zeros(1,generations);
%
% GENERATIONS
for g=2:generations
   x=xo;y=yo;
   pile(x,y)=pile(x,y)+drop;
   %%%%
   %Image loop
   if(g>grains)
      a=pile(1,1); b=pile(NX,NY); pile(1,1)=1; pile(NX,NY)= 6*(stack+drop);
      if(mesher==1)
         mesh(pile)
      else
         imagesc(pile)
      end
      title(g);xlabel(fell(g-1));ylabel(sandboxsize(g-1));
      frame=frame+1;
      if(flicks>0)
         M(frame)=getframe;
      else
         M=getframe;
      end
      pile(1,1)=a; pile(NX,NY)=b;
   end 
   iter=0;
   while(and(pile(xo,yo)>=stack,iter<tries))
      tryy=0;
      while(and(pile(x,y)>=stack,tryy<tries))
         xx=x; rr=rand; if(rr<1/3); xx=x+1; end; if(rr>2/3); xx=x-1; end
         yy=y; rr=rand; if(rr<1/3); yy=y+1; end; if(rr>2/3); yy=y-1; end
         if(or(or(xx>NX,xx<1),or(yy>NY,yy<1)))
            old=pile(x,y);
            pile(x,y)= max(pile(x,y)-drop,0); 
            fell(g)=fell(g)+pile(x,y)-old;
            xx=x; yy=y;
         elseif(and(pile(x,y)>pile(xx,yy),pile(x,y)>=stack))
            moved=max(0,floor((pile(x,y)-pile(xx,yy))/2)-1);
            pile(x,y)=pile(x,y)-moved;
            pile(xx,yy)=pile(xx,yy)+moved;
            fell(g)=fell(g)+moved;
            if(moved~=0)
               %%% Image loop
               if(g>grains)
                  a=pile(1,1); b=pile(NX,NY); pile(1,1)=1; pile(NX,NY)= 6*(stack+drop);
                  if(mesher==1)
                     mesh(pile)
                  else
                     imagesc(pile)
                  end
                  title(g);xlabel(fell(g-1));ylabel(sandboxsize(g-1));
                  frame=frame+1;
                  if(flicks>0)
                     M(frame)=getframe;
                  else
                     M=getframe;
                  end
                  pile(1,1)=a; pile(NX,NY)=b;
               end 
               %%%
            end
         end
         tryy=tryy+1;
         x=xx;y=yy;
      end
      iter=iter+1;
   end
   sandboxsize(g)=sum(sum(pile));
end
if(flicks>=1)  
   movie(M,flicks)
end
% Generating log-log histogram
histlow=min(fell)+1;				% Low Point of log-log histogram
histhi=max(fell)+1;				% High Point of log-log histogram
rati=histhi/histlow;
histog=ones(bins+1,1);
if(generations>=genstart)
   for g=genstart:generations
      for b=1:bins+1 
         if(and(histlow*(rati^((b-1)/bins))<fell(g),fell(g)<=histlow*(rati^(b/bins))))
            histog(b)=histog(b)+1;
         break
         end
      end
   end
end
figure
semilogy(histog); title('log-log histogram');
figure
plot(sandboxsize); title('sandbox size');
figure
plot(fell); title('fallen grains');
e website templates.