Smooth iteration count for the Mandelbrot set

The exterior of the Mandelbrot set is usually colored by using the number of iterations. As the number of iterations is a discrete quantity, this leads to the occurrence of banding in the coloring. In this article, I will derive a formula for a fractional iteration count. This is by no means novel; plenty of derivations can be found on the internet. However, I found most derivations to be fairly hard to follow, and hope that my explanation may be helpful to at least some people.
Comparison of the classical iteration count with the smooth iteration count

Mandelbrot formula

To check if a point is in the Mandelbrot set, we iterate
zk+1=zk2+cz_{k + 1} = z_k^2 + c

If limkzk=\lim_{k \rightarrow \infty} |z_k| = \infty, the set is outside the Mandelbrot set, otherwise, it is in the Mandelbrot set. In practice, we just iterate a fixed number of times, and check that zk|z_k| stays within an escape radius RR. It can be shown that when zk>2|z_k| > 2 for some kk, then limkzk=\lim_{k \rightarrow \infty} |z_k| = \infty. So, in a sense, R=2R = 2 is big enough. However, when we color the fractal based on the number of iterations, the escape radius matters, so in this article I’ll use a general escape radius RR.

I will use the following conventions: the magnitude of the iterand zkz_k is denoted by rk=zkr_k = |z_k|. The first nn such that rn>Rr_n > R for a given z0z_0 is called the iteration count for the point z0z_0.

While the iterands z0,z1,...z_0, z_1, ... (and thus, their magnitudes) depend on the starting point in a continuous way, the iteration count ‘jumps’ to discrete values. Suppose that ϵ>0\epsilon > 0 is a very small number. A starting point for which rn=R+ϵr_n = R + \epsilon will have an iteration count of nn, while a starting point with rn=Rϵr_n = R - \epsilon will have iteration count n+1n + 1. If we would have some kind of measurement for the amount by which the iterand has escaped the escape radius RR, we could use this to assign a fractional part of the iteration count. That is, the iterand with rn=R+ϵr_n = R + \epsilon would have an iteration count slightly lower than nn, while the iterand with rn=Rϵr_n = R - \epsilon would have an iteration count slightly higher than nn.

Ideally, we would like to have a smooth function f:RRf : \mathbb{R} \rightarrow \mathbb{R} such that f(k)=zkf(k) = | z_k | for kNk \in \mathbb{N}, and find the smallest xR>0x_R > 0 such that f(xR)=Rf(x_R) = R. Instead of trying to find such a function, we will try to approximate it locally.

Suppose that xRx_R is the smallest number such that f(xR)=Rf(x_R) = R. We then have zn+1=zn2+cz_{n+1} = z_n^2 + c. Assuming that cc is small with respect to RR, we get
f(xR+1)R2 f(x_R + 1) \approx R^2

Likewise, we find f(xR+2)=R4,f(xR+3)=R8f(x_R + 2) = R^4, f(x_R + 3) = R^8, or, more generally, f(n+ϵ)=R2ϵf(n + \epsilon) = R^{2^\epsilon}. Note that this is a perfectly fine approximation even when ϵ\epsilon is real. So now we can try to solve
f(xR+ϵ)=R2ϵ=rn f(x_R + \epsilon) = R^{2^\epsilon} = r_n

for ϵ\epsilon. In doing so, we find ϵ=log2(logR(rn))\epsilon = \log_2(\log_R(r_n)). Since f(n)=rnf(n) = r_n, we have n=xR+ϵn = x_R + \epsilon, so for the fractional iteration count xRx_R we find
xR=nlog2(logR(rn))x_R = n - \log_2(\log_R(r_n))

where RR is the escape radius, rn=znr_n = |z_n|, and nn is the classical iteration count (i.e. the smallest nn such that zn>R|z_n| > R).

Exercise: a) Suppose that we instead chose to approximate f(x)f(x) at x=nx = n instead of x=xRx = x_R. Show that we would have end up with:
xR=n+log2(logrn(R)) x_R = n + \log_2(\log_{r_n}(R))

b) Show that these expressions are the same. Hint: Use logb(x)=logc(x)logc(b)\log_b(x) = \frac{\log_c(x)}{\log_c(b)} and log(1x)=log(x)\log(\frac{1}{x}) = -\log(x).

c) Show that taking if we would take another base instead of RR for the inner logarithm, we would still get a smooth coloring, but if we would take another base instead of 2 for the outer logarithm, we would get a non-smooth coloring. Hint: use that log(xy)=log(x)+log(y)\log(xy) = \log(x) + \log(y).

It is not hard to see that the smooth iteration count is continuous. Imagine we are picking a starting point in a fractal colored with the discrete iteration count. Suppose the starting point has iteration count nn. If we move the starting point z0z_0 around a little bit, but no so much that the discrete iteration count changes, the smooth iteration count is a continuous function of z0z_0. We can visualize this as moving the starting point without leaving the ‘band’ that the starting point is in. When we move the starting point so much that it approaches the outer edge of its band, we see that the smooth iteration count will approach nn. Likewise, if we move the starting point near the inner edge of the of the band, the smooth iteration count will approach n+1n + 1. This means that the smooth iteration count is continous, even as the starting point crosses bands, since the smooth iteration count will assume the value nn on the border between the nnth and the n+1n + 1th band.