# Mandelbrot Set

Mandelbrot set is a famous two dimensional [fractal](fractal.md), a [set](set.md) of [points](point.md) in two dimensional plane that are defined by a specific very simple equation. It turns out this set has an infinitely complex border (i.e. its shape is a fractal) and the whole thing is just [beautiful](beauty.md) to look at, especially when we draw it with colors and start zooming in to various interesting places -- patterns keep emerging down to infinitely small scales so we may keep zooming in forever and still discover new and new things; some patterns show self similarity, some not. Applying tricks to further add colors to inside and outside of the set increases the visual beauty yet more -- rendering Mandelbrot set is in fact a quite popular activity among programmers as it's very easy to [program](programming.md) such visualizations (at least until we reach the limits of [floating point](float.md) precision, then some more cleverness has to be applied; and yes, Mandelbrot can also be rendered only using [fixed point](fixed_point.md)). The origins of exploring this set are somewhere around 1905 when Fatou and Julia explored the equations related to it, however due to the lack of [computers](computer.md) the set couldn't very well be drawn -- this was only achieved much later, the first rendering of the set seems to be from 1978, albeit of very poor resolution. The set is named after Benoit Mandelbrot who is often considered the father of the field of fractal geometry and who researched this particular set a lot. Of course, Mandelbrot set is awesome, it's a like a whole infinite world to explore, hidden in just one simple formula.

