The complete illustrated project description is available on the Mandelbrot GitHub Pages website.
The conventional Mandelbrot escape-time algorithm assigns an integer iteration count to every point in the complex plane. Visual representations of the set then assign a color to each point based upon iteration count.
For a point
starting with
we iterate as follows:
- If
$\lvert z_n \rvert \to \infty$ , then$c$ is outside the Mandelbrot set. - If
$\{z_n\}_{n=0}^{\infty}$ is bounded, then$c$ is inside the Mandelbrot set.
If the magnitude of
A straightforward renderer assigns a color according to the integer
In practice:
- If
$\lvert z_n \rvert > 2$ , then the orbit definitely escapes. Therefore,$c$ is outside the set and we stop iterating. - If the maximum iteration count is reached while
$\lvert z_n \rvert \le 2$ , escape has not been demonstrated. For rendering purposes,$c$ is provisionally treated as belonging to the set and, as is common practice, colored black.
The maximum number of iterations is typically on the order of 1000 to 5000. A larger maximum reduces the number of exterior points that are provisionally misclassified as interior. Visually, the edge of the set becomes more sharply defined as the maximum iteration count increases.
Starting with
we have
Writing
gives
So
and
The absolute value of
We can forego the square-root operation and compare against 4 rather than 2:
- If
$u_n^2 + v_n^2 > 4$ , then the orbit will become unbounded. Therefore,$c$ is outside the set, we stop iterating, and we assign a color based on$n$ . - If the maximum iteration count is reached with
$u_n^2 + v_n^2 \le 4$ , escape has not been demonstrated. For rendering purposes,$c$ is provisionally treated as belonging to the set and, as is common practice, colored black.
At this point, the result can be disappointing because the color distribution does not look as smooth as many Mandelbrot images plotted elsewhere. Typically, the color changes are bunched near the edge of the black set while large areas exhibit visible color bands. Compressing or stretching the palette, or selecting different colors, may alter the appearance but cannot eliminate the fundamental banding caused by using only an integer escape count.
Smooth coloring replaces the integer escape count by a real-valued quantity usually written
or equivalently,
Here
The formula may at first appear somewhat arbitrary, particularly because it contains a logarithm of a logarithm. In fact, both logarithms arise naturally from the quadratic growth of the Mandelbrot iteration after
Suppose two nearby points escape as follows. For the first point,
while for a neighboring point,
With ordinary escape-time coloring, both points are assigned the same value:
Yet they are at substantially different stages of escape. The second orbit has progressed much farther into the escaping regime than the first.
The integer iteration count throws away this information.
What we want is therefore a way of using the magnitude of the escaping value to estimate a fractional position between iteration levels.
Instead of obtaining values such as
50, 50, 50, 51, 51,
we would like something more like
50.12, 50.34, 50.76, 51.08, 51.41.
A continuous color palette can then vary continuously with this number.
The iteration is
Once
Taking magnitudes,
Let
Then
This is the key relation from which smooth iteration coloring follows.
Starting from
one additional iteration gives
Another iteration gives
Thus, after
because each Mandelbrot iteration squares the previous magnitude.
The exponent therefore grows as
or
This extremely rapid growth is the reason that two logarithms eventually appear in the smooth-iteration formula.
Take the natural logarithm of
Using
we obtain
The repeated squaring has now become ordinary exponential growth. This is the first important simplification.
Take the logarithm once again:
Using
gives
Since
we obtain
and therefore
Notice what has happened.
Each additional Mandelbrot iteration increases the value of
by approximately one.
Consequently,
is approximately unchanged as the escaping
This is the fundamental mathematical observation behind smooth iteration coloring.
Define
Consider the same orbit one iteration later. Since
we have
Then
Therefore,
Dividing by
Consequently,
is approximately
which simplifies to
Thus,
once
The combination of the integer iteration number and the double logarithm therefore gives us a continuous measure of essentially the same underlying escape state.
The expression derived above naturally suggests
The formula conventionally used for Mandelbrot coloring, however, is
The additional 1 is essentially a choice of normalization and iteration indexing. It establishes where the nominal integer boundaries of the continuous scale are placed.
To see this more concretely, suppose we regard
Take logarithms:
Choose a fixed reference level (see the note below):
Then
Hence
Taking
so
Adding this fractional offset to the current iteration
and therefore
or, since
Thus the "+1" does not represent another actual Mandelbrot iteration. It is part of the chosen normalization of the continuous iteration coordinate.
Changing this additive constant merely translates the palette along its color scale; it does not destroy the smoothing.
Note: The choice
The two logarithms can now be understood intuitively.
After escape,
Thus the magnitude undergoes repeated squaring:
The first logarithm converts powers into multiplication:
The quantity still doubles with each iteration.
The second logarithm converts this doubling into addition:
Dividing by
Thus,
acts like a continuous measure of how many iterations of exponential escape have occurred.
That is the mathematical reason for the double logarithm.
For
the magnitude is
The formula could therefore be implemented directly as
nu = n + 1.0 - log (log (sqrt (x * x + y * y))) / log (2.0);However, the square root can conveniently be avoided. Because
we may write
log_zn = log (x * x + y * y) / 2.0;
nu = n + 1.0 - log (log_zn) / log (2.0);This is mathematically equivalent.
The commonly used formula
is represented directly in the current long double implementation by
long double log_zn, smooth;
log_zn = logl ((r1 * r1) + (i1 * i1)) / 2.0L;
smooth = (long double) iterations + 1.0L
- logl (log_zn) / logl (2.0L);or, more compactly,
smooth = (long double) iterations + 1.0L
- log2l (logl ((r1 * r1) + (i1 * i1)) / 2.0L);The difference between various formulae seen in Mandelbrot programs is often an additive constant, so several variants can produce visually similar results while shifting the palette phase. It is nevertheless useful to distinguish the formulae mathematically.
Suppose a point escapes on iteration
and at that iteration
Then
Next,
Since
we obtain
Therefore,
or
The pixel is consequently not merely classified as "iteration 50." Its position within that escape band has been estimated continuously.
A nearby pixel might have
another
and another
A continuous palette can therefore vary smoothly across what would otherwise have been an abrupt boundary between integer iteration counts 50 and 51.
It is important to distinguish smooth iteration coloring from interpolation between neighbouring pixels.
No gradient of the two-dimensional image is required. We do not need to calculate
or determine the normal to an iso-iteration contour.
Instead, every pixel independently supplies additional information through the final complex value
The integer escape count tells us approximately which band the pixel belongs to. The magnitude
The smooth value is therefore derived from the underlying Mandelbrot dynamics rather than from the geometry of neighbouring pixels.
This has several important consequences:
- no convolution or matrix operation is required;
- neighbouring pixels do not have to be examined;
- the calculation is amenable to parallel processing;
- increasing image resolution does not alter the mathematical definition; and
- the smoothing reflects the actual behaviour of the iterated function.
We used
instead of the exact expression
This approximation becomes increasingly accurate as the orbit escapes.
When
whereas
Thus the relative importance of
Consequently, the asymptotic behaviour approaches
The smooth iteration formula should therefore be regarded as an asymptotic interpolation of the escape dynamics, not as an exact identity for every finite value of
One can improve its behavior by continuing an escaping orbit for additional iterations before calculating the smooth value. The iteration counter must also be advanced for those additional iterations before evaluating
is even better.
The appearance of
Consider instead the generalized "Multibrot" iteration
where
After escape,
Proceeding exactly as before gives
Taking another logarithm,
Thus the double logarithm advances by
The corresponding normalized iteration count becomes
up to the chosen additive normalization.
For the Mandelbrot set,
There is a deeper mathematical interpretation.
For points outside the Mandelbrot set, define the escape-rate quantity
This quantity is closely related to the Green function of the Mandelbrot set; the precise multiplicative normalization depends on the indexing convention used for the critical orbit. With
We divide by
Thus
The quantity tends toward an invariant escape rate.
Taking the base-2 logarithm,
Rearranging,
Thus the continuous iteration count is, apart from the chosen additive normalization,
Smooth iteration coloring is therefore directly related to the negative logarithm of the escape-rate potential, and hence to the Green-function description of escape from the Mandelbrot set.
Begin with the Mandelbrot iteration:
After escape,
Taking magnitudes,
After
Taking logarithms twice,
Therefore,
increases by approximately one for each iteration.
Subtracting this quantity from the integer iteration counter produces an approximately iteration-independent continuous measure of escape:
With the conventional normalization, this becomes
which is the standard smooth or normalized Mandelbrot iteration count.
The two logarithms have a simple origin:
It is this transformation from explosive quadratic growth into an approximately linear iteration coordinate that allows the integer escape bands of the Mandelbrot set to be replaced by a smoothly varying scalar field.
Copyright © 2026 P. David Buchan (pdbuchan@gmail.com)
Code is distributed under the GNU General Public License, version 3 or later, as stated in the source headers and the root LICENSE file.