Version 2.0 -- Mandelbrot and Julia Set Overview

Introduction

This page presents a very quick overview and introduction to the mathematics behind the Mandelbrot and Julia sets. While it is not necessary to read this to use Mandelbrot Madness!, a good understanding of the math behind the pretty pictures will help you appreciate them more. Warning: Heavy duty math lies ahead! (But its really pretty simple. Honest!)

[Top]

Review of Complex Numbers

At the heart of these functions is a concept called complex numbers. You remember those, right? If you do, you can skip on to the next section. Otherwise, read on.

To help classify numbers, we often divide them up into sets. For example, there is the set of all numbers, which contains every number possible. A better example is the set of integers, which are all numbers which are whole and have no fractional parts (-2, -1, 0, 1, 2,...). The set of real numbers are all numbers that can be expressed by a rational fraction. This includes integers (2 = 2/1) as well as decimal values (0.75 = 3/4).

Just like your mother used to make you distinguish between your real and imaginary friends, there are also imaginary numbers. The most fundamental imaginary number is the square root of -1, which we will assign to the variable i. The value if i cannot be expressed in any way that makes sense. That is why we call it imaginary. We can say that i2 = -1, but we cannot express i directly, since we cannot take the square root of a negative number. The set of all imaginary numbers are all numbers that are multiples of i.

Normally, real and imaginary numbers rarely meet. However, as calculus was invented and mathematicians began solving more and more complex math problems to find special values, strange things began to happen. Often, mathematicians would try to find the roots of an equation; that is, where one of the inputs equals 0. While solving more complex equations, they discovered that some roots did not fit in the set of real numbers. These roots often had both a real and imaginary part. It has since been found that many, many equations have such roots, and a special name has been assigned to such numbers. We call any number with both a real and imaginary part a complex number.

Complex numbers are often written in the form x + yi, where x is the "real part" and y is the "imaginary part." (i is of course the same as above.) Mathematical operations can be defined for complex numbers, as for all numbers, and works much like those for polynomials. For example:

• Addition: (a + bi) + (c + di) = (a + c) + (b + d)i
• Multiplication: (a + bi)(c + di) = ac + adi + bci + bdi2 = (ac - bd) + (ad + bc)i

There is a special case of multiplication where we multiply a complex number by itself: in other words, we raise it to the power of 2. This gives us the following equation:

• (a + bi)2 = (a + bi)(a + bi) = a2 + abi + abi + (bi)2 = (a2 - b2) + 2abi

We single this particular fact out because it is very important to the graphs of the Mandelbrot and Julia sets.

We can graph complex numbers easily to a plane (2-dimensional graph). To do this, we simply assign the x value to an x axis, and do a similar thing with the y values. A single point C = (x + yi) can then easily be plotted, as in the image below: [Top]

Enter the Julia Set: Ordered Chaos

The Julia set is named after Gaston Julia (1893-1978), the French mathematician who first explored its concepts. It is defined as follows: Consider the function

Zn+1 = Zn2 + C

where Zn, Zn+1, and C are all complex numbers. C is assigned to some constant, which is unique to any given Julia set. (A Julia set is defined by this constant.) The number Z will represent a point in the (x, y) plane where x + yi is a complex number. If we feed Z into the equation above, we come up with a new Z value. (We call this process iteration.) If we continue to do this, we will come up with a whole sequence of Z values, all complex numbers, that will exhibit one of the three following properties:

1. The values of Z will increase without bound (go to infinity)
2. The values of Z will collapse to 0 (zero)
3. The values of Z will change, but will not fit in either of the above two categories

In the world of fractals, infinity and zero would be called attractors, because many points approach (are attracted to) these points. The values that fit in the first two categories are sometimes called the Fatou set. The values that fit in the third category are said to be in the Julia set. Points in the Fatou set tend to stick together; that is, points close to each other will follow similar paths, drawing closer to either infinity or zero. Points in the Julia set, however, are said to be chaotic, meaning that very small differences in points tend to show wildly different results.

So where do all those cool pictures come from?

Since we do not know from the start which points are in the Fatou set and which are in the Julia set, we must test each and every one. In reality, this is impossible, but we can approximate this with the help of computers. In essence, we tell the computer to create a graph where each pixel on the screen represents a point on the graph. How far each pixel is apart from its neighbors is a function of the resolution (size) of the graph and the boundaries we set for it. We then take each (x, y) pair (which represents a complex number, remember) and use that as our C value. We then begin to iterate the Julia set function. Since we cannot test for infinity (since it can never be reached), we assign the computer a cut-off or escape value. If the calculations pass outside a certain radius of values (we use 5 in MM!) the value is said to escape to infinity. We also assign another cut-off value on the number of iterations performed, so that if we exceed this number, we say the values wander chaotically and are thus in the Julia set.