{ Pretty amazing ASCII rendering of the Mandelbrot set can be found at http://www.mrob.com/pub/muency/asciigraphics.html. ~drummyfish }

```
 ___________________________________________________________
|[-2,1]                                       .             |
|                                            .:.            |
|                                           :::::           |
|                                         ...:::..  .       |
|                                    :..:::::::::::::....   |
|                                   .:::::::::::::::::::'   |
|                                 ::::::::::::::::::::::::  |
|                                :::::::::::::::::::::::::' |
|                     :..:::.   .:::::::::::::::::::::::::: |
|                   .:::::::::. ::::::::::::::::::::::::::  |
|                .. ::::::::::: :::::::::::::::::::::::::'  |
|      '  '     '::':::::::::::'::::::::::::::::::::::::.   |
|                   ::::::::::: ::::::::::::::::::::::::::  |
|                    ':::::::'  ::::::::::::::::::::::::::. |
|                     '  '''     :::::::::::::::::::::::::' |
|                                '::::::::::::::::::::::::' |
|                                 ''::::::::::::::::::::''  |
|                                    ::::::::::::::::::::   |
|                                    '  ''::::::::'':       |
|                                           .:::.           |
|                                           ':::'           |
|                                             :             |
|___________________________________________________[0.5,-1]|
```

*Simple ASCII rendering of Mandelbrot set.*

**Definition**: we use [complex numbers](complex_number.md) to define the set. Consider the following series of complex numbers *z[n]*:

*z[0] = 0*, *z[n + 1] = z[n]^2 + p*

Mandelbrot set is the set of all points *p* for which the [absolute value](abs.md) ("length") of *z[n]* does NOT grow towards infinity as *n* goes towards infinity.

I.e. taking any point *p* in the complex plane (whose real and imaginary parts we see as the *x* and *y* coordinates), plugging it into the above equation and iterating the series infinitely many times, if the absolute value of *z[n]* stays bounded under some finite value (even very large, just not infinitely large), the number belongs to the set, otherwise not (if the absolute value diverges towards infinity). I.e. in other words the Mandelbrot set is a set of kind of "well behaved" points that don't shoot away to infinity when we keep applying some operation to them over and over. Of course computers cannot evaluate infinitely many iterations of the series so they cannot compute the set 100% accurately, but we may very well [approximate](approximation.md) by performing many iterations (let's 100000) and seeing if the value we get is "very large" (let's say 1000000000) when we stop -- this will work correctly for most points and those few points near the set borders where we make a wrong guess won't really be noticed unless we zoom in very close -- in such cases we can simply perform more iterations to increase precision. To add **[colors](color.md)** to the visualization (so that we don't observe just the borders but also some kind of structure inside and outside of the set) we may simply assign different colors to the points depending e.g. on how big the absolute value is at the time we stop the evaluation, or how many iterations it took for the absolute value to exceed given limit (for points outside the set). Also note that for nice pictures we should apply [antialiasing](antialiasing.md). Additional fancy filters and [shaders](shader.md) such as some kind of postprocessing or fake 3D can also be applied to make the result even more impressive.

TODO: example on specific point

There are further [optimizations](optimization.md) we may apply to calculate the set faster, for example it's proven that if absolute value of *z[n]* ever gets greater than 2, the point won't lie in the set. The set itself also lies in the circle centered at [0,0] with radius 2, so points outside this area can be safely marked as lying outside the set.

As an alternative to drawing the set in the traditional plane with *x*/*y* axes correspond to the *real*/*imaginary* parts of the complex number, we may utilize different mappings, for example [polar coordinates](polar_coords.md) or the "inversion mode" (swapping zero and infinity) used in xaos. These may offer yet different angles of view of the set.

Mandelbrot set is similar and related to **[Julia sets](julia_set.md)**; in a way Mandelbrot set is kind of a map of Julia sets, of which there are infinitely many. Each Julia set is, like the Mandelbrot, a set of complex numbers that usually has fractal boundary. Julia sets are defined using the same series as Mandelbrot set, however for given Julia set we take the *p* to be constant and instead set *z[0]* to the visualized coordinate -- so each *p* in the complex plane has its own Julia set. There are some deep mathematical connections between Julia sets and Mandelbrot set. To a Mandelbrot set admirer Julia sets offer infinitely many similar worlds to explore.

The following are some **attributes** of the Mandelbrot set:

- **[Hausdorff dimension](hausdorff_dimension.md)** (of the boundary): 2
- **area**: approximately 1.5052; this is a current best estimate, the area is not easy to calculate (it may be estimated e.g. with [Monte Carlo](monte_carlo.md) methods).
- It is **symmetric** along the *x* axis.
- It's proven the set is **connected**, i.e. it's just a single "island".
- ...

**How to explore Mandelbrot set?** There are about billion programs for this, but a quite nice FOSS one is e.g. [Xaos](xaos.md).

As the set is being studied and explored a lot, some even started to make maps of it and give names to various regions. The biggest bulb-part is called the *Main Cardioid*, the smaller disk to the left of it is the *Main Disk*. Between these two parts there is the *Seahorse Valley*. On the right side of *Main Cardioid* there is the *Elephant Valley*. There are terms such as *mu-atom* (also *island*, *mandelbrotie*, *minibrot* or *midget*) -- the smaller distorted self-similar versions of the big set inside the set itself. And so on. Here are some examples of **interesting places** (nice for wallpapers :]) in the Mandelbrot set (views are denoted as [center X, center Y, view radius]):

- View [-0.774680610626904,-0.137416885603787,8e-12] shows a very nice circular pattern.
- View [-0.74989,-0.0376656,1.04358e-05] shows another nice grid pattern.
- View [0.353447,0.0990225,1.12029e-05] shows a cool spiral pattern.
- View [-1.4045,0,0.0006] shows self-similarity, an approximate smaller Mandelbrot set shape inside itself.
- Views [-1.38379,0,0.037555] and [-1.3973347,0,0.008779] show approximate self similarity.
- Point [-1.3932809650418352,0.0215485287711777498] shows a very thin connection.
- Point [0.372138,0.0903982] shows an infinitely zoomable point from which circular arms stem.
- ...

**Generalizations and modifications**: mentioned [Julia sets](julia_set.md) are very similar to the Mandelbrot set. **[Multibrot](multibrot.md)** sets are sets similar to the Mandelbrot which we define by requiring *abs(z[n])* to not surpass some given value *T* under inifinite iteration, i.e. Mandelbrot set is one of Multibrot sets, that in which we set *T = 2* (because as mentioned above, reaching 2 always leads to divergence towards infinity); for different values of *T* we'll get similar but different Multibrot fractal sets. We may also modify the iterative equation from quadratic to cubic (replace *z[n]^2* with *z[n]^3*), or a different power (or modify the equation in similar ways) to again get sets similar to the Mandelbrot. Using [quaternions](quaternion.md) instead of complex numbers generalized Mandelbrot from 2D to 4D.

## Code

The following code is a simple [C](c.md) program that renders the Mandelbrot set into terminal (for demonstrative purposes, it isn't efficient or do any [antialiasing](antialiasing.md)).

```
#include <stdio.h>

#define ROWS 30
#define COLS 60
#define FROM_X -2.0
#define FROM_Y 1.0
#define STEP (2.5 / ((double) COLS))

unsigned int mandelbrot(double x, double y)
{
  double cx = x, cy = y, tmp;

  for (int i = 0; i < 1000; ++i)
  {
    tmp = cx * cx - cy * cy + x;
    cy = 2 * cx * cy + y;
    cx = tmp;

    if (cx * cx * cy * cy > 1000000000)
      return 0;
  }

  return 1;
}

int main(void)
{
  double cx, cy = FROM_Y;

  for (int y = 0; y < ROWS; ++y)
  {
    cx = FROM_X;

    for (int x = 0; x < COLS; ++x)
    {
      unsigned int point = 
        mandelbrot(cx,cy) + (mandelbrot(cx,cy + STEP) * 2);   

      putchar(point == 3 ? ':' : (point == 2 ? '\'' : 
        (point == 1 ? '.' : ' ')));

      cx += STEP;
    }

    putchar('\n');

    cy -= 2 * STEP;
  }

  return 0;
}
```