% bfs.m % This draws the Schottky circles, based on the algorithm described % in Box 12: Breadth-first search (p. 115). % % SYNTAX: bfs.m(levstart,levend) % % levstart = level to start of plotting % levend = level to end % Here, level refers to the Schottky circle level. function bfs(levstart,levend); % 0. Initialize axes axis equal; axis ([-2.5 2.5 -2.5 2.5]); hold on; colors=['r' 'y' 'g' 'b' 'm' 'c']; % colors array % 1. Initialize generators and circles ready. theta=pi/4; b=[1 cos(theta); cos(theta) 1]/sin(theta); % generators a=[1 i*cos(theta); -i*cos(theta) 1]/sin(theta); gens=cell(4,1); gens{1}=a;gens{2}=b;gens{3}=inv(a);gens{4}=inv(b); invs=[3 4 1 2]; % inverse of 1 is 3, etc. group=cell(1000000,1); % to store words, eg. aaBA circ(1).cen=sec(theta)*i; circ(1).rad=tan(theta); for j=2:4 circ(j).cen=circ(j-1).cen*-i; circ(j).rad=tan(theta); end % 2. Enumeration loop num=[1 5]; % indices where levels 1 and 2 begin % lev=1 for i=1:4 group{i}=gens{i}; % add word to list tag(i)=i; % tag with the last generator used end inew=5; % initialize counter for lev=2:levend-1 for iold=num(lev-1):num(lev)-1 % words from the previous level for j=1:4 if j~=invs(tag(iold)) % avoid cancellations group{inew}=group{iold}*gens{j}; % add word to list tag(inew)=j; % tag with the last generator used inew=inew+1; end end end num(lev+1)=inew; % record end of level end % 3. Output loop if levstart==1 for j=1:4 disc(circ(j),'r'); end end for lev=max([1 levstart-1]):levend-1 for i=num(lev):num(lev+1)-1 clr=colors(mod(lev,6)+1); % get color from colors array for j=1:4 if j~=invs(tag(i)) % avoid cancellations newcirc=mobius_on_circle(group{i}, circ(j)); disc(newcirc,clr); end end end drawnow; end % End of main program segment. Supplementary functions follow. % Box 10 on p.91 function D=mobius_on_circle(T,C); if T(2,2)/T(2,1)+C.cen==0 z=inf; else z= C.cen - (C.rad*C.rad)/(T(2,2)/T(2,1)+C.cen)'; end D.cen=mobius_on_point(T,z); D.rad=abs(D.cen-mobius_on_point(T,C.cen+C.rad)); % Box 8 on p.75 function w=mobius_on_point(T,z); if z==inf if T(2,1)==0 w=inf; else w=T(1,1)/T(2,1); end else if T(2,1)*z+T(2,2)==0 w=inf; else w=(T(1,1)*z+T(1,2))/(T(2,1)*z+T(2,2)); end end % disc - Draws a disc. function disc(circ, colour, nsides) if nargin == 2 % number of arguments is only 2 nsides = 64; end nsides = round(nsides); % make sure it is an integer a = [0:pi/nsides:(2+1/nsides)*pi]; fill(circ.rad*cos(a)+real(circ.cen),circ.rad*sin(a)+imag(circ.cen),colour);