The wild colors produced in MM! depend on how "quickly" escaping values move toward infinity. For example, if you used the Grey Scale Palette, the lighter the color is, the more quickly it reaches infinity. (However, there are only 256 colors, and if the calculation goes beyond 256 iterations, the colors will cycle around and be reused. Try this with "The Wheel" preset view to see what I mean.) The very first color in any palette (such as black in the Grey Scale and Rainbow palettes) denotes values inside the Julia set.

As you can easily imagine, testing every single point in the plane can take quite a long time, especially if we create large images (high resolution) with large cut-off values (many iterations). In general, the higher the resolution and the higher the iteration count, the more detail we see, but it will also take much, much longer to complete.

[Top]

The Mandelbrot Set: The Sum of All Julias

Okay, so now we've defined the Julia set. But where's this Mandelbrot set thing? Isn't that what this program is named after?

The Mandelbrot set is named after Benoit Mandelbrot (1924-), a brilliant Polish mathematician (and fellow IBMer). Mandelbrot, inspired by Julia's published works, was one of the first to apply computers to the study of Julia sets, and was the first to coin the term fractal. With the aid of his trusty computer, he began to explore Julia sets, and found (by accident) a very interesting relationship between them. As we discovered above, Julia sets are all points where the sequence of Z values change, often drastically, but do not approach infinity nor zero. Points in the Julia set tend to drift to other such points, and their graphs may connect. Some Julia sets may consist of many disconnected points (called "dust sets"); others from larger "solid" areas that seem all connected; some form thin, wiggly lines that are all connected but do not outline any shapes ("dendritic" types).

Noting the different types of Julia sets, Mandelbrot set out to find some connection between them. Why were some dust sets, some solid, and some dendritic? In time, he discovered a very simple test to determine this value. By setting Z to be the origin of the complex plane (0 + 0i), the Julia set equation can be iterated and a new value calculated. If the resulting series is of class (1) above, the Julia set is a dust set. If it is of class (2), the Julia set is solid. Naturally, if it is type (3), it is dendritic. Sounds simple enough.

Or is it? Curious about this new-found information, Mandelbrot decided to plot a graph of this new equation and colored the values depending on whether they were types (1), (2), or (3). Interestingly, he created a sort of "master" Julia set, a totally different fractal we know today as the Mandelbrot set.

If we zoom in on a portion of a Julia set, we will see the same detail repeated over and over on a smaller scale. Other than size, it does not change. However, because the Mandelbrot set is an amalgamation of all Julia sets, the detail changes drastically depending on where you zoom in. It is based on the precise location in which you are zooming, and is often similar in shape to the Julia sets derived from that area. The Mandelbrot set is never the same twice, and you can technically zoom forever (if it weren't for the limits of your computer's hardware).

[Top]

Why Are These Functions Fractals?

A fractal, for those of you dying to know, is an object (function) with a fractional dimension, meaning its dimension is not a whole number. A point has a dimension of zero, a line a dimension of one, a plane a dimension of two, and a sphere a dimension of three. But some objects do not fit easily within the normal (Euclidean) concept of geometry; a line with a kink in it travels in more than one dimension, but (in essence) less than two.

So why the Mandelbrot and Julia sets fractals? Technically, the sets themselves are not. However, the complex graphs created by graphing them in the complex plane are.

Unfortunately, the term fractal is extremely hard to define. The definition above is highly simplistic. Through some highly complex mathematics, we can prove that the Mandelbrot and Julia sets meet this definition, but I'll save you the headaches here. Why don't we look as some other definitions of fractals and compare what we know to them.

The Divergent Measure definition: Any shape that has the unusual property that when you measure its length, area, surface area or volume in discrete units, the measured value varies exponentially with the size of the discrete unit. We know this to be true by the very definition of the two sets. As we stated above, even minor changes in our starting values produce wildly different values of the result. Close examination of the graphs also reveals this with the bizarre patterns displayed.

Hausdorff definition: Any geometric form whose Hausdorff dimension is greater than its topological dimension. Hmmm... it might help to know what a Hausdorff dimension is. For a shape F imbedded in D-dimensional Euclidean space SD, define the measure Me to be

