And I decided to run the graphing procedure using the 811-node approximation with A = 24. It took a very long time (3 hours I think) to generate the graph due to the arbitrary precision math. I suppose it could have been accelerated by computing fewer points and using an interpolation technique instead of computing every pixel however my graphing code was crude and I just wanted to see what it would do. The results are attached to this post. It's 512x512 pixels and runs from -10.01 + 10.01i (upper left) to 10.01 - 10.01i (lower right).
The graph is a magnitude/phase color graph where the magnitude is represented by the intensity of the color and the phase angle by the hue. The grey areas represent where the iteration \( \mathrm{tet}(z+1) = \exp(\mathrm{tet}(z)) \) exceeded the safety limit required to prevent overflows. The value of the function may be huge or small in that area but the computer could not graph it there due to arithmetical limits.
The graph is very intriguing. It's like the Julia set of the exponential map grows there. I guess the structure gets ever more convoluted and fractal-like the further one goes toward the right. What's up with that? This behavior is really neat yet it's not like the usual special functions I've seen.
The graphing code is here. It outputs a PPM (portable pixelmap) file. Note that I had to change the routine Tetrate, in order to implement the safety bound to prevent the overflow:
Code:
/* Do general tetration */
Tetrate(v, A, bias, z) = {
local(tval);
if(real(z) < -0.5, tval = Tetrate(v, A, bias, z+1));
if(real(z) > 0.5, tval = Tetrate(v, A, bias, z-1));
if(tval == "err", return("err"));
if(abs(tval) > 1e+8, return("err")); /* safety "bailout" */
if(abs(real(tval)) < 1e-1000, tval = imag(tval));
if(abs(imag(tval)) < 1e-1000, tval = real(tval));
if(abs(tval) < 1e-10000, tval = 0);
if(real(z) < -0.5, return(log(tval)));
if(real(z) > 0.5, return(exp(tval)));
tval = PointEvaluate(v, A, z + bias);
if(imag(z) == 0, tval = real(tval)); /* clean up */
return(tval);
}
/* Color conversion (HSB to RGB). */
HSB2RGB(hsb) = {
local(H=hsb[1]);
local(S=hsb[2]);
local(B=hsb[3]);
local(HH=0);
local(F=0);
local(P=0);
local(Q=0);
local(T=0);
HH = floor(6*H)%6;
F = (6*H) - floor(6*H);
P = B*(1 - S);
Q = B*(1 - (F*S));
T = B*(1 - (1-F)*S);
if(B > 1.0, B = 1.0);
if(B < 0.0, B = 0.0);
if(P > 1.0, P = 1.0);
if(P < 0.0, P = 0.0);
if(Q > 1.0, Q = 1.0);
if(Q < 0.0, Q = 0.0);
if(T > 1.0, T = 1.0);
if(T < 0.0, T = 0.0);
if(HH == 0, return([B, T, P]));
if(HH == 1, return([Q, B, P]));
if(HH == 2, return([P, B, T]));
if(HH == 3, return([P, Q, B]));
if(HH == 4, return([T, P, B]));
if(HH == 5, return([B, P, Q]));
}
/* Safe argument. */
safetyarg(z) = if(z == 0, 0, arg(z));
/* Initialize */
v = MakeApprox(811, 24.0);
for(i=1,32,v=OneIterationNrml(v, 24.0));
for(i=1,6,v=OneIteration(v, 24.0));
bias = FindBias(v, 24.0);
/* Make graph. */
width = 128*4;
height = 128*4;
x0 = -10.01;
y0 = 10.01;
x1 = 10.01;
y1 = -10.01;
xstep = (x1 - x0)/width;
ystep = (y1 - y0)/height;
write("tetrationgraphcauchy.ppm", "P3");
write("tetrationgraphcauchy.ppm", "# tetrationgraphcauchy.ppm");
write("tetrationgraphcauchy.ppm", width, " ", height);
write("tetrationgraphcauchy.ppm", "255");
for(y=0, height-1,\
for(x=0, width-1,\
xx = x0+(xstep*x);\
yy = y0+(ystep*y);\
z = xx+yy*I;\
funcvalue = Tetrate(v, 24.0, bias, z);\
if(funcvalue != "err",\
if(abs(funcvalue) < 1e-10000, funcvalue = 0);\
mag = abs(funcvalue);\
phase = safetyarg(funcvalue);\
H = phase/(2*Pi);\
S = 1/(1 + 0.3*log(mag + 1));\
B = 1 - 1/(1.1 + 5*log(mag + 1));\
RGB = HSB2RGB([H, S, B]);\
Red = floor(RGB[1]*255.0);\
Green = floor(RGB[2]*255.0);\
Blue = floor(RGB[3]*255.0);,\
Red = 128;\
Green = 128;\
Blue = 128;\
);\
write1("tetrationgraphcauchy.ppm", Red, " ", Green, " ", Blue, " ");\
);\
write("tetrationgraphcauchy.ppm", "");\
);