% spcg.m % This draws the limit set of special parabolic commutator groups % as described on Box 21 on p. 229. % % SYNTAX: spcg(tra,trb,sgn,fine) % % tra=tr(a), trb=tr(b) % sgn = { 0 : take the positive square root of discriminant for tr(ab) % { 1 : take the negative square root of discriminant for tr(ab) % fine = { 0 : do a coarse plot % { 1 : do a fine plot % ===================================================================== % Given tra, trb, the program computes trab to be one of the solutions % to the quadratic (depending on choice of sgn): % x^2 - tra trb x + tra^2 + trb^2 = 0 % and computes % z0 = (trab - 2) trb / (trb trab - 2tra + 2i trab) % and generator matrices a,b as follows: % a = [ tra/2 (tra trab - 2trb + 4i) / (2trab + 4) / z0 ] % [ (tra trab - 2trb - 4i)z0 / (2trab - 4) tra/2 ] % b = 1/2 [ trb - 2i trb ] % [ trb trb + 2i] % The program proceeds to plot the limit set of . % For example, you may wish to try (2,2,1,0) or (1.91+.05i,1.91+.05i,0,0) function spcg(tra,trb,sgn,fine) global epsilon epsilonmin fp gens level lvlmax oldpoint oldppoint endpt numplots numb4plot plots; switch fine case{0} disp('Coarse setting.'); eps=.01;epsm=.001;lvlm=100;numb4=100; case{1} disp('Fine setting.'); eps=.002;epsm=.0001;lvlm=100;numb4=1000; end set(0,'RecursionLimit',lvlm+100) epsilon=eps; % distance must be less that epsilon in order to plot epsilonmin=epsm; % distance must be greater than epsmin to plot lvlmax=lvlm; % maximum level to consider numb4plot=numb4; % number of points to compute before plotting level=0; plots=1; % Initialize axes axis equal; hold on; % 1. Initialize generators trab=(tra*trb+(-1)^sgn*sqrt(tra^2*trb^2-4*(tra^2+trb^2)))/2; z0=(trab-2)*trb/(trb*trab-2*tra+2i*trab); a=[tra/2 (tra*trab-2*trb+4i)/(2*trab+4)/z0; (tra*trab-2*trb-4i)*z0/(2*trab-4) tra/2] b=[trb-2i trb; trb trb+2i]/2 % generators a & b A=inv(a); B=inv(b); gens=cell(4,1); gens{1}=a;gens{2}=b;gens{3}=A;gens{4}=B; invs=[3 4 1 2]; % inverse of 1 is 3, etc. repet=cell(4,3); % See p. 218-219 for k=1:4 begpt(k)=fixpt(gens{mod4(k+1)}*gens{mod4(k+2)}*gens{mod4(k+3)}*gens{k}); endpt(k)=fixpt(gens{mod4(k-1)}*gens{mod4(k-2)}*gens{mod4(k-3)}*gens{k}); repet{k,2}=gens{k}; end % Repetends to consider repet{1,1}=b*A*B*a;repet{1,3}=B*A*b*a; repet{2,1}=A*B*a*b;repet{2,3}=a*B*A*b; repet{3,1}=B*a*b*A;repet{3,3}=b*a*B*A; repet{4,1}=a*b*A*B;repet{4,3}=A*b*a*B; for i=1:4 for j=1:3 fp(i,j)=fixpt(repet{i,j}); %Compute fixed points to be considered end end numplots=0; % 2. Explore the tree! for k=1:4 oldpoint=begpt(k); exploreTree(gens{k},k); end % End of main program segment. Supplementary functions follow. % Box 17: Recursive depth-first search (p. 152) with adaptation (p. 183) function exploreTree(X,l); global epsilon epsilonmin fp gens level lvlmax oldpoint oldppoint endpt numplots numb4plot plots; if numplots>=numb4plot*plots numplots plots=plots+1; drawnow; % updates the Matlab plot % (otherwise, Matlab only draws at the end.) end for k=l-1:l+1 tag=mod4(k); Y=X*gens{tag}; newpoint=mob(Y,endpt(tag)); dist=abs(newpoint-oldpoint); for j=1:3 z(j)=mob(Y,fp(tag,j)); end termNow=0; if dist=lvlmax %then draw! if numplots==0 oldppoint=newpoint; end if dist>=epsilonmin & level>1 drawline(oldppoint,newpoint); numplots=numplots+1; oldppoint=newpoint; end oldpoint=newpoint; else %not yet: explore further! level=level+1; exploreTree(Y,tag); %recursive call level=level-1; end end % End of function exploreTree(X,l); function drawline(point1,point2) x=linspace(real(point1),real(point2),2); y=linspace(imag(point1),imag(point2),2); line(x,y); line(-x,-y); %applies 180 degree rotation automatically function w=fixpt(T); % Note 3.3 on p.78, to determine fixed point a=T(1,1); b=T(1,2); c=T(2,1); d=T(2,2); if c==0 w=inf; %modified in Ch8 else w=(a-d+sqrt( (a+d)^2-4 ) )/(2*c); end function w=mob(T,z); %Mobius on point (Box 8 on p.75) 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 function m=mod4(n); % = {1,2,3,4} mod 4 m=mod(n-1,4)+1;