Posted on 2012-08-09 13:11:42

Mandelbrot in Plain English

Mandelbrot means almond bread in German. But it's also an image produced using an algorithm that takes a complex number, composed of an X and Y coordinate between -2.0 and 2.0 for the complex's real and imaginary components. Then you square the complex number and then check if the resulting complex number's abs() value is greater than 2. Every complex number you get from all the possible combinations that gives you an abs() value smaller than 2 is part of the mandelbrot set, everything else is thrown away.

1
2
3
4
5
6
x = 0.5 # or any number in a range divided by the range
y = 0.5 # like 50 / 100, where 50 is the number and 100 the range 
c = complex(x * 4.0 - 2.0,         
            y * 4.0 - 2.0)         
c = c**2 
abs(c)

The X and Y combinations are then mapped as a bitmap with their boolean values representing either black or white colors for the pixels they represent. You'll end up with an image not too dissimilar to this.

bitmap

Now, that's step one. To get a softer edge, you'll have to give the complex number a few more times to escape. Of course, you'll have to give a limit. If you don't, some could take next to forever to escape. We don't want that. Your machine wouldn't want that either. So you give it a limit, and then you count and take note of the number of times the complex number needed to escape.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
bitmap = {}                                           
limit = 100                                           
size = 100                                            
flt_size = float(size)                                
for x in range(size):                                 
    for y in range(size):                             
        c = complex((x/flt_size) * 4.0 - 2.0,         
                    (y/flt_size) * 4.0 - 2.0)         
        z = 0                                         
        for i in range(limit):                        
            z = (z*z) + c                             
            if abs(z) >= 2:                           
                bitmap[(x, y)] = i                    
                break                                 
        else:                                         
            bitmap[(x, y)] = 0

import pprint                                         
pprint.pprint(bitmap.items())

Then all you have to do is normalize it. And that's simply dividing all the counts by the largest count in the bitmap. If you are writing a bitmap with 255 color values, you could multiply the resulting float with 255.

Here's an example by Dominic:

black and white

You'll notice that the higher limit you give the crisper the image you'll get. There's technique people use wherein they generate three different images with three different limits. The limits could be something like 10, 100, and 1000. They then assign those three images to the red, green and blue channels of an image. I think that's cool. But even better is how this dude wrote a python script that generates a mandelbrot and have the script itself look like it's a mandelbrot.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
_                                      =   (
                                        255,
                                    lambda
                            V       ,B,c
                            :c   and Y(V*V+B,B,  c
                            -1)if(abs(V)<6)else
            (              2+c-4*abs(V)**-0.4)/i
                )  ;v,      x=1500,1000;C=range(v*x
                );import  struct;P=struct.pack;M,\
            j  ='<QIIHHHH',open('M.bmp','wb').write
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
            i  ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9
                *i-950*T  **99,T*70-880*T**18+701*
                T  **9     ,T*i**(1-T**45*2)))(sum(
            [              Y(0,(A%3/3.+X%v+(X/v+
                            A/3/3.-x/2)/1j)*2.5
                            /x   -2.7,i)**2 for  \
                            A       in C
                                    [:9]])
                                        /9)
                                    )   )

It may not score well for legibility but you'll have to credit design of the code. It's the 21st century ee.cummings. The image it generates is equally mesmerizing.

klzzwxh:0006

But that's not the part that got me interested in mandelbrots just yet. I want you to consider each complex number as person. And just like any other person, there's a part that is imaginary and there is a part that's real. And we are all trapped in the matrix, the bitmap of life. And we want to escape from the mundanity of it all, escape from the matrix. Escape unto a higher way of thinking. Nirvana. Zen.

Before I get too metaphorical, let me tell you about buddhabrots. The buddhabrot is an offshoot of the mandelbrot. There's just a small amount of addition to the code. Instead of counting how many iterations were there needed for a pixel to escape, you take note of where it lands, which pixel it stays in, for each iteration in it's attempt to escape. One could say, the journey is more important than the destination and some individuals have higher iterations and some have lower thresholds. I'm not kidding, that's how you do it. Oh, I forget. There's one extra step. You'll have to switch the real and imaginary components of the complex number. I'm also not kidding. Those are the very terms mathmaticians would use. It just so happens that if you apply it to person it also works.

So switch imaginary and real components of a complex person, I mean number. And track it's journey, rather than it's destination.

I was working on this for a few hours. I couldn't get my code to work. But the first time the image came out, it freaked me out. I'm using iteration values 20, 200, 2000.

4k

Buddhabrots are computationally intensive. The fun is actually in the ways to taylore your algorithm so that it'll be more efficient. There are loads of ideas for that scattered in the net.

4k brot 6k brot low brot high brot