Me = eD * Ne

where Ne is the minimum number of points in the space SD such that every point in F lies within a neighborhood of radius e of at least one point. Then the Hausdorff dimension of F is

lime->0 ln(Ne) / ln(D)

Ouch! My eyes just hurt looking at that! Suffice it to say we won't calculate all that, but it has been found that the Mandelbrot set has a Hausdorff dimension of 2, which is greater than the topological (boundary) dimension, which is 1. This means the graph is indeed a fractal.

The Natural definition: A geometric figure or natural object that combines the following characteristics: (a) its parts have the same form or structure as the whole, except that they are at a different scale and may be slightly deformed; (b) its form is extremely irregular or fragmented, and remains so, whatever the scale of examination; (c) it contains "distinct elements" whose scales are very varied and cover a large range. This looks a little more within our grasp to prove. The first part is what we like to call self-similarity, which the Julia set demonstrates easily (no matter how far in we zoom, we see the same structures), but the Mandelbrot set is harder to see. However, on closer examination, we see the master Mandelbrot set repeated over and over leading us to believe that the first part is true. Part (b) is highly obvious for our sets, as is part (c).

Thus, we can prove our graphs are indeed fractals. If this quick gloss-over doesn't satisfy you, I strongly suggest a quick jaunt to the Web, where tons of sites can give you far better definitions than I.

[Top]

Mandelbrot and Julia Set Algorithms

For the computer literate out there, here's a simple algorithm in psuedocode for building the Mandelbrot set. First, a few variables must be defined:

• xmin, xmax, ymin, and ymax are the boundaries of our current view. For simplicity's sake, in MM! we define that our viewing area must be square, therefore xmax - xmin = ymax - ymin
• res is the resolution, or size, of our image in pixels. Since he have defined the image to be square, the x and y resolution will be the same.
• num_colors is our color depth, or the number of colors available to us.
• iters is the number of iterations we allow before declaring a point to be in the set. If we escape the radius before this number is reached, we declare that the given point escapes to infinity.
• xgap and ygap represent the distance between to pixels in the actual graph. The x value of point pn+1 will be xgap more than the x value of point pn. The same follows for y values.
• setPixel() is the function that draws a pixel to the screen. It takes three arguments: an x value, a y value, and the color of the pixel. For us, we will use an indexed palette, where a positive integer between 0 and num_colors will represent a given color.
• j and k will be iterative values used to iterate through every point in the plane.
• x, y, savex, savex2, savey, radius, and count will be intermediate values used in the calculation.

The algorithm:

xgap = (xmax - xmin) / res
ygap = (ymax - ymin) / res
for j = 0 to (res - 1)
for k = 0 to (res - 1)
x = xmin + j * xgap
y = ymin + k * ygap
savex = x
savey = y
count = 0
while (radius < 5.0) and (count < iters)
savex2 = x
x = x * x - y * y + savex
y = 2.0 * savex2 * y + savey
radius = x * x + y * y
count = count + 1
endwhile
setPixel(j, res - k, count mod num_colors)
else
setPixel(j, res - k, 0)
endif
endfor
endfor

Notes:

• Note that in the setPixel() function calls, the y component k is subtracted from res. This means we draw the graph from the bottom up (really!).
• For Julia sets, instead of setting savex and savey to the x and y starting values, set them to the x and y parts of the constant C for the Julia set you wish to create (remember, C = (x + yi))
• The escape radius value is hard-coded here to 5. Why? Because it has been proven that the origin stays bounded if and only if its image always stays within a distance of 2 from the origin. This gives us a circular boundary with a radius of x2 + y2 = 22 = 4 < 5. (A little extra for added measure.) Officially, the radius value can be changed in the MandelObject class if you reference it outside of MM!, but you should only make it higher. MM! has always hard-coded it to 5.
• Can you see where the multiplication and addition of complex numbers comes in? If not, consider the following equations:

Z2 + C = (z1 + z2i)2 + (c1 + c2i)
= ((z12 - z22) + 2z1z2i) + (c1 + c2i)
= ((z12 - z22) + c1) + (2z1z2 + c2)i

Remember that x and y in the above algorithm corresponds to (x + yi) = Z.

• savex2 is used to hold the old value of x so we do not lose it after we recalculate x.
• Note that j, k, res, iters, num_colors, and count are all integers, while all other variables should be floating point numbers, preferably double-precision. If you wish to use a language such as C++ or Java with this algorithm, you should explicitly cast these variables where appropriate.

[Top]