Kleinian and Quasi-Fuchsian Limit Sets: An Open Source Toolbox
Program Listings in Colour
Chris King
Depthfirst Matlab Listing in Colour
function outfl=depthfirst(A,B,ep,levmax,scal,sav,spec,siz,iterate,tab)
%depthfirst(2,2,0.001,1000,1,0);
%Standard option=0
%depthfirst(2,2,0.001,1000,1,0,1);
%spec=1 closing gaps
%depthfirst(1.87+0.1i,1.87-0.1i,0.001,1000,1/2.8,0,0,1100,3);
%3rd iterate
%depthfirst(1.87+0.1i,1.87-0.1i,0.001,1000,1/2.8,0,0);
%depthfirst(1.87+0.1i,1.87-0.1i,0.01,1000,1/2.8,0,1);
special words
%Example 11.1 non-free group
with relations (aba^-1b^-1)^2=I
%depthfirst(1.924781-0.047529i,2,0.005,1000,2,1,2,1100,-2,1.9248-1.4617i);
%depthfirst(1.9247306-0.0449408i,
1.91+0.2i,0.005,3000,1/6,1,2,1100,-2, 1.8569-1.2426i);
%depthfirst(2,2,0.005,1000,2,2,2,1100,-2,2.0000-1.4142i);
%or
depthfirst(2,2,0.005,1000,2,2,2,1100,-2,nonfree(2,2,0,0));
%Special words example 8.16
with aaB parabolic.
%the function specialwords can
be reprogrammed to handle examples like
%the double cusps where longer
expressions like 2/5 where aaaBaaB is parabolic
%depthfirst(2+i,3,0.005,3000,1,0,8);
% A,B are traces of the Mobius transforms generating a,b,a^-1,b^-1
% ep=epsilon in the tree search
using commutator attracting fixed pts
% levmax is the maximum depth
of the tree search (10000 if set to 0)
% scal is the scaling factor
for depicting the image
% sav=1,3 saves the file as a
png. if sav>=2 we also have a program timer
% sav=-1 test mode - exits on
completion outfl=1 or on reaching levmax outfl=0
% the timer reports tabs(1-4) as the numbers cycle through branches
% you can either produce a
black line plot or a coloured image
% iterate = -2 plot n>0
colour image by nth iterate, -1 by final level, 0 black
% spec=0 standard method
% spec=1 special words used
also on fixed pts of a,b,a^-1,b^-1
% this refines whorls with
necks and when A=2 and B=2 closes the gasket gaps
% spec=2,3 as 0,1 but for non-free
groups using automatic group table.
% If the positive grandma root
is to be chosen add 4 to spec.
% To include special words from
the subfunction specialwords() add 8 to spec
% FSA is used to remove null
words when (aba^-1b^-1)^2=I
% siz is the image size default
1100x1100
% if you add a tenth parameter
tab you can generate non-free limit sets
% tab is the trace of ab used
in the advanced grandma algorithm
% to test full exploration of
the tree uncomment 102-107, with levmax=4
%[a,b]=grandma(A,B,0);
if nargin<9
iterate=-2;
colfac=1;
end
if iterate==-2
colfac=0;
else
colfac=1;
end
% colfac=1; %Set to 0 for a
black and white image 1 for colour-coded
% iterate=1; %Which iterate to
colour code by -1 colours by the final level
ext=0; %set
to 1 to retun if image out of range (large or chaotic)
dotc=0;
outfl=true;
if nargin<8
siz=1100;
end
if nargin<7
spec=0;
end
if nargin<6
sav=0;
end
if nargin<5
scal=1;
end
ep=ep/scal;
tic;
clf;
hold on
M=256*ones(siz);
if mod(spec,8)>=4
posrt=1;
else
posrt=0;
end
if nargin<10
[a,b]=grandma(A,B,posrt,0);
else
[a,b]=grandma(A,B,posrt,2,tab);
end
gens=cell(1,4);
gens{1}=a;
gens{2}=b;
gens{3}=a^-1;
gens{4}=b^-1;
if levmax==0;
levmax=10000;
end
word=cell(1,levmax);
tags=zeros(1,levmax);
state=zeros(1,levmax);
FSA=[2 3 4
5;2 6 0 5;8 3 9 0;0 3 4 7;10 0 11 5;8 3 12 0;13 0 11 5;2 6 0 14;0 3 4 15;2 16 0
5;0 17 4 5;0 3 4 18;2 19 0 5;10 0 0 5;0 0 11 5;8 3 0 0;0 3 9 0;0 0 11 5;8 3 0
0];
%FSA=[2
3 4 5;2 3 0 5;2 3 4 0;0 3 4 5;2 0 4 5]; %table replicating std exs.
stfl=true;
oldpoint=0;
if spec<8
fix=zeros(3,4);
for i=1:4
fix(1,i)=fixp(gens{mymod(i-1)}*gens{mymod(i-2)}*gens{mymod(i-3)}*gens{mymod(i-4)});
fix(2,i)=fixp(gens{i});
fix(3,i)=fixp(gens{mymod(i+1)}*gens{mymod(i+2)}*gens{mymod(i+3)}*gens{mymod(i+4)});
end
else
[numfp,fix]=specialwords1(a,b);
points=zeros(max(numfp));
end
%spec=mod(spec,4);
%stpt=0;
lev=1;
tags(1)=1;
state(1)=1;
word{1}=gens{1};
dotfl=false;
while ~(lev==0&&tags(1)==2)
fl=false;
if spec==2||spec==3
if state(lev)==0
fl=true;
end
end
while ~fl
plt=false;
switch spec
case {1,3,5,7}
newpoint=mob_on_point(word{lev},fix(1,tags(lev))); %branch termination?
oldpoint=mob_on_point(word{lev},fix(3,tags(lev))); %branch termination?
midpoint=mob_on_point(word{lev},fix(2,tags(lev)));
if ((lev==levmax) || (abs(newpoint-midpoint)<ep && abs(oldpoint-midpoint)<ep))
plt=true;
end
case {0,2,4,6}
newpoint=mob_on_point(word{lev},fix(1,tags(lev))); %branch termination?
oldpoint=mob_on_point(word{lev},fix(3,tags(lev))); %branch termination?
if ((lev==levmax) || (abs(newpoint-oldpoint)<ep))
plt=true;
end
case 8
pts=numfp(tags(lev));
fl4=true;
pts=numfp(tags(lev));
points(1)=mob_on_point(word{lev},fix(1,tags(lev)));
for i=2:pts
points(i)=mob_on_point(word{lev},fix(i,tags(lev)));
if abs(points(i-1)-points(i))>=ep
fl4=false;
break;
end
end
if lev==levmax
fl4=true;
end
if fl4
plt=true;
newpoint=points(1);
end
end
if lev==levmax
if sav>=2
fprintf('.');
dotfl=true;
dotc=dotc+1;
if dotc>=200
dotc=0;
fprintf('\n');
end
end
if sav==-1
outfl=false;
return;
end
end
if spec<8
x=scal*abs(newpoint);
if ext && x>50 %breakout to portray chaotic limit sets
fprintf('Exiting...\n');
colormap(colorcube);
image(255*M');
return
end
end
if spec<8 && x>1.6
&& plt==true %too far offscreen, so break
fl=true;
break;
end
if iterate>0
tagpos=tags(iterate);
end
if iterate==-1
tagpos=tags(lev);
end
if iterate==0 || iterate==-2
tagpos=0;
end
if plt
switch spec
case {1,3,5,7}
if A==2 && B==2
M=myplot(scal,M,oldpoint,midpoint,siz,tagpos,spec);
M=myplot(scal,M,midpoint,newpoint,siz,tagpos,spec);
else
M=myplot(scal,M,oldpoint,newpoint,siz,tagpos,spec);
end
case {0,2,4,6}
M=myplot(scal,M,oldpoint,newpoint,siz,tagpos,spec);
case 8
for i=2:pts
M=myplot(scal,M,points(i-1),points(i),siz,tagpos,spec);
end
end
if ~stfl
if spec==2 || spec==3 || spec==6 ||
spec==7
if abs(oldpoint-stpoint)<10*ep
M=myplot(scal,M,oldpoint,stpoint,siz,tagpos,spec);
end
end
end
stpoint=newpoint;
fl=true;
else
fl=false;
end
if fl
if stfl
%stpoint=oldpoint;
stfl=false;
end
break;
else
lev=lev+1; %go forward
tags(lev)=mymod(tags(lev-1)+1);
if lev==1
word{lev}=gens{tags(lev)};
if spec==2 || spec==3 || spec==6 ||
spec==7
state(lev)=tags(lev);
end
else
word{lev}=word{lev-1}*gens{tags(lev)};
if spec==2 || spec==3 || spec==6 ||
spec==7
state(lev)=FSA(state(lev-1),tags(lev));
if state(lev)==0
fl=true;
end
end
end
end
end
fl=true;
while fl
lev=lev-1; %go backward
if lev==0 || tags(lev+1)-1~=mod(tags(lev)+2,4) %available turn
fl=false;
end
end
if (lev==0 && tags(1)==2)
% M=myplot(scal,M,stpt,oldpoint,siz,colfac*tags(iterate),spec);
if dotfl
fprintf('\n');
dotfl=false;
end
if sav>=2
fprintf('%d %d %d %d
%4.4f\n', tags(1),tags(2),tags(3),tags(4),toc);
end
toc;
break; %Finished -
exit routine
end
lev=lev+1;
tags(lev)=mymod(tags(lev)-1); %turn and go forward
if sav>=2
if lev<4 %progress clock for long iterations
if dotfl
fprintf('\n');
dotfl=false;
end
fprintf('%d %d %d %d
%4.4f\n', tags(1),tags(2),tags(3),tags(4),toc);
end
end
if lev==1
word{1}=gens{tags(1)};
%state(1)=tags(1);
else
word{lev}=word{lev-1}*gens{tags(lev)};
if spec==2 || spec==3 || spec==6 ||
spec==7
state(lev)=FSA(state(lev-1),tags(lev));
% if state(lev)==0
% fl=true;
% end
end
end
end
s=size(M); % Plot the matrix and save a png file
tit=[num2str(A),', ',num2str(B),', ',num2str(ep),', ',num2str(levmax)];
if spec==2 ||
spec==3 || spec==6 || spec==7
tit=[tit,', ',num2str(tab)];
end
z=zeros(1,s(1)*s(2));
k=1;
sc11=11/10;
if ~colfac
for i=1:s(1)
for j=1:s(2)
if M(i,j)<255
z(k)=((i-s(1)/2)*2/s(1)+1i*(j-s(2)/2)*2/s(2))*sc11;
k=k+1;
end
end
end
plot(z(1:k-1),'.','MarkerSize',1,'Color','k');
axis([-sc11
sc11 -sc11 sc11]);
text(-1,1.05,tit);
else
image(M');
colormap(colorcube(256));
sz=size(M');
axis([0
s(2) 0 s(1)]);
end
if mod(sav,2)
% if colfac==0
% imwrite(255*M',[tit,'.png']);
% else
imwrite(M',colorcube(256),[tit,'.png']);
% end
%save([tit2,'.mat'],'M');
end
function n=mymod(m)
n=mod(m,4);
if n==0
n=4;
end
function M=myplot(sc,M,o,n,siz,c,spec) %Plots a
scaled image in M
siz=siz/2;
sizs=10/11*siz;
fl=true;
big=10/sc;
if (abs(o))>big
|| abs(n)>big %added to avoid plotting line
offscreen
fl=false;
end
switch c
case 0
co=241; %black
case 4
co=186; %magenta
case 1
co=233; %blue
case 2
co=208; %red
case 3
co=165; %cyan
end
% if spec==2 &&
abs(n-o)>0.1/sc %added to remove four extraneous lines
% fl=false;
% end
if fl
if abs(imag(n-o))>abs(real(n-o))
stps=max(ceil(abs(sc*imag(n-o)*siz)),2);
zs=linspace(sc*o,sc*n,stps);
else
stps=max(ceil(abs(sc*real(n-o)*siz)),2);
zs=linspace(sc*o,sc*n,stps);
end
for i=1:length(zs)
if ~isnan(zs(i))
if max(abs(real(zs(i))),abs(imag(zs(i))))<1
M(siz-floor(sizs*real(zs(i))),siz-floor(sizs*imag(zs(i))))=co;
end
end
end
end
function zo=mob_on_point(T,z) %Mobius
transforms a point
%D=struct();
a=T(1,1);
b=T(1,2);
c=T(2,1);
d=T(2,2);
zo=(a*z+b)/(c*z+d);
function z=fixp(T) %Finds an attracting fixed point of a transformation
a=T(1,1);
b=T(1,2);
c=T(2,1);
d=T(2,2);
T2=T^2;
tr=T(1,1)+T(2,2);
tr2=T2(1,1)+T2(2,2);
k=((tr+sqrt(tr2-4))/2)^2;
if abs(k)>1
z=(-(d-a)+((d-a)^2+4*b*c))^(1/2)/(2*c);
else
z=(-(d-a)-((d-a)^2+4*b*c))^(1/2)/(2*c);
end
function [a,b]=grandma(ta,tb,posroot,opt,tab)
if nargin<5
opt=mod(opt,2);
end
if nargin<4
opt=0;
end
if nargin<3
posroot=false;
end
if opt<2 %Calculate the trace Tab from the grandfather identity
p=-ta*tb;
q=ta^2+tb^2;
if posroot
tab=(-p+(p^2-4*q)^0.5)/2;
else
tab=(-p-(p^2-4*q)^0.5)/2;
end
z0=((tab-2)*tb)/(tb*tab-2*ta+2*1i*tab);
if opt==0 %Grandma's original recipe
ab=[tab/2
(tab-2)/(2*z0);(tab+2)*z0/2 tab/2];
b=[(tb-2*1i)/2 tb/2;tb/2 (tb+2*1i)/2];
a=ab*b^-1;
end
if opt==1 %Jorgensen's recipe
a=[ta-tb/tab
ta/tab/tab;ta tb/tab];
b=[tb-ta/tab
-tb/tab/tab;-tb ta/tab];
end
else
tC=ta^2+tb^2+tab^2-ta*tb*tab-2; %Grandma's
three parameter double alarm
Q=sqrt(2-tC);
if abs(tC+1i*Q*sqrt(tC+2))>=2+1e-15 %e-15 added to avoid Ta = Tb =2 error
R=sqrt(tC+2);
else
R=-sqrt(tC+2);
end
%R=-R;
zo=(tab-2)*(tb-R)/(tb*tab-2*ta+1i*Q*tab);
a=[ta/2
(ta*tab-2*tb+2i*Q)/((2*tab+4)*zo);(ta*tab-2*tb-2i*Q)*zo/(2*tab-4) ta/2];
b=[(tb-1i*Q)/2
(tb*tab-2*ta-1i*Q*tab)/((2*tab+4)*zo);(tb*tab-2*ta+1i*Q*tab)*zo/(2*tab-4)
(tb+1i*Q)/2];
end
function [numfp, fix]=specialwords1(a,b)
A=a^-1;
B=b^-1;
numfp=zeros(1,4);
for i=1:4
switch i
case {1,3}
numfp(i)=4;
case{2,4}
numfp(i)=3;
end
end
fix=zeros(4,4);
fix(1,1)=fixp(b*A*B*a);
fix(2,1)=fixp(a*B*a);
fix(3,1)=fixp(B*a*a);
fix(4,1)=fixp(B*A*b*a);
fix(1,2)=fixp(A*B*a*b);
fix(2,2)=fixp(A*A*b);
fix(3,2)=fixp(a*B*A*b);
fix(1,3)=fixp(B*a*b*A);
fix(2,3)=fixp(A*b*A);
fix(3,3)=fixp(b*A*A);
fix(4,3)=fixp(b*a*B*A);
fix(1,4)=fixp(a*b*A*B);
fix(2,4)=fixp(a*a*B);
fix(3,4)=fixp(A*b*a*B);
Tracepq Program Listing in Colour
function [e,tt]=tracepq(p,q,opt,prt)
%opt=0 f==2 root 1 f==-2 2 non
free f==2 3 non free f==-2
syms t
g=gcd(p,q);
p=p/g;
q=q/g;
s=fareyseq(p,q);
t0=t;
if opt<2
t1=t+2i;
else
t1=t+sqrt(2)*1i;
end
t2=2;
for i=1:length(s)
if s(i)==0
h=expand(t1*t0-t2);
t2=t1;
t1=h;
else
h=expand(t1*t2-t0);
t0=t1;
t1=h;
end
%fprintf('.');
end
%fprintf('\n');
c=expand(t1); %Expand it into polynomial form
f=symfun(c,t); %Make it into a function we can solve
if mod(opt,2)==0
e=eval(vpasolve(f==2,t)); %Solve it for f=2
else
e=eval(vpasolve(f==-2,t));
end
q=q/gcd(p,q);
tt=zeros(length(e),3);
for i=1:q
tt(i,1)=i;
tt(i,2)=real(e(i));
tt(i,3)=imag(e(i));
end
tt=sortrows(tt,2);
if prt
for i=1:q
if tt(i,3)>=0
fprintf('%d\t%4.8f+%4.8fi\n',tt(i,1),tt(i,2),tt(i,3));
else
fprintf('%d\t%4.8f%4.8fi\n',tt(i,1),tt(i,2),tt(i,3));
end
end
end
function s=fareyseq(p,q)
p=p/gcd(p,q);
q=q/gcd(p,q);
s=[];
p0=0;
q0=1;
p1=1;
q1=0;
ph=p0+p1;
qh=q0+q1;
while p~=ph || q~=qh
if ph/qh>p/q
p1=ph;
q1=qh;
ph=ph+p0;
qh=qh+q0;
s=[s
0];
else
p0=ph;
q0=qh;
ph=ph+p1;
qh=qh+q1;
s=[s
1];
end
end
Depth First C-script Listing in Colour
//To run this file
from terminal put it in a folder, cd to the folder and input
//gcc -o depthf
depthfirst.c -lm && ./depthf
//To run successive
compiled versions type ./depthf
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <time.h>
typedef double _Complex arry[2][2];
void mult(arry a,arry b, arry c);
void inv(arry a, arry c);
double _Complex fixp(arry T);
time_t start,end;
int main(void)
{
FILE *mf;
const char base[] = "DF";
char filename [100];
//double _Complex ta=1.9264340533-0.0273817919*I,tb=2;
//double _Complex ta=1.80785524+0.136998688*I, tb=2;
//double _Complex ta = 1.924781-0.047529*I, tb=2, tab; //= 1.9248-1.4617*I //spec=2
//double _Complex ta = 2, tb=2; //=2.0000-1.41421356*I; //spec=2
//double _Complex ta = 1.87+0.1*I, tb = 1.87-0.1*I;
//double _Complex ta = 1.61891069-0.80846358*I,
tb=1.66692448-0.40921981*I;
double _Complex ta=1.95824516-0.01663690*I, tb=2;//spec=2
//double _Complex ta = 1.5-0.8660254038*I,
tb=1.5+0.8660254038*I;
int spec=2,
altroot=0; //spec=2 non-free
group altroot sets which sqare root for tab
int neck=1,iterate=0; //to aid drawing large whorls with narrow necks
usinf midpoint
const int levmax=1000,siz=1100;
double ep=0.001,scal=2;
double _Complex tab;
int M[siz][siz],siz2,sizs;
double _Complex gens[2][2][4];
double _Complex word[3][3][levmax+1];
int tags[levmax+1];
int state[levmax+1];
double dif;
int FSA[19][4]={{1,2,3,4},{1,5,-1,4},{7,2,8,-1},{-1,2,3,6},{9,-1,10,4},{7,2,11,-1},{12,-1,10,4},{1,5,-1,13},{-1,2,3,14},{1,15,-1,4},{-1,16,3,4},{-1,2,3,17},{1,18,-1,4},{9,-1,-1,4},{-1,-1,10,4},{7,2,-1,-1},{-1,2,8,-1},{-1,-1,10,4},{7,2,-1,-1}};
double _Complex fix[3][4];
int i,j,co;
double _Complex p,q,z0,z,Q,tC,R,zo;
arry a,b,ab,A,B,h;
arry *iv, *mu,h1,h2,h3;
int stfl,lev,fl,plt,stps;
double _Complex oldpoint,stpt,newpoint,midpoint;
double x;
sprintf(filename, "%s %e %e %e %e %d %e %e.txt",base,creal(ta),cimag(ta),creal(tb),cimag(tb),levmax,ep,scal);
mf=fopen(filename,"w");
time (&start);
ep=ep/scal;
for (i=0;i<siz;i++)
for (j=0;j<siz;j++)
M[i][j]=255;
siz2=siz/2;
sizs=(int)siz2*10.0/11;
//grandma's recipe
if (spec==0)
{
p=-ta*tb;
q=ta*ta+tb*tb;
if (altroot==0)
tab=(-p-csqrt(p*p-4*q))/2;
else
tab=(-p+csqrt(p*p-4*q))/2;
//tab=(-p-csqrt(p*p-4*q))/2;
z0=((tab-2)*tb)/(tb*tab-2*ta+2*I*tab);
ab[0][0]=tab/2;
ab[0][1]=(tab-2)/(2*z0);
ab[1][0]=(tab+2)*z0/2;
ab[1][1]=tab/2;
b[0][0]=(tb-2*I)/2;
b[0][1]=tb/2;
b[1][0]=tb/2;
b[1][1]=(tb+2*I)/2;
}
else
{
p=-ta*tb;
q=ta*ta+tb*tb-2;
if (altroot==0)
tab=(-p-csqrt(p*p-4*q))/2;
else
tab=(-p+csqrt(p*p-4*q))/2;
tC=ta*ta+tb*tb+tab*tab-ta*tb*tab-2; //Grandma's three parameter double alarm
Q=csqrt(2-tC);
if ((cabs(tC+I*Q*csqrt(tC+2))>=2+1e-15))
R=csqrt(tC+2);
else
R=-csqrt(tC+2);
zo=(tab-2)*(tb-R)/(tb*tab-2*ta+1i*Q*tab);
a[0][0]=ta/2;
a[0][1]=(ta*tab-2*tb+2*I*Q)/((2*tab+4)*zo);
a[1][0]=(ta*tab-2*tb-2*I*Q)*zo/(2*tab-4);
a[1][1]=ta/2;
b[0][0]=(tb-I*Q)/2;
b[0][1]=(tb*tab-2*ta-I*Q*tab)/((2*tab+4)*zo);
b[1][0]=(tb*tab-2*ta+I*Q*tab)*zo/(2*tab-4);
b[1][1]=(tb+I*Q)/2;
}
inv(b,B);
if (spec==0)
mult(ab,B,a);
inv(a,A);
for (i=0;i<2;i++) for (j=0;j<2;j++) gens[i][j][0]=a[i][j];
for (i=0;i<2;i++) for (j=0;j<2;j++) gens[i][j][1]=b[i][j];
for (i=0;i<2;i++) for (j=0;j<2;j++) gens[i][j][2]=A[i][j];
for (i=0;i<2;i++) for (j=0;j<2;j++) gens[i][j][3]=B[i][j];
mult(b,a,h1); mult(A,h1,h2);
mult(B,h2,h3); fix[0][0]=fixp(h3);
mult(A,b,h1); mult(B,h1,h2);
mult(a,h2,h3); fix[0][1]=fixp(h3);
mult(B,A,h1); mult(a,h1,h2);
mult(b,h2,h3); fix[0][2]=fixp(h3);
mult(a,B,h1); mult(b,h1,h2);
mult(A,h2,h3); fix[0][3]=fixp(h3);
fix[1][0]=fixp(a);
fix[1][1]=fixp(b); fix[1][2]=fixp(A);
fix[1][3]=fixp(B);
mult(B,a,h1); mult(A,h1,h2);
mult(b,h2,h3); fix[2][0]=fixp(h3);
mult(a,b,h1); mult(B,h1,h2);
mult(A,h2,h3); fix[2][1]=fixp(h3);
mult(b,A,h1); mult(a,h1,h2);
mult(B,h2,h3); fix[2][2]=fixp(h3);
mult(A,B,h1); mult(b,h1,h2);
mult(a,h2,h3); fix[2][3]=fixp(h3);
lev=0;
tags[0]=0;
state[0]=0;
for (i=0;i<2;i++) for (j=0;j<2;j++) word[i][j][0]=gens[i][j][0];
while (~((lev==-1)&&(tags[0]==1)))
{
fl=0;
if (spec==2)
if (state[lev]==-1)
fl=1;
while (fl==0)
{
z=fix[0][tags[lev]];
newpoint=(word[0][0][lev]*z+word[0][1][lev])/(word[1][0][lev]*z+word[1][1][lev]);
z=fix[2][tags[lev]];
oldpoint=(word[0][0][lev]*z+word[0][1][lev])/(word[1][0][lev]*z+word[1][1][lev]);
if (neck>0)
{
z=fix[1][tags[lev]];
midpoint=(word[0][0][lev]*z+word[0][1][lev])/(word[1][0][lev]*z+word[1][1][lev]);
}
plt=0;
x=scal*cabs(newpoint);
if (x>10) //Chaotic
instability
{
printf("exiting...\n");
return(0);
}
if (neck>0)
{
if ((lev==levmax) ||
((cabs(newpoint-midpoint)<ep)&&(cabs(midpoint-oldpoint)<ep)))
{
if (x>1.5) //Limit
set off screen
{
fl=1;
break;
}
plt=1;
}
}
else
{
if ((lev==levmax) || (cabs(newpoint-oldpoint)<ep))
{
if (x>1.5) //Limit
set off screen
{
fl=1;
break;
}
plt=1;
}
}
if (plt==1)
{
fl=1;
z=newpoint-oldpoint;
if (fabs(cimag(z))>fabs(creal(z)))
{
stps=1;
x=ceil(fabs(scal*cimag(z)*siz2));
if (x>1) stps=x;
}
else
{
stps=1;
x=ceil(fabs(scal*creal(z)*siz2));
if (x>1) stps=x;
}
for (j=0;j<=stps;j++)
{
z=scal*(newpoint*j/stps+oldpoint*(stps-j)/stps);
if ((fabs(creal(z))<1.0) && (fabs(cimag(z))<1.0))
{
if (iterate==0)
M[(int)(siz2-floor(sizs*creal(z)))][(int)(siz2-floor(sizs*cimag(z)))]=241;
if (iterate>0)
{
if (tags[iterate-1]==0) co=233; //blue
if (tags[iterate-1]==1) co=208; //red
if (tags[iterate-1]==2) co=165; //cyan
if (tags[iterate-1]==3) co=186; //magenta
M[(int)(siz2-floor(sizs*creal(z)))][(int)(siz2-floor(sizs*cimag(z)))]=co;
}
if (iterate==-1)
{
if (tags[lev]==0) co=233; //blue
if (tags[lev]==1) co=208; //red
if (tags[lev]==2) co=165; //cyan
if (tags[lev]==3) co=186; //magenta
M[(int)(siz2-floor(sizs*creal(z)))][(int)(siz2-floor(sizs*cimag(z)))]=co;
}
}
}
}
else
fl=0;
if (fl==1)
{
}
else
{
lev=lev+1; //go
forward
tags[lev]=(tags[lev-1]+1)%4;
if (lev==0)
{
for (i=0;i<2;i++) for (j=0;j<2;j++)
word[i][j][lev]=gens[i][j][tags[lev]];
if (spec==2) state[lev]=tags[lev];
}
else
{
for (i=0;i<2;i++) for (j=0;j<2;j++)
{
h1[i][j]=word[i][j][lev-1];
h2[i][j]=gens[i][j][tags[lev]];
}
mult(h1,h2,h3);
for (i=0;i<2;i++) for (j=0;j<2;j++)
word[i][j][lev]=h3[i][j];
if (spec==2)
{
state[lev]=FSA[state[lev-1]][tags[lev]];
if (state[lev]==-1) fl=1;
}
}
}
}
fl=1;
while (fl==1)
{
lev=lev-1; //go
backward
if ((lev==-1) || ((tags[lev+1]+3)%4 !=
((tags[lev]+2)%4))) //available
turn
{
fl=0;
}
}
if ((lev==-1)&&(tags[0]==1))
{
printf("%d %d %d %d\n", tags[0]+1,tags[1]+1,tags[2]+1,tags[3]+1);
time (&end);
dif=difftime (end,start);
printf("Elasped time is %.0lf
seconds.\n", dif );
break; //finished!!
}
lev=lev+1;
if (tags[lev]>0)
tags[lev]=(tags[lev]-1)%4; //turnandgoforward
else
tags[lev]=(tags[lev]+3)%4;
if (lev<3) //progress clock for long iterations
{
time (&end);
dif=difftime (end,start);
printf("%d %d %d %d ", tags[0]+1,tags[1]+1,tags[2]+1,tags[3]+1);
printf("%.1lf sec\n", dif );
}
if (lev==0)
{
for (i=0;i<2;i++) for (j=0;j<2;j++)
{
word[i][j][lev]=gens[i][j][tags[lev]];
//state[0]=tags[0];
}
}
else
{
for (i=0;i<2;i++) for (j=0;j<2;j++)
{
h1[i][j]=word[i][j][lev-1];
h2[i][j]=gens[i][j][tags[lev]];
}
mult(h1,h2,h3);
for (i=0;i<2;i++) for (j=0;j<2;j++)
word[i][j][lev]=h3[i][j];
if (spec==2)
{
state[lev]=FSA[state[lev-1]][tags[lev]];
lev=lev+1-1;
// if (state[lev]==-1 fl=1;
}
}
}
for(i=0;i<siz;i++)
for(j=0;j<siz;j++)
fprintf(mf,"%d ",M[i][j]);
fclose(mf);
return(0);
}
double _Complex fixp(arry T)
{
double _Complex z,tr,tr2,a,b,c,d;
double _Complex k;
a=T[0][0];
b=T[0][1];
c=T[1][0];
d=T[1][1];
tr=a+d;
tr2=a*a+2*b*c+d*d;
k=((tr+csqrt(tr2-4))/2)*((tr+csqrt(tr2-4))/2);
if (cabs(k)>1)
z=(-(d-a)+csqrt((d-a)*(d-a)+4*b*c))/(2*c);
else
z=(-(d-a)-csqrt((d-a)*(d-a)+4*b*c))/(2*c);
return(z);
}
void mult(arry a,arry b,arry c)
{
int i,j;
for (i=0;i<2;i++)
for (j=0;j<2;j++)
c[i][j]=a[i][0]*b[0][j]+a[i][1]*b[1][j];
}
void inv(arry a, arry c)
{
double _Complex d;
d=a[0][0]*a[1][1]-a[0][1]*a[1][0];
c[0][0]=a[1][1]/d;
c[0][1]=-a[0][1]/d;
c[1][0]=-a[1][0]/d;
c[1][1]=a[0][0]/d;
}
//To run this file
from terminal put it in a folder, cd to the folder and input
//gcc -o tracepqr
tracepqr.c -lm && ./tracepqr
//To run successive
compiled versions type ./depthf
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <time.h>
double _Complex fracfunct(int *s,int sl,int opt,double _Complex val);
int main(void)
{
//double _Complex val=2;
//int p=3,q=5,opt=0;
double _Complex val=1.61691788-1.29437374i;
int p=1597,q=2584,opt=0;
double ep=1e-8;
int g,hld,h1,h2,p0,q0,p1,q1,ph,qh,its,i;
int s[200],sl=0;
double _Complex vh,h,f,df;
h1=p; //Find gcd(p,q)
h2=q;
while (h2%h1>0)
{
hld=h2%h1;
h2=h1;
h1=hld;
}
g=h1;
p=p/g;
q=q/g;
p0=0; // Generate Farey sequence for p/q
q0=1;
p1=1;
q1=0;
ph=p0+p1;
qh=q0+q1;
while ((p!=ph) || (q!=qh))
if (ph*q>p*qh)
{
p1=ph;
q1=qh;
ph=ph+p0;
qh=qh+q0;
s[sl]=0;
sl=sl+1;
}
else
{
p0=ph;
q0=qh;
ph=ph+p1;
qh=qh+q1;
s[sl]=1;
sl=sl+1;
}
h=(1+I)*1e-7;
its=500;
for (i=0;i<its;i++) //Newton's iteration loop
{
vh=val;
f=fracfunct(s,sl,opt,val)-2;
df=(fracfunct(s,sl,opt,val+h)-fracfunct(s,sl,opt,val-h))/2/h;
val=val-f/df;
if (cabs(vh-val)<ep)
{
printf("OK
%d %4.12f %4.12f %4.12f\n",i,cabs(vh-val),creal(val),cimag(val));
break;
}
}
if (i==its)
printf("Bad:%d %4.12f %4.12f\n",i,creal(val),cimag(val));
}
double _Complex fracfunct(int *s, int sl,int opt,double _Complex val)
{
double _Complex t0,t1,t2,h;
int i;
t0=val;
if (opt<2)
t1=val+2i;
else
t1=val+sqrt(2)*1i;
t2=2;
for (i=0;i<sl;i++)
{
if (s[i]==0)
{
h=t1*t0-t2;
t2=t1;
t1=h;
}
else
{
h=t1*t2-t0;
t0=t1;
t1=h;
}
}
return(t1);
}