A complex coloring book

Julia Barnes from WCU will be speaking next week on ways to visualize complex functions - sounds like it’s not to miss! - particularly for folks in complex variables. I suspect she’ll mention her very fun book A Coloring Book of Complex Function Representations. It’s got a number of images that look like this one that are, evidently, great for coloring. As stated, that image is a contour plot of Re((f^3)(z)) where

f[z_] = (z^3)+((-0.2+0.11I)/(z^3));

Here’s how to generate such an image, though this does take a little while:

pic = ContourPlot[Re[f@f@f[x+I*y]],{x,-1.3,1.3},{y,-1.3,1.3},
ContourShading->False, Contours->{-2,0,2}, ContourStyle->Thick,
MaxRecursion->4, ImageSize->1600,PlotRangePadding->None, FrameTicks->None,
FrameStyle->Thickness[0.005]];
Rasterize[pic, RasterSize->1600, ImageSize->800]

Let’s try to get a grip on what’s going on in this picture. 

First off, note that Re(f(x+i y)) is a real valued function of two real variables so we can visualize it using techniques learned in Calculus III. For example, we could generate a contour plot:

ContourPlot[Re[f[x+I*y]],{x,-1.3,1.3},{y,-1.3,1.3},
ContourShading->False, Contours->{-2,0,2}, 
MaxRecursion->3, ImageSize->600]

We can also see how these fit on a 3D surface:

Plot3D[Re[f[x+I*y]],{x,-1.3,1.3},{y,-1.3,1.3},
Mesh->{{-2,0,2}}, MaxRecursion->4, MeshFunctions -> {#3&},
 ClippingStyle->None, PlotRange->{-10,10}, PlotPoints -> 50,
ImageSize->600, MeshStyle->Thick]

Again, these plots display just the real part of the function. It’d be nice to see how that fits into the whole complex picture. We can do so using domain coloring:

domainColoring[expr_,{z_,min_,max_}, opts___] := Module[{cF},
cF = Function[expr /. z->#];
DensityPlot[Arg[cF[x+I*y]], {x,Re[min],Re[max]},{y,Im[min],Im[max]},
MeshFunctions->{Arg[cF[#1+I*#2]]&,Abs[cF[#1+I*#2]]&},
MeshStyle -> {Directive[Opacity[0.4], Thickness[0.001]]},
opts, Mesh -> True, ColorFunction -> Hue, AspectRatio->Automatic, PlotPoints -> 101]
];
Row[{
domainColoring[f[z],{z,-1.3-1.3I,1.3+1.3I}, ImageSize -> 500],
domainColoring[z,{z,-1.3-1.3I,1.3+1.3I}, ImageSize -> 500]
}]

This indicates clearly that there are six points that map to zero. Since Re(0)=0, the curves that extend out from the origin in the image are exactly the contours Re(f(x+i y))=0 and must pass through those points. Zero itself appears to be a pole. We can understand those facts by examining the rational form of f:

Together[f[z]]

So I guess those six pre-images of zero are exactly the sixth roots of -0.2+0.11 i.

Now, what’s with this (f^3) business? Well, (f^n)stands for the (n^th) iterate of f. Thus, (f^2)=f∘f, (f^3)=f∘f∘f, and more generally (f^n)=f∘f∘f∘⋯∘f with n occurrences of f. 

As a next step, let’s think about what (f^2) might look like. In the following code, f@f is Mathematica input for composition.

Rasterize[ContourPlot[Re[f@f[x+I*y]],{x,-1.3,1.3},{y,-1.3,1.3},
ContourShading->False, Contours->{-2,0,2}, 
MaxRecursion->4, ImageSize->600], RasterSize->1200]

The 6 six leafed flowers we see surrounding the big flower are place at the roots of f. If (Subscript[z, r]) denotes any one of those points, then f((Subscript[z, r]))=0, so f(f((Subscript[z, r])))=f(0)=∞. Thus, those points are poles of (f^2) that look like the poles of f which is how they occur. When we take it to (f^3), we find that there are six points that map to each of those six points which is how even more flowers appear.

You know, as long as we’re supposed to color this thing anyway, why wait for the kids to do it?

d = ImageData[pic] /. {{0.`,0.`,0.`,0.0`} -> 0, {0.0,0.0,0.0,_?(#>0&)} :>1};
pic2 = ArrayPlot[d, Frame->False];
m = MorphologicalComponents[pic2,0.5];
Colorize[m, ImageSize->800]