Mandelbrot set

From Rosetta Code
Jump to: navigation, search
This page uses content from Wikipedia. The original article was at Mandelbrot_set. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)
Task
Mandelbrot set
You are encouraged to solve this task according to the task description, using any language you may know.

Generate and draw the Mandelbrot set.

Note that there are many algorithms to draw Mandelbrot set and there are many functions which generate it .

Contents

[edit] ACL2

(defun abs-sq (z)
(+ (expt (realpart z) 2)
(expt (imagpart z) 2)))
 
(defun round-decimal (x places)
(/ (floor (* x (expt 10 places)) 1)
(expt 10 places)))
 
(defun round-complex (z places)
(complex (round-decimal (realpart z) places)
(round-decimal (imagpart z) places)))
 
(defun mandel-point-r (z c limit)
(declare (xargs :measure (nfix limit)))
(cond ((zp limit) 0)
((> (abs-sq z) 4) limit)
(t (mandel-point-r (+ (round-complex (* z z) 15) c)
c
(1- limit)))))
 
(defun mandel-point (z iters)
(- 5 (floor (mandel-point-r z z iters) (/ iters 5))))
 
(defun draw-mandel-row (im re cols width iters)
(declare (xargs :measure (nfix cols)))
(if (zp cols)
nil
(prog2$ (cw (coerce
(list
(case (mandel-point (complex re im)
iters)
(5 #\#)
(4 #\*)
(3 #\.)
(2 #\.)
(otherwise #\Space))) 'string))
(draw-mandel-row im
(+ re (/ (/ width 3)))
(1- cols)
width iters))))
 
(defun draw-mandel (im rows width height iters)
(if (zp rows)
nil
(progn$ (draw-mandel-row im -2 width width iters)
(cw "~%")
(draw-mandel (- im (/ (/ height 2)))
(1- rows)
width
height
iters))))
 
(defun draw-mandelbrot (width iters)
(let ((height (floor (* 1000 width) 3333)))
(draw-mandel 1 height width height iters)))
Output:
> (draw-mandelbrot 60 100)
                                        #                   
                                     ..                     
                                   .####                    
                            .     # .##.                    
                             ##*###############.            
                           #.##################             
                          .######################.          
                 ######.  #######################           
               ##########.######################            
##############################################              
               ##########.######################            
                 ######.  #######################           
                          .######################.          
                           #.##################             
                             ##*###############.            
                            .     # .##.                    
                                   .####                    
                                     ..                     

[edit] Ada

Library: Lumen

mandelbrot.adb:

with Lumen.Binary;
package body Mandelbrot is
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor is
use type Lumen.Binary.Byte;
Result : Lumen.Image.Descriptor;
X0, Y0 : Float;
X, Y, Xtemp : Float;
Iteration  : Float;
Max_Iteration : constant Float := 1000.0;
Color : Lumen.Binary.Byte;
begin
Result.Width := Width;
Result.Height := Height;
Result.Complete := True;
Result.Values := new Lumen.Image.Pixel_Matrix (1 .. Width, 1 .. Height);
for Screen_X in 1 .. Width loop
for Screen_Y in 1 .. Height loop
X0 := -2.5 + (3.5 / Float (Width) * Float (Screen_X));
Y0 := -1.0 + (2.0 / Float (Height) * Float (Screen_Y));
X := 0.0;
Y := 0.0;
Iteration := 0.0;
while X * X + Y * Y <= 4.0 and then Iteration < Max_Iteration loop
Xtemp := X * X - Y * Y + X0;
Y := 2.0 * X * Y + Y0;
X := Xtemp;
Iteration := Iteration + 1.0;
end loop;
if Iteration = Max_Iteration then
Color := 255;
else
Color := 0;
end if;
Result.Values (Screen_X, Screen_Y) := (R => Color, G => Color, B => Color, A => 0);
end loop;
end loop;
return Result;
end Create_Image;
 
end Mandelbrot;

mandelbrot.ads:

with Lumen.Image;
 
package Mandelbrot is
 
function Create_Image (Width, Height : Natural) return Lumen.Image.Descriptor;
 
end Mandelbrot;

test_mandelbrot.adb:

with System.Address_To_Access_Conversions;
with Lumen.Window;
with Lumen.Image;
with Lumen.Events;
with GL;
with Mandelbrot;
 
procedure Test_Mandelbrot is
 
Program_End : exception;
 
Win : Lumen.Window.Handle;
Image : Lumen.Image.Descriptor;
Tx_Name : aliased GL.GLuint;
Wide, High : Natural := 400;
 
-- Create a texture and bind a 2D image to it
procedure Create_Texture is
use GL;
 
package GLB is new System.Address_To_Access_Conversions (GLubyte);
 
IP : GLpointer;
begin -- Create_Texture
-- Allocate a texture name
glGenTextures (1, Tx_Name'Unchecked_Access);
 
-- Bind texture operations to the newly-created texture name
glBindTexture (GL_TEXTURE_2D, Tx_Name);
 
-- Select modulate to mix texture with color for shading
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
-- Wrap textures at both edges
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
-- How the texture behaves when minified and magnified
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-- Create a pointer to the image. This sort of horror show is going to
-- be disappearing once Lumen includes its own OpenGL bindings.
IP := GLB.To_Pointer (Image.Values.all'Address).all'Unchecked_Access;
 
-- Build our texture from the image we loaded earlier
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, GLsizei (Image.Width), GLsizei (Image.Height), 0,
GL_RGBA, GL_UNSIGNED_BYTE, IP);
end Create_Texture;
 
-- Set or reset the window view parameters
procedure Set_View (W, H : in Natural) is
use GL;
begin -- Set_View
GL.glEnable (GL.GL_TEXTURE_2D);
glClearColor (0.8, 0.8, 0.8, 1.0);
 
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glViewport (0, 0, GLsizei (W), GLsizei (H));
glOrtho (0.0, GLdouble (W), GLdouble (H), 0.0, -1.0, 1.0);
 
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
end Set_View;
 
-- Draw our scene
procedure Draw is
use GL;
begin -- Draw
-- clear the screen
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
GL.glBindTexture (GL.GL_TEXTURE_2D, Tx_Name);
 
-- fill with a single textured quad
glBegin (GL_QUADS);
begin
glTexCoord2f (1.0, 0.0);
glVertex2i (GLint (Wide), 0);
 
glTexCoord2f (0.0, 0.0);
glVertex2i (0, 0);
 
glTexCoord2f (0.0, 1.0);
glVertex2i (0, GLint (High));
 
glTexCoord2f (1.0, 1.0);
glVertex2i (GLint (Wide), GLint (High));
end;
glEnd;
 
-- flush rendering pipeline
glFlush;
 
-- Now show it
Lumen.Window.Swap (Win);
end Draw;
 
-- Simple event handler routine for keypresses and close-window events
procedure Quit_Handler (Event : in Lumen.Events.Event_Data) is
begin -- Quit_Handler
raise Program_End;
end Quit_Handler;
 
-- Simple event handler routine for Exposed events
procedure Expose_Handler (Event : in Lumen.Events.Event_Data) is
pragma Unreferenced (Event);
begin -- Expose_Handler
Draw;
end Expose_Handler;
 
-- Simple event handler routine for Resized events
procedure Resize_Handler (Event : in Lumen.Events.Event_Data) is
begin -- Resize_Handler
Wide := Event.Resize_Data.Width;
High := Event.Resize_Data.Height;
Set_View (Wide, High);
-- Image := Mandelbrot.Create_Image (Width => Wide, Height => High);
-- Create_Texture;
Draw;
end Resize_Handler;
 
begin
-- Create Lumen window, accepting most defaults; turn double buffering off
-- for simplicity
Lumen.Window.Create (Win => Win,
Name => "Mandelbrot fractal",
Width => Wide,
Height => High,
Events => (Lumen.Window.Want_Exposure => True,
Lumen.Window.Want_Key_Press => True,
others => False));
 
-- Set up the viewport and scene parameters
Set_View (Wide, High);
 
-- Now create the texture and set up to use it
Image := Mandelbrot.Create_Image (Width => Wide, Height => High);
Create_Texture;
 
-- Enter the event loop
declare
use Lumen.Events;
begin
Select_Events (Win => Win,
Calls => (Key_Press => Quit_Handler'Unrestricted_Access,
Exposed => Expose_Handler'Unrestricted_Access,
Resized => Resize_Handler'Unrestricted_Access,
Close_Window => Quit_Handler'Unrestricted_Access,
others => No_Callback));
end;
exception
when Program_End =>
null;
end Test_Mandelbrot;
Output:

Ada Mandelbrot.gif

[edit] ALGOL 68

Plot part of the Mandelbrot set as a pseudo-gif image.

 
INT pix = 300, max iter = 256, REAL zoom = 0.33 / pix;
[-pix : pix, -pix : pix] INT plane;
COMPL ctr = 0.05 I 0.75 # center of set #;
 
# Compute the length of an orbit. #
PROC iterate = (COMPL z0) INT:
BEGIN COMPL z := 0, INT iter := 1;
WHILE (iter +:= 1) < max iter # not converged # AND ABS z < 2 # not diverged #
DO z := z * z + z0
OD;
iter
END;
 
# Compute set and find maximum orbit length. #
INT max col := 0;
FOR x FROM -pix TO pix
DO FOR y FROM -pix TO pix
DO COMPL z0 = ctr + (x * zoom) I (y * zoom);
IF (plane [x, y] := iterate (z0)) < max iter
THEN (plane [x, y] > max col | max col := plane [x, y])
FI
OD
OD;
 
# Make a plot. #
FILE plot;
INT num pix = 2 * pix + 1;
make device (plot, "gif", whole (num pix, 0) + "x" + whole (num pix, 0));
open (plot, "mandelbrot.gif", stand draw channel);
FOR x FROM -pix TO pix
DO FOR y FROM -pix TO pix
DO INT col = (plane [x, y] > max col | max col | plane [x, y]);
REAL c = sqrt (1- col / max col); # sqrt to enhance contrast #
draw colour (plot, c, c, c);
draw point (plot, (x + pix) / (num pix - 1), (y + pix) / (num pix - 1))
OD
OD;
close (plot)
 

[edit] Applesoft BASIC

This version takes into account the Apple II's funky 280×192 6-color display, which has an effective resolution of only 140×192 in color.

 
10 HGR2
20 XC = -0.5  : REM CENTER COORD X
30 YC = 0  : REM " " Y
40 S = 2  : REM SCALE
45 IT = 20  : REM ITERATIONS
50 XR = S * 4 / 3  : REM TOTAL RANGE OF X
60 YR = S  : REM " " " Y
70 X0 = XC - (XR/2) : REM MIN VALUE OF X
80 X1 = XC + (XR/2) : REM MAX " " X
90 Y0 = YC - (YR/2) : REM MIN " " Y
100 Y1 = YC - (YR/2) : REM MAX " " Y
110 XM = XR / 279  : REM SCALING FACTOR FOR X
120 YM = YR / 191  : REM " " " Y
130 FOR YI = 0 TO 3  : REM INTERLEAVE
140 FOR YS = 0+YI TO 188+YI STEP 4 : REM Y SCREEN COORDINATE
145 HCOLOR=3 : HPLOT 0,YS TO 279,YS
150 FOR XS = 0 TO 278 STEP 2  : REM X SCREEN COORDINATE
170 X = XS * XM + X0  : REM TRANSL SCREEN TO TRUE X
180 Y = YS * YM + Y0  : REM TRANSL SCREEN TO TRUE Y
190 ZX = 0
200 ZY = 0
210 XX = 0
220 YY = 0
230 FOR I = 0 TO IT
240 ZY = 2 * ZX * ZY + Y
250 ZX = XX - YY + X
260 XX = ZX * ZX
270 YY = ZY * ZY
280 C = IT-I
290 IF XX+YY >= 4 GOTO 301
300 NEXT I
301 IF C >= 8 THEN C = C - 8 : GOTO 301
310 HCOLOR = C : HPLOT XS, YS TO XS+1, YS
320 NEXT XS
330 NEXT YS
340 NEXT YI
 

By making the following modifications, the same code will render the Mandelbrot set in monochrome at full 280×192 resolution.

 
150 FOR XS = 0 TO 279
301 C = (C - INT(C/2)*2)*3
310 HCOLOR = C: HPLOT XS, YS
 

[edit] AutoHotkey

Max_Iteration := 256
Width := Height := 400
 
File := "MandelBrot." Width ".bmp"
Progress, b2 w400 fs9, Creating Colours ...
Gosub, CreateColours
Gosub, CreateBitmap
Progress, Off
Gui, -Caption
Gui, Margin, 0, 0
Gui, Add, Picture,, %File%
Gui, Show,, MandelBrot
Return
 
GuiClose:
GuiEscape:
ExitApp
 
 
 
;---------------------------------------------------------------------------
CreateBitmap: ; create and save a 32bit bitmap file
;---------------------------------------------------------------------------
; define header details
HeaderBMP := 14
HeaderDIB := 40
DataOffset := HeaderBMP + HeaderDIB
ImageSize := Width * Height * 4 ; 32bit
FileSize := DataOffset + ImageSize
Resolution := 3780 ; from mspaint
 
; create bitmap header
VarSetCapacity(IMAGE, FileSize, 0)
NumPut(Asc("B") , IMAGE, 0x00, "Char")
NumPut(Asc("M") , IMAGE, 0x01, "Char")
NumPut(FileSize , IMAGE, 0x02, "UInt")
NumPut(DataOffset , IMAGE, 0x0A, "UInt")
NumPut(HeaderDIB , IMAGE, 0x0E, "UInt")
NumPut(Width , IMAGE, 0x12, "UInt")
NumPut(Height , IMAGE, 0x16, "UInt")
NumPut(1 , IMAGE, 0x1A, "Short") ; Planes
NumPut(32 , IMAGE, 0x1C, "Short") ; Bits per Pixel
NumPut(ImageSize , IMAGE, 0x22, "UInt")
NumPut(Resolution , IMAGE, 0x26, "UInt")
NumPut(Resolution , IMAGE, 0x2A, "UInt")
 
; fill in Data
Gosub, CreatePixels
 
; save Bitmap to file
FileDelete, %File%
Handle := DllCall("CreateFile", "Str", File, "UInt", 0x40000000
, "UInt", 0, "UInt", 0, "UInt", 2, "UInt", 0, "UInt", 0)
DllCall("WriteFile", "UInt", Handle, "UInt", &IMAGE, "UInt"
, FileSize, "UInt *", Bytes, "UInt", 0)
DllCall("CloseHandle", "UInt", Handle)
 
Return
 
 
 
;---------------------------------------------------------------------------
CreatePixels: ; create pixels for [-2 < x < 1] [-1.5 < y < 1.5]
;---------------------------------------------------------------------------
Loop, % Height // 2 + 1 {
yi := A_Index - 1
y0 := -1.5 + yi / Height * 3 ; range -1.5 .. +1.5
Progress, % 200*yi // Height, % "Current line: " 2*yi " / " Height
Loop, %Width% {
xi := A_Index - 1
x0 := -2 + xi / Width * 3 ; range -2 .. +1
Gosub, Mandelbrot
p1 := DataOffset + 4 * (Width * yi + xi)
NumPut(Colour, IMAGE, p1, "UInt")
p2 := DataOffset + 4 * (Width * (Height-yi) + xi)
NumPut(Colour, IMAGE, p2, "UInt")
}
}
Return
 
 
 
;---------------------------------------------------------------------------
Mandelbrot: ; calculate a colour for each pixel
;---------------------------------------------------------------------------
x := y := Iteration := 0
While, (x*x + y*y <= 4) And (Iteration < Max_Iteration) {
xtemp := x*x - y*y + x0
y := 2*x*y + y0
x := xtemp
Iteration++
}
Colour := Iteration = Max_Iteration ? 0 : Colour_%Iteration%
 
Return
 
 
 
;---------------------------------------------------------------------------
CreateColours: ; borrowed from PureBasic example
;---------------------------------------------------------------------------
Loop, 64 {
i4 := (i3 := (i2 := (i1 := A_Index - 1) + 64) + 64) + 64
Colour_%i1% := RGB(4*i1 + 128, 4*i1, 0)
Colour_%i2% := RGB(64, 255, 4*i1)
Colour_%i3% := RGB(64, 255 - 4*i1, 255)
Colour_%i4% := RGB(64, 0, 255 - 4*i1)
}
Return
 
 
 
;---------------------------------------------------------------------------
RGB(r, g, b) { ; return 24bit color value
;---------------------------------------------------------------------------
Return, (r&0xFF)<<16 | g<<8 | b
}

[edit] AWK

 
BEGIN {
XSize=59; YSize=21;
MinIm=-1.0; MaxIm=1.0;MinRe=-2.0; MaxRe=1.0;
StepX=(MaxRe-MinRe)/XSize; StepY=(MaxIm-MinIm)/YSize;
for(y=0;y<YSize;y++)
{
Im=MinIm+StepY*y;
for(x=0;x<XSize;x++)
{
Re=MinRe+StepX*x; Zr=Re; Zi=Im;
for(n=0;n<30;n++)
{
a=Zr*Zr; b=Zi*Zi;
if(a+b>4.0) break;
Zi=2*Zr*Zi+Im; Zr=a-b+Re;
}
printf "%c",62-n;
}
print "";
}
exit;
}
 
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<==========
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<====
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<===
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<==
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<=
><<<<;;;;;:::972456-567763 +9;;<<<<<<<
><;;;;;;::::9875& .3 *9;;;<<<<<<
>;;;;;;::997564' ' 8:;;;<<<<<<
>::988897735/ &89:;;;<<<<<<
>::988897735/ &89:;;;<<<<<<
>;;;;;;::997564' ' 8:;;;<<<<<<
><;;;;;;::::9875& .3 *9;;;<<<<<<
><<<<;;;;;:::972456-567763 +9;;<<<<<<<
>=<<<<<<<<;;;:599999999886 %78:;;<<<<<<=
>>=<<<<<<<<<<<;;;::::::999752 *79:;<<<<<<==
>>==<<<<<<<<<<<<<;;;;::::996. &2 45335:;<<<<<<===
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764 5789999:;;<<<<<====
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974 (.9::::;;<<<<<======
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
 

[edit] BASIC

Works with: QBasic

This is almost exactly the same as the pseudocode from the Wikipedia entry's "For programmers" section (which it's closely based on, of course). The image generated is very blocky ("low-res") due to the selected video mode, but it's fairly accurate.

SCREEN 13
WINDOW (-2, 1.5)-(2, -1.5)
FOR x0 = -2 TO 2 STEP .01
FOR y0 = -1.5 TO 1.5 STEP .01
x = 0
y = 0
 
iteration = 0
maxIteration = 223
 
WHILE (x * x + y * y <= (2 * 2) AND iteration < maxIteration)
xtemp = x * x - y * y + x0
y = 2 * x * y + y0
 
x = xtemp
 
iteration = iteration + 1
WEND
 
IF iteration <> maxIteration THEN
c = iteration
ELSE
c = 0
END IF
 
PSET (x0, y0), c + 32
NEXT
NEXT

[edit] BASIC256

fastgraphics
 
graphsize 384,384
refresh
kt=319 : m = 4.0
xmin=2.1 : xmax=-0.6 : ymin=-1.35 : ymax=1.35
dx=(xmax-xmin)/graphwidth : dy=(ymax-ymin)/graphheight
 
for x=0 to graphwidth
jx = xmin+x*dx
for y=0 to graphheight
jy = ymin+y*dy
k = 0 : wx = 0.0 : wy = 0.0
do
tx = wx*wx-(wy*wy+jx)
ty = 2.0*wx*wy+jy
wx = tx
wy = ty
r = wx*wx+wy*wy
k = k+1
until r>m or k>kt
 
if k>kt then
color black
else
if k<16 then color k*8,k*8,128+k*4
if k>=16 and k<64 then color 128+k-16,128+k-16,192+k-16
if k>=64 then color kt-k,128+(kt-k)/2,kt-k
end if
plot x,y
next y
refresh
next x
imgsave "Mandelbrot_BASIC-256.png", "PNG"
 
Image generated by the script:

Mandelbrot BASIC-256.jpg

[edit] BBC BASIC

      sizex% = 300 : sizey% = 300
maxiter% = 128
VDU 23,22,sizex%;sizey%;8,8,16,128
ORIGIN 0,sizey%
GCOL 1
FOR X% = 0 TO 2*sizex%-2 STEP 2
xi = X%/200 - 2
FOR Y% = 0 TO sizey%-2 STEP 2
yi = Y% / 200
x = 0
y = 0
FOR I% = 1 TO maxiter%
IF x*x+y*y > 4 EXIT FOR
xt = xi + x*x-y*y
y = yi + 2*x*y
x = xt
NEXT
IF I%>maxiter% I%=0
COLOUR 1,I%*15,I%*8,0
PLOT X%,Y% : PLOT X%,-Y%
NEXT
NEXT X%

Mandelbrot bbc.gif

[edit] Small BASIC

 
GraphicsWindow.Show()
size = 500
half = 250
GraphicsWindow.Width = size * 1.5
GraphicsWindow.Height = size
GraphicsWindow.Title = "Mandelbrot"
For px = 1 To size * 1.5
x_0 = px/half - 2
For py = 1 To size
y_0 = py/half - 1
x = x_0
y = y_0
i = 0
While(c <= 2 AND i<100)
x_1 = Math.Power(x, 2) - Math.Power(y, 2) + x_0
y_1 = 2 * x * y + y_0
c = Math.Power(Math.Power(x_1, 2) + Math.Power(y_1, 2), 0.5)
x = x_1
y = y_1
i = i + 1
EndWhile
If i < 99 Then
GraphicsWindow.SetPixel(px, py, GraphicsWindow.GetColorFromRGB((255/25)*i, (255/25)*i, (255/5)*i))
Else
GraphicsWindow.SetPixel(px, py, "black")
EndIf
c=0
EndFor
EndFor
 

[edit] Brace

This is a simple Mandelbrot plotter. A longer version based on this smooths colors, and avoids calculating the time-consuming black pixels: http://sam.ai.ki/brace/examples/mandelbrot.d/1

#!/usr/bin/env bx
use b
 
Main():
num outside = 16, ox = -0.5, oy = 0, r = 1.5
long i, max_i = 100, rb_i = 30
space()
uint32_t *px = pixel()
num d = 2*r/h, x0 = ox-d*w_2, y0 = oy+d*h_2
for(y, 0, h):
cmplx c = x0 + (y0-d*y)*I
repeat(w):
cmplx w = 0
for i=0; i < max_i && cabs(w) < outside; ++i
w = w*w + c
*px++ = i < max_i ? rainbow(i*359 / rb_i % 360) : black
c += d

An example plot from the longer version:

Brace-mandelbrot-small.png

[edit] C

[edit] PPM non interactive

Here is one file program. It directly creates ppm file.

 /* 
c program:
--------------------------------
1. draws Mandelbrot set for Fc(z)=z*z +c
using Mandelbrot algorithm ( boolean escape time )
-------------------------------
2. technique of creating ppm file is based on the code of Claudio Rocchini
http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg
create 24 bit color graphic file , portable pixmap file = PPM
see http://en.wikipedia.org/wiki/Portable_pixmap
to see the file use external application ( graphic viewer)
*/

#include <stdio.h>
int main()
{
/* screen ( integer) coordinate */
int iX,iY;
const int iXmax = 800;
const int iYmax = 800;
/* world ( double) coordinate = parameter plane*/
double Cx,Cy;
const double CxMin=-2.5;
const double CxMax=1.5;
const double CyMin=-2.0;
const double CyMax=2.0;
/* */
double PixelWidth=(CxMax-CxMin)/iXmax;
double PixelHeight=(CyMax-CyMin)/iYmax;
/* color component ( R or G or B) is coded from 0 to 255 */
/* it is 24 bit color RGB file */
const int MaxColorComponentValue=255;
FILE * fp;
char *filename="new1.ppm";
char *comment="# ";/* comment should start with # */
static unsigned char color[3];
/* Z=Zx+Zy*i  ; Z0 = 0 */
double Zx, Zy;
double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */
/* */
int Iteration;
const int IterationMax=200;
/* bail-out value , radius of circle ; */
const double EscapeRadius=2;
double ER2=EscapeRadius*EscapeRadius;
/*create new file,give it a name and open it in binary mode */
fp= fopen(filename,"wb"); /* b - binary mode */
/*write ASCII header to the file*/
fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue);
/* compute and write image data bytes to the file*/
for(iY=0;iY<iYmax;iY++)
{
Cy=CyMin + iY*PixelHeight;
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
for(iX=0;iX<iXmax;iX++)
{
Cx=CxMin + iX*PixelWidth;
/* initial value of orbit = critical point Z= 0 */
Zx=0.0;
Zy=0.0;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
/* */
for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
{
Zy=2*Zx*Zy + Cy;
Zx=Zx2-Zy2 +Cx;
Zx2=Zx*Zx;
Zy2=Zy*Zy;
};
/* compute pixel color (24 bit = 3 bytes) */
if (Iteration==IterationMax)
{ /* interior of Mandelbrot set = black */
color[0]=0;
color[1]=0;
color[2]=0;
}
else
{ /* exterior of Mandelbrot set = white */
color[0]=255; /* Red*/
color[1]=255; /* Green */
color[2]=255;/* Blue */
};
/*write color to the file*/
fwrite(color,1,3,fp);
}
}
fclose(fp);
return 0;
}

[edit] PPM Interactive

Mandel-C-GL.png

Infinitely zoomable OpenGL program. Adjustable colors, max iteration, black and white, screen dump, etc. Compile with gcc mandelbrot.c -lglut -lGLU -lGL -lm

  • OpenBSD users, install freeglut package, and compile with make mandelbrot CPPFLAGS='-I/usr/local/include `pkg-config glu --cflags`' LDLIBS='-L/usr/local/lib -lglut `pkg-config glu --libs` -lm'
Library: GLUT
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
 
void set_texture();
 
typedef struct {unsigned char r, g, b;} rgb_t;
rgb_t **tex = 0;
int gwin;
GLuint texture;
int width, height;
int tex_w, tex_h;
double scale = 1./256;
double cx = -.6, cy = 0;
int color_rotate = 0;
int saturation = 1;
int invert = 0;
int max_iter = 256;
 
void render()
{
double x = (double)width /tex_w,
y = (double)height/tex_h;
 
glClear(GL_COLOR_BUFFER_BIT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
glBindTexture(GL_TEXTURE_2D, texture);
 
glBegin(GL_QUADS);
 
glTexCoord2f(0, 0); glVertex2i(0, 0);
glTexCoord2f(x, 0); glVertex2i(width, 0);
glTexCoord2f(x, y); glVertex2i(width, height);
glTexCoord2f(0, y); glVertex2i(0, height);
 
glEnd();
 
glFlush();
glFinish();
}
 
int dump = 1;
void screen_dump()
{
char fn[100];
int i;
sprintf(fn, "screen%03d.ppm", dump++);
FILE *fp = fopen(fn, "w");
fprintf(fp, "P6\n%d %d\n255\n", width, height);
for (i = height - 1; i >= 0; i--)
fwrite(tex[i], 1, width * 3, fp);
fclose(fp);
printf("%s written\n", fn);
}
 
void keypress(unsigned char key, int x, int y)
{
switch(key) {
case 'q': glFinish();
glutDestroyWindow(gwin);
return;
case 27: scale = 1./256; cx = -.6; cy = 0; break;
 
case 'r': color_rotate = (color_rotate + 1) % 6;
break;
 
case '>': case '.':
max_iter += 128;
if (max_iter > 1 << 15) max_iter = 1 << 15;
printf("max iter: %d\n", max_iter);
break;
 
case '<': case ',':
max_iter -= 128;
if (max_iter < 128) max_iter = 128;
printf("max iter: %d\n", max_iter);
break;
 
case 'c': saturation = 1 - saturation;
break;
 
case 's': screen_dump(); return;
case 'z': max_iter = 4096; break;
case 'x': max_iter = 128; break;
case ' ': invert = !invert;
}
set_texture();
}
 
void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
{
if (min == max) max = min + 1;
if (invert) hue = max - (hue - min);
if (!saturation) {
p->r = p->g = p->b = 255 * (max - hue) / (max - min);
return;
}
double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
# define VAL 255
double c = VAL * saturation;
double X = c * (1 - fabs(fmod(h, 2) - 1));
 
p->r = p->g = p->b = 0;
 
switch((int)h) {
case 0: p->r = c; p->g = X; return;
case 1: p->r = X; p->g = c; return;
case 2: p->g = c; p->b = X; return;
case 3: p->g = X; p->b = c; return;
case 4: p->r = X; p->b = c; return;
default:p->r = c; p->b = X;
}
}
 
void calc_mandel()
{
int i, j, iter, min, max;
rgb_t *px;
double x, y, zx, zy, zx2, zy2;
min = max_iter; max = 0;
for (i = 0; i < height; i++) {
px = tex[i];
y = (i - height/2) * scale + cy;
for (j = 0; j < width; j++, px++) {
x = (j - width/2) * scale + cx;
iter = 0;
 
zx = hypot(x - .25, y);
if (x < zx - 2 * zx * zx + .25) iter = max_iter;
if ((x + 1)*(x + 1) + y * y < 1/16) iter = max_iter;
 
zx = zy = zx2 = zy2 = 0;
for (; iter < max_iter && zx2 + zy2 < 4; iter++) {
zy = 2 * zx * zy + y;
zx = zx2 - zy2 + x;
zx2 = zx * zx;
zy2 = zy * zy;
}
if (iter < min) min = iter;
if (iter > max) max = iter;
*(unsigned short *)px = iter;
}
}
 
for (i = 0; i < height; i++)
for (j = 0, px = tex[i]; j < width; j++, px++)
hsv_to_rgb(*(unsigned short*)px, min, max, px);
}
 
void alloc_tex()
{
int i, ow = tex_w, oh = tex_h;
 
for (tex_w = 1; tex_w < width; tex_w <<= 1);
for (tex_h = 1; tex_h < height; tex_h <<= 1);
 
if (tex_h != oh || tex_w != ow)
tex = realloc(tex, tex_h * tex_w * 3 + tex_h * sizeof(rgb_t*));
 
for (tex[0] = (rgb_t *)(tex + tex_h), i = 1; i < tex_h; i++)
tex[i] = tex[i - 1] + tex_w;
}
 
void set_texture()
{
alloc_tex();
calc_mandel();
 
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_w, tex_h,
0, GL_RGB, GL_UNSIGNED_BYTE, tex[0]);
 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
render();
}
 
void mouseclick(int button, int state, int x, int y)
{
if (state != GLUT_UP) return;
 
cx += (x - width / 2) * scale;
cy -= (y - height/ 2) * scale;
 
switch(button) {
case GLUT_LEFT_BUTTON: /* zoom in */
if (scale > fabs(x) * 1e-16 && scale > fabs(y) * 1e-16)
scale /= 2;
break;
case GLUT_RIGHT_BUTTON: /* zoom out */
scale *= 2;
break;
/* any other button recenters */
}
set_texture();
}
 
 
void resize(int w, int h)
{
printf("resize %d %d\n", w, h);
width = w;
height = h;
 
glViewport(0, 0, w, h);
glOrtho(0, w, 0, h, -1, 1);
 
set_texture();
}
 
void init_gfx(int *c, char **v)
{
glutInit(c, v);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(640, 480);
glutDisplayFunc(render);
 
gwin = glutCreateWindow("Mandelbrot");
 
glutKeyboardFunc(keypress);
glutMouseFunc(mouseclick);
glutReshapeFunc(resize);
glGenTextures(1, &texture);
set_texture();
}
 
int main(int c, char **v)
{
init_gfx(&c, v);
printf("keys:\n\tr: color rotation\n\tc: monochrome\n\ts: screen dump\n\t"
"<, >: decrease/increase max iteration\n\tq: quit\n\tmouse buttons to zoom\n");
 
glutMainLoop();
return 0;
}

[edit] C++

This generic function assumes that the image can be accessed like a two-dimensional array of colors. It may be passed a true array (in which case the Mandelbrot set will simply be drawn into that array, which then might be saved as image file), or a class which maps the subscript operator to the pixel drawing routine of some graphics library. In the latter case, there must be functions get_first_dimension and get_second_dimension defined for that type, to be found by argument dependent lookup. The code provides those functions for built-in arrays.

#include <cstdlib>
#include <complex>
 
// get dimensions for arrays
template<typename ElementType, std::size_t dim1, std::size_t dim2>
std::size_t get_first_dimension(ElementType (&a)[dim1][dim2])
{
return dim1;
}
 
template<typename ElementType, std::size_t dim1, std::size_t dim2>
std::size_t get_second_dimension(ElementType (&a)[dim1][dim2])
{
return dim2;
}
 
 
template<typename ColorType, typename ImageType>
void draw_Mandelbrot(ImageType& image, //where to draw the image
ColorType set_color, ColorType non_set_color, //which colors to use for set/non-set points
double cxmin, double cxmax, double cymin, double cymax,//the rect to draw in the complex plane
unsigned int max_iterations) //the maximum number of iterations
{
std::size_t const ixsize = get_first_dimension(ImageType);
std::size_t const iysize = get_first_dimension(ImageType);
for (std::size_t ix = 0; ix < ixsize; ++ix)
for (std::size_t iy = 0; iy < iysize; ++iy)
{
std::complex<double> c(cxmin + ix/(ixsize-1.0)*(cxmax-cxmin), cymin + iy/(iysize-1.0)*(cymax-cymin));
std::complex<double> z = 0;
unsigned int iterations;
 
for (iterations = 0; iterations < max_iterations && std::abs(z) < 2.0; ++iterations)
z = z*z + c;
 
image[ix][iy] = (iterations == max_iterations) ? set_color : non_set_color;
 
}
}

[edit] C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
 
/// <summary>
/// Generates bitmap of Mandelbrot Set and display it on the form.
/// </summary>
public class MandelbrotSetForm : Form
{
const double MaxValueExtent = 2.0;
Thread thread;
 
static double CalcMandelbrotSetColor(ComplexNumber c)
{
// from http://en.wikipedia.org/w/index.php?title=Mandelbrot_set
const int MaxIterations = 1000;
const double MaxNorm = MaxValueExtent * MaxValueExtent;
 
int iteration = 0;
ComplexNumber z = new ComplexNumber();
do
{
z = z * z + c;
iteration++;
} while (z.Norm() < MaxNorm && iteration < MaxIterations);
if (iteration < MaxIterations)
return (double)iteration / MaxIterations;
else
return 0; // black
}
 
static void GenerateBitmap(Bitmap bitmap)
{
double scale = 2 * MaxValueExtent / Math.Min(bitmap.Width, bitmap.Height);
for (int i = 0; i < bitmap.Height; i++)
{
double y = (bitmap.Height / 2 - i) * scale;
for (int j = 0; j < bitmap.Width; j++)
{
double x = (j - bitmap.Width / 2) * scale;
double color = CalcMandelbrotSetColor(new ComplexNumber(x, y));
bitmap.SetPixel(j, i, GetColor(color));
}
}
}
 
static Color GetColor(double value)
{
const double MaxColor = 256;
const double ContrastValue = 0.2;
return Color.FromArgb(0, 0,
(int)(MaxColor * Math.Pow(value, ContrastValue)));
}
 
public MandelbrotSetForm()
{
// form creation
this.Text = "Mandelbrot Set Drawing";
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.MaximizeBox = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.ClientSize = new Size(640, 640);
this.Load += new System.EventHandler(this.MainForm_Load);
}
 
void MainForm_Load(object sender, EventArgs e)
{
thread = new Thread(thread_Proc);
thread.IsBackground = true;
thread.Start(this.ClientSize);
}
 
void thread_Proc(object args)
{
// start from small image to provide instant display for user
Size size = (Size)args;
int width = 16;
while (width * 2 < size.Width)
{
int height = width * size.Height / size.Width;
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
GenerateBitmap(bitmap);
this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), bitmap);
width *= 2;
Thread.Sleep(200);
}
// then generate final image
Bitmap finalBitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format24bppRgb);
GenerateBitmap(finalBitmap);
this.BeginInvoke(new SetNewBitmapDelegate(SetNewBitmap), finalBitmap);
}
 
void SetNewBitmap(Bitmap image)
{
if (this.BackgroundImage != null)
this.BackgroundImage.Dispose();
this.BackgroundImage = image;
}
 
delegate void SetNewBitmapDelegate(Bitmap image);
 
static void Main()
{
Application.Run(new MandelbrotSetForm());
}
}
 
struct ComplexNumber
{
public double Re;
public double Im;
 
public ComplexNumber(double re, double im)
{
this.Re = re;
this.Im = im;
}
 
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
{
return new ComplexNumber(x.Re + y.Re, x.Im + y.Im);
}
 
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
{
return new ComplexNumber(x.Re * y.Re - x.Im * y.Im,
x.Re * y.Im + x.Im * y.Re);
}
 
public double Norm()
{
return Re * Re + Im * Im;
}
}

[edit] Clojure

Translation of: Perl
(ns mandelbrot
(:refer-clojure :exclude [+ * <])
(:use (clojure.contrib complex-numbers)
(clojure.contrib.generic [arithmetic :only [+ *]]
[comparison :only [<]]
[math-functions :only [abs]])))
(defn mandelbrot? [z]
(loop [c 1
m (iterate #(+ z (* % %)) 0)]
(if (and (> 20 c)
(< (abs (first m)) 2) )
(recur (inc c)
(rest m))
(if (= 20 c) true false))))
 
(defn mandelbrot []
(for [y (range 1 -1 -0.05)
x (range -2 0.5 0.0315)]
(if (mandelbrot? (complex x y)) "#" " ")))
 
(println (interpose \newline (map #(apply str %) (partition 80 (mandelbrot)))))
 

[edit] D

[edit] Textual Version

This uses std.complex because D built-in complex numbers are deprecated.

void main() {
import std.stdio, std.complex;
 
for (real y = -1.2; y < 1.2; y += 0.05) {
for (real x = -2.05; x < 0.55; x += 0.03) {
auto z = 0.complex;
foreach (_; 0 .. 100)
z = z ^^ 2 + complex(x, y);
write(z.abs < 2 ? '#' : '.');
}
writeln;
}
}
Output:
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
................................................................##.....................
.............................................................######....................
.............................................................#######...................
..............................................................######...................
..........................................................#.#.###..#.#.................
...................................................##....################..............
..................................................###.######################.###.......
...................................................############################........
................................................###############################........
................................................################################.......
.............................................#####################################.....
..............................................###################################......
..............................##.####.#......####################################......
..............................###########....####################################......
............................###############.######################################.....
............................###############.#####################################......
........................##.#####################################################.......
......#.#####################################################################..........
........................##.#####################################################.......
............................###############.#####################################......
............................###############.######################################.....
..............................###########....####################################......
..............................##.####.#......####################################......
..............................................###################################......
.............................................#####################################.....
................................................################################.......
................................................###############################........
...................................................############################........
..................................................###.######################.###.......
...................................................##....################..............
..........................................................#.#.###..#.#.................
..............................................................######...................
.............................................................#######...................
.............................................................######....................
................................................................##.....................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................
.......................................................................................

[edit] More Functional Textual Version

The output is similar.

void main() {
import std.stdio, std.complex, std.range, std.algorithm;
 
foreach (immutable y; iota(-1.2, 1.2, 0.05))
iota(-2.05, 0.55, 0.03).map!(x => 0.complex
.recurrence!((a, n) => a[n - 1] ^^ 2 + complex(x, y))
.drop(100).front.abs < 2 ? '#' : '.').writeln;
}

[edit] Graphical Version

Library: QD
Library: SDL
Library: Phobos
import qd;
 
double lensqr(cdouble c) { return c.re * c.re + c.im * c.im; }
 
const Limit = 150;
 
void main() {
screen(640, 480);
for (int y = 0; y < screen.h; ++y) {
flip; events;
for (int x = 0; x < screen.w; ++x) {
auto
c_x = x * 1.0 / screen.w - 0.5,
c_y = y * 1.0 / screen.h - 0.5,
c = c_y * 2.0i + c_x * 3.0 - 1.0,
z = 0.0i + 0.0,
i = 0;
for (; i < Limit; ++i) {
z = z * z + c;
if (lensqr(z) > 4) break;
}
auto value = cast(ubyte) (i * 255.0 / Limit);
pset(x, y, rgb(value, value, value));
}
}
while (true) { flip; events; }
}

[edit] Dart

Implementation in Google Dart works on http://try.dartlang.org/ (as of 10/18/2011) since the language is very new, it may break in the future. The implementation uses a incomplete Complex class supporting operator overloading.

class Complex {
double _r,_i;
 
Complex(this._r,this._i);
double get r() => _r;
double get i() => _i;
String toString() => "($r,$i)";
 
Complex operator +(Complex other) => new Complex(r+other.r,i+other.i);
Complex operator *(Complex other) =>
new Complex(r*other.r-i*other.i,r*other.i+other.r*i);
double abs() => r*r+i*i;
}
 
void main() {
double start_x=-1.5;
double start_y=-1.0;
double step_x=0.03;
double step_y=0.1;
 
for(int y=0;y<20;y++) {
String line="";
for(int x=0;x<70;x++) {
Complex c=new Complex(start_x+step_x*x,start_y+step_y*y);
Complex z=new Complex(0,0);
for(int i=0;i<100;i++) {
z=z*(z)+c;
if(z.abs()>2) {
break;
}
}
line+=z.abs()>2 ? " " : "*";
}
print(line);
}
}

[edit] DEC BASIC-PLUS

Works under RSTS/E v7.0 on the simh PDP-11 emulator. For installation procedures for RSTS/E, see here.

10 X1=59\Y1=21
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1
40 FOR Y=0 TO Y1
50 I3=I1+S2*Y
60 FOR X=0 TO X1
70 R3=R1+S1*X\Z1=R3\Z2=I3
80 FOR N=0 TO 30
90 A=Z1*Z1\B=Z2*Z2
100 IF A+B>4.0 THEN GOTO 130
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3
120 NEXT N
130 PRINT STRING$(1%,62%-N);
140 NEXT X
150 PRINT
160 NEXT Y
170 END
 
Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<========
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<=======
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<=====
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<====
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<===
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<==
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<=
><;;;;;;::::9875&      .3                       *9;;;<<<<<<=
>;;;;;;::997564'        '                       8:;;;<<<<<<=
>::988897735/                                 &89:;;;<<<<<<=
>::988897735/                                 &89:;;;<<<<<<=
>;;;;;;::997564'        '                       8:;;;<<<<<<=
><;;;;;;::::9875&      .3                       *9;;;<<<<<<=
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<=
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<==
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<===
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<====
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<=====
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<=======
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<========
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========

[edit] DWScript

Translation of: D
const maxIter = 256;
 
var x, y, i : Integer;
for y:=-39 to 39 do begin
for x:=-39 to 39 do begin
var c := Complex(y/40-0.5, x/40);
var z := Complex(0, 0);
for i:=1 to maxIter do begin
z := z*z + c;
if Abs(z)>=4 then Break;
end;
if i>=maxIter then
Print('#')
else Print('.');
end;
PrintLn('');
end;

[edit] F#

open System.Drawing 
open System.Windows.Forms
type Complex =
{
re : float;
im : float
}
let cplus (x:Complex) (y:Complex) : Complex =
{
re = x.re + y.re;
im = x.im + y.im
}
let cmult (x:Complex) (y:Complex) : Complex =
{
re = x.re * y.re - x.im * y.im;
im = x.re * y.im + x.im * y.re;
}
 
let norm (x:Complex) : float =
x.re*x.re + x.im*x.im
 
type Mandel = class
inherit Form
static member xPixels = 500
static member yPixels = 500
val mutable bmp : Bitmap
member x.mandelbrot xMin xMax yMin yMax maxIter =
let rec mandelbrotIterator z c n =
if (norm z) > 2.0 then false else
match n with
| 0 -> true
| n -> let z' = cplus ( cmult z z ) c in
mandelbrotIterator z'
c (n-1)
let dx = (xMax - xMin) / (float (Mandel.xPixels))
let dy = (yMax - yMin) / (float (Mandel.yPixels))
in
for xi = 0 to Mandel.xPixels-1 do
for yi = 0 to Mandel.yPixels-1 do
let c = {re = xMin + (dx * float(xi) ) ;
im = yMin + (dy * float(yi) )} in
if (mandelbrotIterator {re=0.;im=0.;} c maxIter) then
x.bmp.SetPixel(xi,yi,Color.Azure)
else
x.bmp.SetPixel(xi,yi,Color.Black)
done
done
 
member public x.generate () = x.mandelbrot (-1.5) 0.5 (-1.0) 1.0 200 ; x.Refresh()
 
new() as x = {bmp = new Bitmap(Mandel.xPixels , Mandel.yPixels)} then
x.Text <- "Mandelbrot set" ;
x.Width <- Mandel.xPixels ;
x.Height <- Mandel.yPixels ;
x.BackgroundImage <- x.bmp;
x.generate();
x.Show();
end
 
let f = new Mandel()
do Application.Run(f)

[edit] Forth

This uses grayscale image utilities.

500 value max-iter
 
: mandel ( gmp F: imin imax rmin rmax -- )
0e 0e { F: imin F: imax F: rmin F: rmax F: Zr F: Zi }
dup bheight 0 do
i s>f dup bheight s>f f/ imax imin f- f* imin f+ TO Zi
dup bwidth 0 do
i s>f dup bwidth s>f f/ rmax rmin f- f* rmin f+ TO Zr
Zr Zi max-iter
begin 1- dup
while fover fdup f* fover fdup f*
fover fover f+ 4e f<
while f- Zr f+
frot frot f* 2e f* Zi f+
repeat fdrop fdrop
drop 0 \ for a pretty grayscale image, replace with: 255 max-iter */
else drop 255
then fdrop fdrop
over i j rot g!
loop
loop drop ;
 
80 24 graymap
dup -1e 1e -2e 1e mandel
dup gshow
free bye

[edit] Fortran

Works with: Fortran version 90 and later
program mandelbrot
 
implicit none
integer , parameter :: rk = selected_real_kind (9, 99)
integer , parameter :: i_max = 800
integer , parameter :: j_max = 600
integer , parameter :: n_max = 100
real (rk), parameter :: x_centre = -0.5_rk
real (rk), parameter :: y_centre = 0.0_rk
real (rk), parameter :: width = 4.0_rk
real (rk), parameter :: height = 3.0_rk
real (rk), parameter :: dx_di = width / i_max
real (rk), parameter :: dy_dj = -height / j_max
real (rk), parameter :: x_offset = x_centre - 0.5_rk * (i_max + 1) * dx_di
real (rk), parameter :: y_offset = y_centre - 0.5_rk * (j_max + 1) * dy_dj
integer, dimension (i_max, j_max) :: image
integer :: i
integer :: j
integer :: n
real (rk) :: x
real (rk) :: y
real (rk) :: x_0
real (rk) :: y_0
real (rk) :: x_sqr
real (rk) :: y_sqr
 
do j = 1, j_max
y_0 = y_offset + dy_dj * j
do i = 1, i_max
x_0 = x_offset + dx_di * i
x = 0.0_rk
y = 0.0_rk
n = 0
do
x_sqr = x ** 2
y_sqr = y ** 2
if (x_sqr + y_sqr > 4.0_rk) then
image (i, j) = 255
exit
end if
if (n == n_max) then
image (i, j) = 0
exit
end if
y = y_0 + 2.0_rk * x * y
x = x_0 + x_sqr - y_sqr
n = n + 1
end do
end do
end do
open (10, file = 'out.pgm')
write (10, '(a/ i0, 1x, i0/ i0)') 'P2', i_max, j_max, 255
write (10, '(i0)') image
close (10)
 
end program mandelbrot

[edit] GLSL

This example works directly on Shadertoy link[1]

void main(void)
{
vec2 uv = gl_FragCoord.xy / iResolution.xy;
float scale = iResolution.y / iResolution.x;
uv=((uv-0.5)*5.5);
uv.y*=scale;
uv.y+=0.0;
uv.x-=0.5;
 
 
vec2 z = vec2(0.0, 0.0);
vec3 c = vec3(0.0, 0.0, 0.0);
float v;
 
for(int i=0;(i<170);i++)
{
 
if(((z.x*z.x+z.y*z.y) >= 4.0)) break;
z = vec2(z.x*z.x - z.y*z.y, 2.0*z.y*z.x) + uv;
 
 
if((z.x*z.x+z.y*z.y) >= 2.0)
{
c.b=float(i)/20.0;
c.r=sin((float(i)/5.0));
}
 
}
 
 
gl_FragColor = vec4(c,1.0);
}

[edit] gnuplot

The output from gnuplot is controlled by setting the appropriate values for the options terminal and output.

set terminal png
set output 'mandelbrot.png'

The following script draws an image of the number of iterations it takes to escape the circle with radius rmax with a maximum of nmax.

rmax = 2
nmax = 100
complex (x, y) = x * {1, 0} + y * {0, 1}
mandelbrot (z, z0, n) = n == nmax || abs (z) > rmax ? n : mandelbrot (z ** 2 + z0, z0, n + 1)
set samples 200
set isosamples 200
set pm3d map
set size square
splot [-2 : .8] [-1.4 : 1.4] mandelbrot (complex (0, 0), complex (x, y), 0) notitle
Output:

Mandelbrot.png

[edit] Go

Text

Prints an 80-char by 41-line depiction.

package main
 
import "fmt"
import "math/cmplx"
 
func mandelbrot(a complex128) (z complex128) {
for i := 0; i < 50; i++ {
z = z*z + a
}
return
}
 
func main() {
for y := 1.0; y >= -1.0; y -= 0.05 {
for x := -2.0; x <= 0.5; x += 0.0315 {
if cmplx.Abs(mandelbrot(complex(x, y))) < 2 {
fmt.Print("*")
} else {
fmt.Print(" ")
}
}
fmt.Println("")
}
}
Graphical
.png image
package main
 
import (
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"math/cmplx"
"os"
)
 
const (
maxEsc = 100
rMin = -2.
rMax = .5
iMin = -1.
iMax = 1.
width = 750
red = 230
green = 235
blue = 255
)
 
func mandelbrot(a complex128) float64 {
i := 0
for z := a; cmplx.Abs(z) < 2 && i < maxEsc; i++ {
z = z*z + a
}
return float64(maxEsc-i) / maxEsc
}
 
func main() {
scale := width / (rMax - rMin)
height := int(scale * (iMax - iMin))
bounds := image.Rect(0, 0, width, height)
b := image.NewNRGBA(bounds)
draw.Draw(b, bounds, image.NewUniform(color.Black), image.ZP, draw.Src)
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
fEsc := mandelbrot(complex(
float64(x)/scale+rMin,
float64(y)/scale+iMin))
b.Set(x, y, color.NRGBA{uint8(red * fEsc),
uint8(green * fEsc), uint8(blue * fEsc), 255})
 
}
}
f, err := os.Create("mandelbrot.png")
if err != nil {
fmt.Println(err)
return
}
if err = png.Encode(f, b); err != nil {
fmt.Println(err)
}
if err = f.Close(); err != nil {
fmt.Println(err)
}
}

[edit] Haskell

Translation of: Ruby
import Data.Complex
 
mandelbrot a = iterate (\z -> z^2 + a) 0 !! 50
 
main = mapM_ putStrLn [[if magnitude (mandelbrot (x :+ y)) < 2 then '*' else ' '
| x <- [-2, -1.9685 .. 0.5]]
| y <- [1, 0.95 .. -1]]

Save the code to file m.hs and run :

runhaskell m.hs

[edit] Haxe

This version compiles for flash version 9 or greater. The compilation command is

haxe -swf mandelbrot.swf -main Mandelbrot
class Mandelbrot extends flash.display.Sprite
{
inline static var MAX_ITER = 255;
 
public static function main() {
var w = flash.Lib.current.stage.stageWidth;
var h = flash.Lib.current.stage.stageHeight;
var mandelbrot = new Mandelbrot(w, h);
flash.Lib.current.stage.addChild(mandelbrot);
mandelbrot.drawMandelbrot();
}
 
var image:flash.display.BitmapData;
public function new(width, height) {
super();
var bitmap:flash.display.Bitmap;
image = new flash.display.BitmapData(width, height, false);
bitmap = new flash.display.Bitmap(image);
this.addChild(bitmap);
}
 
public function drawMandelbrot() {
image.lock();
var step_x = 3.0 / (image.width-1);
var step_y = 2.0 / (image.height-1);
for (i in 0...image.height) {
var ci = i * step_y - 1.0;
for (j in 0...image.width) {
var k = 0;
var zr = 0.0;
var zi = 0.0;
var cr = j * step_x - 2.0;
while (k <= MAX_ITER && (zr*zr + zi*zi) <= 4) {
var temp = zr*zr - zi*zi + cr;
zi = 2*zr*zi + ci;
zr = temp;
k ++;
}
paint(j, i, k);
}
}
image.unlock();
}
 
inline function paint(x, y, iter) {
var color = iter > MAX_ITER? 0 : iter * 0x100;
image.setPixel(x, y, color);
}
}

[edit] Icon and Unicon

link graphics
 
procedure main()
width := 750
height := 600
limit := 100
WOpen("size="||width||","||height)
every x:=1 to width & y:=1 to height do
{
z:=complex(0,0)
c:=complex(2.5*x/width-2.0,(2.0*y/height-1.0))
j:=0
while j<limit & cAbs(z)<2.0 do
{
z := cAdd(cMul(z,z),c)
j+:= 1
}
Fg(mColor(j,limit))
DrawPoint(x,y)
}
WriteImage("./mandelbrot.gif")
WDone()
end
 
procedure mColor(x,limit)
max_color := 2^16-1
color := integer(max_color*(real(x)/limit))
 
return(if x=limit
then "black"
else color||","||color||",0")
end
 
record complex(r,i)
 
procedure cAdd(x,y)
return complex(x.r+y.r,x.i+y.i)
end
 
procedure cMul(x,y)
return complex(x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r)
end
 
procedure cAbs(x)
return sqrt(x.r*x.r+x.i*x.i)
end

graphics is required


This example is in need of improvement:
The example is correct; however, Unicon implemented additional graphical features and a better example may be possible.

[edit] IDL

IDL - Interactive Data Language (free implementation: GDL - GNU Data Language http://gnudatalanguage.sourceforge.net)

 
PRO Mandelbrot,xRange,yRange,xPixels,yPixels,iterations
 
xPixelstartVec = Lindgen( xPixels) * Float(xRange[1]-xRange[0]) / $
xPixels + xRange[0]
yPixelstartVec = Lindgen( yPixels) * Float(YRANGE[1]-yrange[0])$
/ yPixels + yRange[0]
 
constArr = Complex( Rebin( xPixelstartVec, xPixels, yPixels),$
Rebin( Transpose(yPixelstartVec), xPixels, yPixels))
 
valArr = ComplexArr( xPixels, yPixels)
 
res = IntArr( xPixels, yPixels)
 
oriIndex = Lindgen( Long(xPixels) * yPixels)
 
FOR i = 0, iterations-1 DO BEGIN ; only one loop needed
 
; calculation for whole array at once
valArr = valArr^2 - constArr
 
whereIn = Where( Abs( valArr) LE 4.0d, COMPLEMENT=whereOut)
 
IF whereIn[0] EQ -1 THEN BREAK
 
valArr = valArr[ whereIn]
 
constArr = constArr[ whereIn]
 
IF whereOut[0] NE -1 THEN BEGIN
 
res[ oriIndex[ whereOut]] = i+1
 
oriIndex = oriIndex[ whereIn]
ENDIF
ENDFOR
 
tv,res ; open a window and show the result
 
END
 
 
Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200
 
END
 
 

from the command line:

 
GDL>.run mandelbrot
 

or

 
GDL> Mandelbrot,[-1.,2.3],[-1.3,1.3],640,512,200
 

[edit] Inform 7

"Mandelbrot"
 
The story headline is "A Non-Interactive Set".
 
Include Glimmr Drawing Commands by Erik Temple.
 
[Q20 fixed-point or floating-point: see definitions below]
Use floating-point math.
 
Finished is a room.
 
The graphics-window is a graphics g-window spawned by the main-window.
The position is g-placeabove.
 
When play begins:
let f10 be 10 as float;
now min re is ( -20 as float ) fdiv f10;
now max re is ( 6 as float ) fdiv f10;
now min im is ( -12 as float ) fdiv f10;
now max im is ( 12 as float ) fdiv f10;
now max iterations is 100;
add color g-Black to the palette;
add color g-Red to the palette;
add hex "#FFA500" to the palette;
add color g-Yellow to the palette;
add color g-Green to the palette;
add color g-Blue to the palette;
add hex "#4B0082" to the palette;
add hex "#EE82EE" to the palette;
open up the graphics-window.
 
Min Re is a number that varies.
Max Re is a number that varies.
Min Im is a number that varies.
Max Im is a number that varies.
 
Max Iterations is a number that varies.
 
Min X is a number that varies.
Max X is a number that varies.
Min Y is a number that varies.
Max Y is a number that varies.
 
The palette is a list of numbers that varies.
 
[vertically mirrored version]
Window-drawing rule for the graphics-window when max im is fneg min im:
clear the graphics-window;
let point be { 0, 0 };
now min X is 0 as float;
now min Y is 0 as float;
let mX be the width of the graphics-window minus 1;
let mY be the height of the graphics-window minus 1;
now max X is mX as float;
now max Y is mY as float;
let L be the column order with max mX;
repeat with X running through L:
now entry 1 in point is X;
repeat with Y running from 0 to mY / 2:
now entry 2 in point is Y;
let the scaled point be the complex number corresponding to the point;
let V be the Mandelbrot result for the scaled point;
let C be the color corresponding to V;
if C is 0, next;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
now entry 2 in point is mY - Y;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
yield to VM;
rule succeeds.
 
[slower non-mirrored version]
Window-drawing rule for the graphics-window:
clear the graphics-window;
let point be { 0, 0 };
now min X is 0 as float;
now min Y is 0 as float;
let mX be the width of the graphics-window minus 1;
let mY be the height of the graphics-window minus 1;
now max X is mX as float;
now max Y is mY as float;
let L be the column order with max mX;
repeat with X running through L:
now entry 1 in point is X;
repeat with Y running from 0 to mY:
now entry 2 in point is Y;
let the scaled point be the complex number corresponding to the point;
let V be the Mandelbrot result for the scaled point;
let C be the color corresponding to V;
if C is 0, next;
draw a rectangle (C) in the graphics-window at the point with size 1 by 1;
yield to VM;
rule succeeds.
 
To decide which list of numbers is column order with max (N - number):
let L be a list of numbers;
let L2 be a list of numbers;
let D be 64;
let rev be false;
while D > 0:
let X be 0;
truncate L2 to 0 entries;
while X <= N:
if D is 64 or X / D is odd, add X to L2;
increase X by D;
if rev is true:
reverse L2;
let rev be false;
otherwise:
let rev be true;
add L2 to L;
let D be D / 2;
decide on L.
 
To decide which list of numbers is complex number corresponding to (P - list of numbers):
let R be a list of numbers;
extend R to 2 entries;
let X be entry 1 in P as float;
let X be (max re fsub min re) fmul (X fdiv max X);
let X be X fadd min re;
let Y be entry 2 in P as float;
let Y be (max im fsub min im) fmul (Y fdiv max Y);
let Y be Y fadd min im;
now entry 1 in R is X;
now entry 2 in R is Y;
decide on R.
 
To decide which number is Mandelbrot result for (P - list of numbers):
let c_re be entry 1 in P;
let c_im be entry 2 in P;
let z_re be 0 as float;
let z_im be z_re;
let threshold be 4 as float;
let runs be 0;
while 1 is 1:
[ z = z * z ]
let r2 be z_re fmul z_re;
let i2 be z_im fmul z_im;
let ri be z_re fmul z_im;
let z_re be r2 fsub i2;
let z_im be ri fadd ri;
[ z = z + c ]
let z_re be z_re fadd c_re;
let z_im be z_im fadd c_im;
let norm be (z_re fmul z_re) fadd (z_im fmul z_im);
increase runs by 1;
if norm is greater than threshold, decide on runs;
if runs is max iterations, decide on 0.
 
To decide which number is color corresponding to (V - number):
let L be the number of entries in the palette;
let N be the remainder after dividing V by L;
decide on entry (N + 1) in the palette.
 
Section - Fractional numbers (for Glulx only)
 
To decide which number is (N - number) as float: (- (numtof({N})) -).
To decide which number is (N - number) fadd (M - number): (- (fadd({N}, {M})) -).
To decide which number is (N - number) fsub (M - number): (- (fsub({N}, {M})) -).
To decide which number is (N - number) fmul (M - number): (- (fmul({N}, {M})) -).
To decide which number is (N - number) fdiv (M - number): (- (fdiv({N}, {M})) -).
To decide which number is fneg (N - number): (- (fneg({N})) -).
To yield to VM: (- glk_select_poll(gg_event); -).
 
Use Q20 fixed-point math translates as (- Constant Q20_MATH; -).
Use floating-point math translates as (- Constant FLOAT_MATH; -).
 
Include (-
#ifdef Q20_MATH;
! Q11.20 format: 1 sign bit, 11 integer bits, 20 fraction bits
[ numtof n r; @shiftl n 20 r; return r; ];
[ fadd n m; return n+m; ];
[ fsub n m; return n-m; ];
[ fmul n m; n = n + $$1000000000; @sshiftr n 10 n; m = m + $$1000000000; @sshiftr m 10 m; return n * m; ];
[ fdiv n m; @sshiftr m 20 m; return n / m; ];
[ fneg n; return -n; ];
#endif;
 
#ifdef FLOAT_MATH;
[ numtof f; @"S2:400" f f; return f; ];
[ fadd n m; @"S3:416" n m n; return n; ];
[ fsub n m; @"S3:417" n m n; return n; ];
[ fmul n m; @"S3:418" n m n; return n; ];
[ fdiv n m; @"S3:419" n m n; return n; ];
[ fneg n; @bitxor n $80000000 n; return n; ];
#endif;
-).

Newer Glulx interpreters provide 32-bit floating-point operations, but this solution also supports fixed-point math which is more widely supported and accurate enough for a zoomed-out view. Inform 6 inclusions are used for the low-level math functions in either case. The rendering process is extremely slow, since the graphics system is not optimized for pixel-by-pixel drawing, so this solution includes an optimization for vertical symmetry (as in the default view) and also includes extra logic to draw the lines in a more immediately useful order.

Mandelbrot-Inform7.png

[edit] J

The characteristic function of the Mandelbrot can be defined as follows:

mcf=. (<: 2:)@|@(] ((*:@] + [)^:((<: 2:)@|@])^:1000) 0:) NB. 1000 iterations test

The Mandelbrot set can be drawn as follows:

domain=. |.@|:@({.@[ + ] *~ j./&i.&>/@+.@(1j1 + ] %~ -~/@[))&>/
 
load'graph'
viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.01 NB. Complex interval and resolution


A smaller version, based on a black&white implementation of viewmat (and paraphrased, from html markup to wiki markup), is shown here:

   viewmat mcf "0 @ domain (_2j_1 1j1) ; 0.1 NB. Complex interval and resolution

The output is HTML-heavy and can be found here (split out to make editing this page easier).

[edit] Java

Library: Swing
Library: AWT
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
 
public class Mandelbrot extends JFrame {
 
private final int MAX_ITER = 570;
private final double ZOOM = 150;
private BufferedImage I;
private double zx, zy, cX, cY, tmp;
 
public Mandelbrot() {
super("Mandelbrot Set");
setBounds(100, 100, 800, 600);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
I = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < getHeight(); y++) {
for (int x = 0; x < getWidth(); x++) {
zx = zy = 0;
cX = (x - 400) / ZOOM;
cY = (y - 300) / ZOOM;
int iter = MAX_ITER;
while (zx * zx + zy * zy < 4 && iter > 0) {
tmp = zx * zx - zy * zy + cX;
zy = 2.0 * zx * zy + cY;
zx = tmp;
iter--;
}
I.setRGB(x, y, iter | (iter << 8));
}
}
}
 
@Override
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
 
public static void main(String[] args) {
new Mandelbrot().setVisible(true);
}
}

[edit] JavaScript

Works with: Firefox version 3.5.11

This needs the canvas tag of HTML 5 (it will not run on IE8 and lower or old browsers).

 
function Mandeliter(cx, cy, maxiter)
{
var i;
var x = 0.0;
var y = 0.0;
for (i = 0; i < maxiter && x*x + y*y <= 4; ++i)
{
var tmp = 2*x*y;
x = x*x - y*y + cx;
y = tmp + cy;
}
return i;
}
 
function Mandelbrot()
{
var width = 900;
var height = 600;
var cd = document.getElementById('calcdata');
var xmin = parseFloat(cd.xmin.value);
var xmax = parseFloat(cd.xmax.value);
var ymin = parseFloat(cd.ymin.value);
var ymax = parseFloat(cd.ymax.value);
var iterations = parseInt(cd.iterations.value);
var ctx = document.getElementById('mandelimage').getContext("2d");
var img = ctx.getImageData(0, 0, width, height);
var pix = img.data;
for (var ix = 0; ix < width; ++ix)
for (var iy = 0; iy < height; ++iy)
{
var x = xmin + (xmax-xmin)*ix/(width-1);
var y = ymin + (ymax-ymin)*iy/(height-1);
var i = Mandeliter(x, y, iterations);
var ppos = 4*(900*iy + ix);
if (i == iterations)
{
pix[ppos] = 0;
pix[ppos+1] = 0;
pix[ppos+2] = 0;
}
else
{
var c = 3*Math.log(i)/Math.log(iterations - 1.0);
if (c < 1)
{
pix[ppos] = 255*c;
pix[ppos+1] = 0;
pix[ppos+2] = 0;
}
else if (c < 2)
{
pix[ppos] = 255;
pix[ppos+1] = 255*(c-1);
pix[ppos+2] = 0;
}
else
{
pix[ppos] = 255;
pix[ppos+1] = 255;
pix[ppos+2] = 255*(c-2);
}
}
pix[ppos+3] = 255;
}
ctx.putImageData(img,0,0);
}

The corresponding HTML:

 
<!DOCTYPE html>
<html>
<head>
<title>Mandelbrot set</title>
<script src="Mandelbrot.js" type="text/javascript"></script>
</head>
 
<body onload="Mandelbrot()">
<h1>Mandelbrot set</h1>
 
<form id="calcdata" onsubmit="javascript:Mandelbrot(); return false;">
<table>
<tr>
<td>xmin =</td>
<td><input name="xmin" type="text" size="10" value="-2"></td>
<td>xmax =</td>
<td><input name="xmax" type="text" size="10" value="1"></td>
</tr>
<tr>
<td>ymin =</td>
<td><input name="ymin" type="text" size="10" value="-1"></td>
<td>ymax =</td>
<td><input name="ymax" type="text" size="10" value="1"></td>
</tr>
</table>
<p>iterations =
<input name="iterations" type="text" size="10" value="1000"></p>
<p>
<input type="submit" value=" Calculate ">
<input type="reset" value=" Reset form ">
</p>
</form>
 
<canvas id="mandelimage" width="900" height="600">
This page needs a browser with canvas support.
</canvas>
</body>
</html>
 
Output:
with default parameters:

Mandelbrot-Javascript.png

[edit] Julia

 
function mandelbrot(a)
z = 0
for i=1:50
z = z^2 + a
end
return z
end
 
for y=1.0:-0.05:-1.0
for x=-2.0:0.0315:0.5
abs(mandelbrot(complex(x, y))) < 2 ? print("*") : print(" ")
end
println()
end
 

[edit] LabVIEW

Works with: LabVIEW version 8.0 Full Development Suite


Mandelbrot set diagram.png Mandelbrot set panel.png

[edit] Lang5

 
: d2c(*,*) 2 compress 'c dress ; # Make a complex number.
 
: iterate(c) [0 0](c) "dup * over +" steps reshape execute ;
 
: print_line(*) "#*+-. " "" split swap subscript "" join . "\n" . ;
 
75 iota 45 - 20 / # x coordinates
29 iota 14 - 10 / # y cordinates
'd2c outer # Make complex matrix.
 
10 'steps set # How many iterations?
 
iterate abs int 5 min 'print_line apply # Compute & print
 

[edit] Lasso

 
define mandelbrotBailout => 16
define mandelbrotMaxIterations => 1000
 
define mandelbrotIterate(x, y) => {
local(cr = #y - 0.5,
ci = #x,
zi = 0.0,
zr = 0.0,
i = 0,
temp, zr2, zi2)
 
{
++#i;
#temp = #zr * #zi
#zr2 = #zr * #zr
#zi2 = #zi * #zi
 
#zi2 + #zr2 > mandelbrotBailout?
return #i
#i > mandelbrotMaxIterations?
return 0
 
#zr = #zr2 - #zi2 + #cr
#zi = #temp + #temp + #ci
 
currentCapture->restart
}()
}
 
define mandelbrotTest() => {
local(x, y = -39.0)
{
stdout('\n')
#x = -39.0
{
mandelbrotIterate(#x / 40.0, #y / 40.0) == 0?
stdout('*')
| stdout(' ');
++#x
#x <= 39.0?
currentCapture->restart
}();
++#y
 
#y <= 39.0?
currentCapture->restart
}()
stdout('\n')
}
 
mandelbrotTest
 
Output:

                                       *                                       
                                       *                                       
                                       *                                       
                                       *                                       
                                       *                                       
                                      ***                                      
                                     *****                                     
                                     *****                                     
                                      ***                                      
                                       *                                       
                                   *********                                   
                                 *************                                 
                                ***************                                
                             *********************                             
                             *********************                             
                              *******************                              
                              *******************                              
                              *******************                              
                              *******************                              
                            ***********************                            
                              *******************                              
                              *******************                              
                             *********************                             
                              *******************                              
                              *******************                              
                               *****************                               
                                ***************                                
                                 *************                                 
                                   *********                                   
                                       *                                       
                                ***************                                
                            ***********************                            
                         * ************************* *                         
                         *****************************                         
                      * ******************************* *                      
                       *********************************                       
                      ***********************************                      
                    ***************************************                    
               *** ***************************************** ***               
               *************************************************               
                ***********************************************                
                 *********************************************                 
                 *********************************************                 
                ***********************************************                
                ***********************************************                
              ***************************************************              
               *************************************************               
               *************************************************               
              ***************************************************              
              ***************************************************              
         *    ***************************************************    *         
       *****  ***************************************************  *****       
       ****** *************************************************** ******       
      ******* *************************************************** *******      
    ***********************************************************************    
    ********* *************************************************** *********    
       ****** *************************************************** ******       
       *****  ***************************************************  *****       
              ***************************************************              
              ***************************************************              
              ***************************************************              
              ***************************************************              
               *************************************************               
               *************************************************               
              ***************************************************              
                ***********************************************                
                ***********************************************                
                  *******************************************                  
                   *****************************************                   
                 *********************************************                 
                **** ****************** ****************** ****                
                 ***  ****************   ****************  ***                 
                  *    **************     **************    *                  
                         ***********       ***********                         
                         **  *****           *****  **                         
                          *   *                 *   *                          

[edit] Liberty BASIC

Any words of description go outside of lang tags.

 
nomainwin
 
WindowWidth =440
WindowHeight =460
 
open "Mandelbrot Set" for graphics_nsb_nf as #w
 
#w "trapclose [quit]"
#w "down"
 
for x0 = -2 to 1 step .0033
for y0 = -1.5 to 1.5 step .0075
x = 0
y = 0
 
iteration = 0
maxIteration = 255
 
while ( ( x *x +y *y) <=4) and ( iteration <maxIteration)
xtemp =x *x -y *y +x0
y =2 *x *y +y0
x = xtemp
iteration = iteration + 1
wend
 
if iteration <>maxIteration then
c =iteration
else
c =0
end if
 
call pSet x0, y0, c
scan
next
next
 
#w "flush"
 
wait
 
sub pSet x, y, c
xScreen = 10 +( x +2) /3 *400
yScreen = 10 +( y +1.5) /3 *400
if c =0 then
col$ ="red"
else
if c mod 2 =1 then col$ ="lightgray" else col$ ="white"
end if
#w "color "; col$
#w "set "; xScreen; " "; yScreen
end sub
 
[quit]
close #w
end
 

[edit]

Works with: UCB Logo
to mandelbrot :left :bottom :side :size
cs setpensize [1 1]
make "inc :side/:size
make "zr :left
repeat :size [
make "zr :zr + :inc
make "zi :bottom
pu
setxy repcount - :size/2 minus :size/2
pd
repeat :size [
make "zi :zi + :inc
setpencolor count.color calc :zr :zi
fd 1 ] ]
end
 
to count.color :count
 ;op (list :count :count :count)
if :count > 256 [op 0] ; black
if :count > 128 [op 7] ; white
if :count > 64 [op 5] ; magenta
if :count > 32 [op 6] ; yellow
if :count > 16 [op 4] ; red
if :count > 8 [op 2] ; green
if :count > 4 [op 1] ; blue
op 3 ; cyan
end
 
to calc :zr :zi [:count 0] [:az 0] [:bz 0]
if :az*:az + :bz*:bz > 4 [op :count]
if :count > 256 [op :count]
op (calc :zr :zi (:count + 1) (:zr + :az*:az - :bz*:bz) (:zi + 2*:az*:bz))
end
 
mandelbrot -2 -1.25 2.5 400

[edit] Mathematica / Wolfram Language

The implementation could be better. But this is a start...

eTime[z0_, maxIter_Integer: 100] := (Length@NestWhileList[(# + z0)^2 &, 0, (Abs@# <= 2) &, 1, maxIter]) - 1
 
DistributeDefinitions[eTime];
mesh = ParallelTable[eTime[(x + I*y), 1000], {y, 1.2, -1.2, -0.01}, {x, -1.72, 1, 0.01}];
ReliefPlot[mesh, Frame -> False]

Faster version:

cf = With[{
mandel = Block[{z = #, c = #},
Catch@Do[If[Abs[z] > 2, Throw@i]; z = z^2 + c, {i, 100}]] &
},
Compile[{},Table[mandel[y + x I], {x, -1, 1, 0.005}, {y, -2, 0.5, 0.005}]]
];
ArrayPlot[cf[]]

[edit] Mathmap

filter mandelbrot (gradient coloration)
   c=ri:(xy/xy:[X,X]*1.5-xy:[0.5,0]);
   z=ri:[0,0]; # initial value z0 = 0 
   # iteration of z
   iter=0;
   while abs(z)<2 && iter<31
   do
       z=z*z+c;  # z(n+1) = fc(zn)
       iter=iter+1
   end;
   coloration(iter/32) # color of pixel
end

[edit] MATLAB

This solution uses the escape time algorithm to determine the coloring of the coordinates on the complex plane. The code can be reduced to a single line via vectorization after the Escape Time Algorithm function definition, but the code becomes unnecessarily obfuscated. Also, this code uses a lot of memory. You will need a computer with a lot of memory to compute the set with high resolution.

function [theSet,realAxis,imaginaryAxis] = mandelbrotSet(start,gridSpacing,last,maxIteration)
 
%Define the escape time algorithm
function escapeTime = escapeTimeAlgorithm(z0)
 
escapeTime = 0;
z = 0;
 
while( (abs(z)<=2) && (escapeTime < maxIteration) )
z = (z + z0)^2;
escapeTime = escapeTime + 1;
end
 
end
 
%Define the imaginary axis
imaginaryAxis = (imag(start):imag(gridSpacing):imag(last));
 
%Define the real axis
realAxis = (real(start):real(gridSpacing):real(last));
 
%Construct the complex plane from the real and imaginary axes
complexPlane = meshgrid(realAxis,imaginaryAxis) + meshgrid(imaginaryAxis(end:-1:1),realAxis)'.*i;
 
%Apply the escape time algorithm to each point in the complex plane
theSet = arrayfun(@escapeTimeAlgorithm, complexPlane);
 
 
%Draw the set
pcolor(realAxis,imaginaryAxis,theSet);
shading flat;
 
end

To use this function you must specify the:

  1. lower left hand corner of the complex plane from which to start the image,
  2. the grid spacing in both the imaginary and real directions,
  3. the upper right hand corner of the complex plane at which to end the image and
  4. the maximum iterations for the escape time algorithm.

For example:

  1. Lower Left Corner: -2.05-1.2i
  2. Grid Spacing: 0.004+0.0004i
  3. Upper Right Corner: 0.45+1.2i
  4. Maximum Iterations: 500

Sample usage:

mandelbrotSet(-2.05-1.2i,0.004+0.0004i,0.45+1.2i,500);

[edit] Modula-3

MODULE Mandelbrot EXPORTS Main;
 
IMPORT Wr, Stdio, Fmt, Word;
 
CONST m = 50;
limit2 = 4.0;
 
TYPE UByte = BITS 8 FOR [0..16_FF];
 
VAR width := 200;
height := 200;
bitnum: CARDINAL := 0;
byteacc: UByte := 0;
isOverLimit: BOOLEAN;
Zr, Zi, Cr, Ci, Tr, Ti: REAL;
 
BEGIN
 
Wr.PutText(Stdio.stdout, "P4\n" & Fmt.Int(width) & " " & Fmt.Int(height) & "\n");
 
FOR y := 0 TO height - 1 DO
FOR x := 0 TO width - 1 DO
Zr := 0.0; Zi := 0.0;
Cr := 2.0 * FLOAT(x) / FLOAT(width) - 1.5;
Ci := 2.0 * FLOAT(y) / FLOAT(height) - 1.0;
 
FOR i := 1 TO m + 1 DO
Tr := Zr*Zr - Zi*Zi + Cr;
Ti := 2.0*Zr*Zi + Ci;
Zr := Tr; Zi := Ti;
isOverLimit := Zr*Zr + Zi*Zi > limit2;
IF isOverLimit THEN EXIT; END;
END;
 
IF isOverLimit THEN
byteacc := Word.Xor(Word.LeftShift(byteacc, 1), 16_00);
ELSE
byteacc := Word.Xor(Word.LeftShift(byteacc, 1), 16_01);
END;
 
INC(bitnum);
 
IF bitnum = 8 THEN
Wr.PutChar(Stdio.stdout, VAL(byteacc, CHAR));
byteacc := 0;
bitnum := 0;
ELSIF x = width - 1 THEN
byteacc := Word.LeftShift(byteacc, 8 - (width MOD 8));
Wr.PutChar(Stdio.stdout, VAL(byteacc, CHAR));
byteacc := 0;
bitnum := 0
END;
Wr.Flush(Stdio.stdout);
END;
END;
END Mandelbrot.

[edit] MySQL

See http://arbitraryscrawl.blogspot.co.uk/2012/06/fractsql.html for an explanation.

 
-- Table to contain all the data points
CREATE TABLE points (
c_re DOUBLE,
c_im DOUBLE,
z_re DOUBLE DEFAULT 0,
z_im DOUBLE DEFAULT 0,
znew_re DOUBLE DEFAULT 0,
znew_im DOUBLE DEFAULT 0,
steps INT DEFAULT 0,
active CHAR DEFAULT 1
);
 
DELIMITER |
 
-- Iterate over all the points in the table 'points'
CREATE PROCEDURE itrt (IN n INT)
BEGIN
label: LOOP
UPDATE points
SET
znew_re=POWER(z_re,2)-POWER(z_im,2)+c_re,
znew_im=2*z_re*z_im+c_im,
steps=steps+1
WHERE active=1;
UPDATE points SET
z_re=znew_re,
z_im=znew_im,
active=IF(POWER(z_re,2)+POWER(z_im,2)>4,0,1)
WHERE active=1;
SET n = n - 1;
IF n > 0 THEN
ITERATE label;
END IF;
LEAVE label;
END LOOP label;
END|
 
-- Populate the table 'points'
CREATE PROCEDURE populate (
r_min DOUBLE,
r_max DOUBLE,
r_step DOUBLE,
i_min DOUBLE,
i_max DOUBLE,
i_step DOUBLE)
BEGIN
DELETE FROM points;
SET @rl = r_min;
SET @a = 0;
rloop: LOOP
SET @im = i_min;
SET @b = 0;
iloop: LOOP
INSERT INTO points (c_re, c_im)
VALUES (@rl, @im);
SET @b=@b+1;
SET @im=i_min + @b * i_step;
IF @im < i_max THEN
ITERATE iloop;
END IF;
LEAVE iloop;
END LOOP iloop;
SET @a=@a+1;
SET @rl=r_min + @a * r_step;
IF @rl < r_max THEN
ITERATE rloop;
END IF;
LEAVE rloop;
END LOOP rloop;
END|
 
DELIMITER ;
 
-- Choose size and resolution of graph
-- R_min, R_max, R_step, I_min, I_max, I_step
CALL populate( -2.5, 1.5, 0.005, -2, 2, 0.005 );
 
-- Calculate 50 iterations
CALL itrt( 50 );
 
-- Create the image (/tmp/image.ppm)
-- Note, MySQL will not over-write an existing file and you may need
-- administrator access to delete or move it
SELECT @xmax:=COUNT(c_re) INTO @xmax FROM points GROUP BY c_im LIMIT 1;
SELECT @ymax:=COUNT(c_im) INTO @ymax FROM points GROUP BY c_re LIMIT 1;
SET group_concat_max_len=11*@xmax*@ymax;
SELECT
'P3', @xmax, @ymax, 200,
GROUP_CONCAT(
CONCAT(
IF( active=1, 0, 55+MOD(steps, 200) ), ' ',
IF( active=1, 0, 55+MOD(POWER(steps,3), 200) ), ' ',
IF( active=1, 0, 55+MOD(POWER(steps,2), 200) ) )
ORDER BY c_im ASC, c_re ASC SEPARATOR ' ' )
INTO OUTFILE '/tmp/image.ppm'
FROM points;
 

[edit] Nimrod

Translation of: Python
import complex
 
proc mandelbrot(a): TComplex =
for i in 0 .. <50:
result = result * result + a
 
iterator stepIt(start, step, iterations) =
for i in 0 .. iterations:
yield start + float(i) * step
 
var rows = ""
for y in stepIt(1.0, -0.05, 41):
for x in stepIt(-2.0, 0.0315, 80):
if abs(mandelbrot((x,y))) < 2:
rows.add('*')
else:
rows.add(' ')
rows.add("\n")
 
echo rows

[edit] OCaml

#load "graphics.cma";;
 
let mandelbrot xMin xMax yMin yMax xPixels yPixels maxIter =
let rec mandelbrotIterator z c n =
if (Complex.norm z) > 2.0 then false else
match n with
| 0 -> true
| n -> let z' = Complex.add (Complex.mul z z) c in
mandelbrotIterator z' c (n-1) in
Graphics.open_graph
(" "^(string_of_int xPixels)^"x"^(string_of_int yPixels));
let dx = (xMax -. xMin) /. (float_of_int xPixels)
and dy = (yMax -. yMin) /. (float_of_int yPixels) in
for xi = 0 to xPixels - 1 do
for yi = 0 to yPixels - 1 do
let c = {Complex.re = xMin +. (dx *. float_of_int xi);
Complex.im = yMin +. (dy *. float_of_int yi)} in
if (mandelbrotIterator Complex.zero c maxIter) then
(Graphics.set_color Graphics.white;
Graphics.plot xi yi )
else
(Graphics.set_color Graphics.black;
Graphics.plot xi yi )
done
done;;
 
mandelbrot (-1.5) 0.5 (-1.0) 1.0 500 500 200;;

[edit] Octave

This code runs rather slowly and produces coloured Mandelbrot set by accident (output image).

#! /usr/bin/octave -qf
global width = 200;
global height = 200;
maxiter = 100;
 
z0 = 0;
global cmax = 1 + i;
global cmin = -2 - i;
 
function cs = pscale(c)
global cmax;
global cmin;
global width;
global height;
persistent px = (real(cmax-cmin))/width;
persistent py = (imag(cmax-cmin))/height;
cs = real(cmin) + px*real(c) + i*(imag(cmin) + py*imag(c));
endfunction
 
ms = zeros(width, height);
for x = 0:width-1
for y = 0:height-1
z0 = 0;
c = pscale(x+y*i);
for ic = 1:maxiter
z1 = z0^2 + c;
if ( abs(z1) > 2 ) break; endif
z0 = z1;
endfor
ms(x+1, y+1) = ic/maxiter;
endfor
endfor
 
saveimage("mandel.ppm", round(ms .* 255).', "ppm");

[edit] OS/8 BASIC

Works under BASIC on a PDP-8 running OS/8. Various emulators exist including simh's PDP-8 emulator and the PDP-8/E Simulator for Classic Macintosh and OS X.

10 X1=59\Y1=21
20 I1=-1.0\I2=1.0\R1=-2.0\R2=1.0
30 S1=(R2-R1)/X1\S2=(I2-I1)/Y1
40 FOR Y=0 TO Y1
50 I3=I1+S2*Y
60 FOR X=0 TO X1
70 R3=R1+S1*X\Z1=R3\Z2=I3
80 FOR N=0 TO 30
90 A=Z1*Z1\B=Z2*Z2
100 IF A+B>4.0 GOTO 130
110 Z2=2*Z1*Z2+I3\Z1=A-B+R3
120 NEXT N
130 PRINT CHR$(62-N);
140 NEXT X
150 PRINT
160 NEXT Y
170 END
 
Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<========
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<=======
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<=====
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<====
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<===
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<==
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<=
><;;;;;;::::9875&      .3                       *9;;;<<<<<<=
>;;;;;;::997564'        '                       8:;;;<<<<<<=
>::988897735/                                 &89:;;;<<<<<<=
>::988897735/                                 &89:;;;<<<<<<=
>;;;;;;::997564'        '                       8:;;;<<<<<<=
><;;;;;;::::9875&      .3                       *9;;;<<<<<<=
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<=
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<==
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<===
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<====
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<=====
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<=======
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<========
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<===========

[edit] Perl

translation / optimization of the ruby solution

use Math::Complex;
 
sub mandelbrot {
my ($z, $c) = @_[0,0];
for (1 .. 20) {
$z = $z * $z + $c;
return $_ if abs $z > 2;
}
}
 
for (my $y = 1; $y >= -1; $y -= 0.05) {
for (my $x = -2; $x <= 0.5; $x += 0.0315)
{print mandelbrot($x + $y * i) ? ' ' : '#'}
print "\n"
}

[edit] Perl 6

Mandel-perl6.png

Variant of a Mandelbrot script from the Perl 6 ecosystem. Produces a Portable Pixel Map to STDOUT. Redirect into a file to save it. Converted to a .png file for display here.

constant MAX_ITERATIONS = 50;
my $height = @*ARGS[0] // 31;
$height = $height % 2 ?? +$height !! 1+$height;
my $width = $height;
 
my $re = [ -2, 1/2 ];
my $im = [-5/4, 5/4];
 
my @re = $re.min, * + ($re.max - $re.min)/($height - 1) ... $re.max;
my @im = 1i «*« ($im.min, * + ($im.max - $im.min)/($width - 1) ... 0);
 
my @color_map = map ~*.comb(/../).map({:16($_)}), <
000000 0000fc 4000fc 7c00fc bc00fc fc00fc fc00bc fc007c fc0040 fc0000 fc4000
fc7c00 fcbc00 fcfc00 bcfc00 7cfc00 40fc00 00fc00 00fc40 00fc7c 00fcbc 00fcfc
00bcfc 007cfc 0040fc 7c7cfc 9c7cfc bc7cfc dc7cfc fc7cfc fc7cdc fc7cbc fc7c9c
fc7c7c fc9c7c fcbc7c fcdc7c fcfc7c dcfc7c bcfc7c 9cfc7c 7cfc7c 7cfc9c 7cfcbc
7cfcdc 7cfcfc 7cdcfc 7cbcfc 7c9cfc b4b4fc c4b4fc d8b4fc e8b4fc fcb4fc fcb4e8
fcb4d8 fcb4c4 fcb4b4 fcc4b4 fcd8b4 fce8b4 fcfcb4 e8fcb4 d8fcb4 c4fcb4 b4fcb4
b4fcc4 b4fcd8 b4fce8 b4fcfc b4e8fc b4d8fc b4c4fc 000070 1c0070 380070 540070
700070 700054 700038 70001c 700000 701c00 703800 705400 707000 547000 387000
1c7000 007000 00701c 007038 007054 007070 005470 003870 001c70 383870 443870
543870 603870 703870 703860 703854 703844 703838 704438 705438 706038 707038
607038 547038 447038 387038 387044 387054 387060 387070 386070 385470 384470
505070 585070 605070 685070 705070 705068 705060 705058 705050 705850 706050
706850 707050 687050 607050 587050 507050 507058 507060 507068 507070 506870
506070 505870 000040 100040 200040 300040 400040 400030 400020 400010 400000
401000 402000 403000 404000 304000 204000 104000 004000 004010 004020 004030
004040 003040 002040 001040 202040 282040 302040 382040 402040 402038 402030
402028 402020 402820 403020 403820 404020 384020 304020 284020 204020 204028
204030 204038 204040 203840 203040 202840 2c2c40 302c40 342c40 3c2c40 402c40
402c3c 402c34 402c30 402c2c 40302c 40342c 403c2c 40402c 3c402c 34402c 30402c
2c402c 2c4030 2c4034 2c403c 2c4040 2c3c40 2c3440 2c3040
>;
 
sub Mandel (Complex $z) { 0, * **2 + $z ... *.abs > 2 }
 
say "P3";
say "$width $height";
say "255";
 
for @re -> $re {
say @color_map[.[^.end], .reverse] given
map { +Mandel($^z)[^MAX_ITERATIONS] % MAX_ITERATIONS },
$re «+« @im;
}

[edit] PHP

Works with: PHP version 5.3.5
Sample output
$min_x=-2;
$max_x=1;
$min_y=-1;
$max_y=1;
 
$dim_x=400;
$dim_y=300;
 
$im = @imagecreate($dim_x, $dim_y)
or die("Cannot Initialize new GD image stream");
header("Content-Type: image/png");
$black_color = imagecolorallocate($im, 0, 0, 0);
$white_color = imagecolorallocate($im, 255, 255, 255);
 
for($y=0;$y<=$dim_y;$y++) {
for($x=0;$x<=$dim_x;$x++) {
$c1=$min_x+($max_x-$min_x)/$dim_x*$x;
$c2=$min_y+($max_y-$min_y)/$dim_y*$y;
 
$z1=0;
$z2=0;
 
for($i=0;$i<100;$i++) {
$new1=$z1*$z1-$z2*$z2+$c1;
$new2=2*$z1*$z2+$c2;
$z1=$new1;
$z2=$new2;
if($z1*$z1+$z2*$z2>=4) {
break;
}
}
if($i<100) {
imagesetpixel ($im, $x, $y, $white_color);
}
}
}
 
imagepng($im);
imagedestroy($im);
 

[edit] PicoLisp

(scl 6)
 
(let Ppm (make (do 300 (link (need 400))))
(for (Y . Row) Ppm
(for (X . @) Row
(let (ZX 0 ZY 0 CX (*/ (- X 250) 1.0 150) CY (*/ (- Y 150) 1.0 150) C 570)
(while (and (> 4.0 (+ (*/ ZX ZX 1.0) (*/ ZY ZY 1.0))) (gt0 C))
(let Tmp (- (*/ ZX ZX 1.0) (*/ ZY ZY 1.0) (- CX))
(setq
ZY (+ (*/ 2 ZX ZY 1.0) CY)
ZX Tmp ) )
(dec 'C) )
(set (nth Ppm Y X) (list 0 C C)) ) ) )
(out "img.ppm"
(prinl "P6")
(prinl 400 " " 300)
(prinl 255)
(for Y Ppm (for X Y (apply wr X))) ) )

[edit] PostScript

%!PS-Adobe-2.0
%%BoundingBox: 0 0 300 200
%%EndComments
/origstate save def
/ld {load def} bind def
/m /moveto ld /g /setgray ld
/dot { currentpoint 1 0 360 arc fill } bind def
%%EndProlog
% param
/maxiter 200 def
% complex manipulation
/complex { 2 array astore } def
/real { 0 get } def
/imag { 1 get } def
/cmul { /a exch def /b exch def
a real b real mul
a imag b imag mul sub
a real b imag mul
a imag b real mul add
2 array astore
} def
/cadd { aload pop 3 -1 roll aload pop
3 -1 roll add
3 1 roll add exch 2 array astore
} def
/cconj { aload pop neg 2 array astore } def
/cabs2 { dup cconj cmul 0 get} def
% mandel
200 100 translate
-200 1 100 { /x exch def
-100 1 100 { /y exch def
/z0 0.0 0.0 complex def
0 1 maxiter { /iter exch def
x 100 div y 100 div complex
z0 z0 cmul
cadd dup /z0 exch def
cabs2 4 gt {exit} if
} for
iter maxiter div g
x y m dot
} for
} for
%
showpage
origstate restore
%%EOF

[edit] Prolog

SWI-Prolog has a graphic interface XPCE :

:- use_module(library(pce)).
 
mandelbrot :-
new(D, window('Mandelbrot Set')),
send(D, size, size(700, 650)),
new(Img, image(@nil, width := 700, height := 650, kind := pixmap)),
 
forall(between(0,699, I),
( forall(between(0,649, J),
( get_RGB(I, J, R, G, B),
R1 is (R * 256) mod 65536,
G1 is (G * 256) mod 65536,
B1 is (B * 256) mod 65536,
send(Img, pixel(I, J, colour(@default, R1, G1, B1))))))),
new(Bmp, bitmap(Img)),
send(D, display, Bmp, point(0,0)),
send(D, open).
 
get_RGB(X, Y, R, G, B) :-
CX is (X - 350) / 150,
CY is (Y - 325) / 150,
Iter = 570,
compute_RGB(CX, CY, 0, 0, Iter, It),
IterF is It \/ It << 15,
R is IterF >> 16,
Iter1 is IterF - R << 16,
G is Iter1 >> 8,
B is Iter1 - G << 8.
 
compute_RGB(CX, CY, ZX, ZY, Iter, IterF) :-
ZX * ZX + ZY * ZY < 4,
Iter > 0,
!,
Tmp is ZX * ZX - ZY * ZY + CX,
ZY1 is 2 * ZX * ZY + CY,
Iter1 is Iter - 1,
compute_RGB(CX, CY, Tmp, ZY1, Iter1, IterF).
 
compute_RGB(_CX, _CY, _ZX, _ZY, Iter, Iter).
Example :

Mandelbrot.jpg

[edit] PureBasic

PureBasic forum: discussion

EnableExplicit
 
#Window1 = 0
#Image1 = 0
#ImgGadget = 0
 
#max_iteration = 64
#width = 800
#height = 600
Define.d x0 ,y0 ,xtemp ,cr, ci
Define.i i, n, x, y ,Event ,color
 
Dim Color.l (255)
For n = 0 To 63
Color( 0 + n ) = RGB( n*4+128, 4 * n, 0 )
Color( 64 + n ) = RGB( 64, 255, 4 * n )
Color( 128 + n ) = RGB( 64, 255 - 4 * n , 255 )
Color( 192 + n ) = RGB( 64, 0, 255 - 4 * n )
Next
 
If OpenWindow(#Window1, 0, 0, #width, #height, "'Mandelbrot set' PureBasic Example", #PB_Window_SystemMenu )
If CreateImage(#Image1, #width, #height)
ImageGadget(#ImgGadget, 0, 0, #width, #height, ImageID(#Image1))
For y.i = 1 To #height -1
StartDrawing(ImageOutput(#Image1))
For x.i = 1 To #width -1
x0 = 0
y0 = 0;
cr = (x / #width)*2.5 -2
ci = (y / #height)*2.5 -1.25
i = 0
While (x0*x0 + y0*y0 <= 4.0) And i < #max_iteration
i +1
xtemp = x0*x0 - y0*y0 + cr
y0 = 2*x0*y0 + ci
x0 = xtemp
Wend
If i >= #max_iteration
Plot(x, y, 0 )
Else
Plot(x, y, Color(i & 255))
EndIf
 
Next
StopDrawing()
SetGadgetState(#ImgGadget, ImageID(#Image1))
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
Next
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Example:

Mandelbrot-PureBasic.png

[edit] Python

Translation of the ruby solution

# Python 3.0+ and 2.5+
try:
from functools import reduce
except:
pass
 
 
def mandelbrot(a):
return reduce(lambda z, _: z * z + a, range(50), 0)
 
def step(start, step, iterations):
return (start + (i * step) for i in range(iterations))
 
rows = (("*" if abs(mandelbrot(complex(x, y))) < 2 else " "
for x in step(-2.0, .0315, 80))
for y in step(1, -.05, 41))
 
print("\n".join("".join(row) for row in rows))
 

A more "Pythonic" version of the code:

 
import math
 
def mandelbrot(z , c , n=40):
if abs(z) > 1000:
return float("nan")
else:
if n > 0:
return mandelbrot(z ** 2 + c, c, n - 1)
else:
return z ** 2 + c
 
print("\n".join(["".join(["#" if not math.isnan(mandelbrot(0, x + 1j * y).real) else " "
for x in [a * 0.02 for a in range(-80, 30)]])
for y in [a * 0.05 for a in range(-20, 20)]])
)
 

[edit] R

iterate.until.escape <- function(z, c, trans, cond, max=50, response=dwell) {
#we iterate all active points in the same array operation,
#and keeping track of which points are still iterating.
active <- seq_along(z)
dwell <- z
dwell[] <- 0
for (i in 1:max) {
z[active] <- trans(z[active], c[active]);
survived <- cond(z[active])
dwell[active[!survived]] <- i
active <- active[survived]
if (length(active) == 0) break
}
eval(substitute(response))
}
 
re = seq(-2, 1, len=500)
im = seq(-1.5, 1.5, len=500)
c <- outer(re, im, function(x,y) complex(real=x, imaginary=y))
x <- iterate.until.escape(array(0, dim(c)), c,
function(z,c)z^2+c, function(z)abs(z) <= 2,
max=100)
image(x)

[edit] Racket

 
#lang racket
 
(require racket/draw)
 
(define (iterations a z i)
(define z′ (+ (* z z) a))
(if (or (= i 255) (> (magnitude z′) 2))
i
(iterations a z′ (add1 i))))
 
(define (iter->color i)
(if (= i 255)
(make-object color% "black")
(make-object color% (* 5 (modulo i 15)) (* 32 (modulo i 7)) (* 8 (modulo i 31)))))
 
(define (mandelbrot width height)
(define target (make-bitmap width height))
(define dc (new bitmap-dc% [bitmap target]))
(for* ([x width] [y height])
(define real-x (- (* 3.0 (/ x width)) 2.25))
(define real-y (- (* 2.5 (/ y height)) 1.25))
(send dc set-pen (iter->color (iterations (make-rectangular real-x real-y) 0 0)) 1 'solid)
(send dc draw-point x y))
(send target save-file "mandelbrot.png" 'png))
 
(mandelbrot 300 200)
 

[edit] REXX

Translation of: AWK
/*REXX program generates and displays a Mandelbrot set as an ASCII image*/
xsize = 59; minre = -2; maxre = +1; stepx = (maxre-minre)/xsize
ysize = 21; minim = -1; maxim = +1; stepy = (maxim-minim)/ysize
 
do y=0 for ysize
im=minim+stepy*y
do x=0 for xsize
re=minre+stepx*x; zr=re; zi=im
do n=0 for 30
a=zr*zr; b=zi*zi
if a+b>4 then leave
zi=2*zr*zi+im; zr=a-b+re
end /*n*/
call charout ,d2c(62-n) /*display number as a char──►term*/
end /*x*/
say /*force last CHAROUTs to the term*/
end /*y*/ /*stick a fork in it, we're done.*/
Output:
>>>>>>=====<<<<<<<<<<<<<<<;;;;;;:::96032:;;;;<<<<==========
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<======
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<====
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<===
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<==
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<=
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<
><;;;;;;::::9875&      .3                       *9;;;<<<<<<
>;;;;;;::997564'        '                       8:;;;<<<<<<
>::988897735/                                 &89:;;;<<<<<<
>::988897735/                                 &89:;;;<<<<<<
>;;;;;;::997564'        '                       8:;;;<<<<<<
><;;;;;;::::9875&      .3                       *9;;;<<<<<<
><<<<;;;;;:::972456-567763                      +9;;<<<<<<<
>=<<<<<<<<;;;:599999999886                    %78:;;<<<<<<=
>>=<<<<<<<<<<<;;;::::::999752                 *79:;<<<<<<==
>>==<<<<<<<<<<<<<;;;;::::996. &2           45335:;<<<<<<===
>>>==<<<<<<<<<<<<<<<;;;;;;:98888764     5789999:;;<<<<<====
>>>>===<<<<<<<<<<<<<<<;;;;;;;::9974    (.9::::;;<<<<<======
>>>>>===<<<<<<<<<<<<<<<<;;;;;;;:::873*079::;;;;<<<<<=======


[edit] Ruby

Text only, prints an 80-char by 41-line depiction. Found here.

require 'complex'
 
def mandelbrot(a)
Array.new(50).inject(0) { |z,c| z*z + a }
end
 
(1.0).step(-1,-0.05) do |y|
(-2.0).step(0.5,0.0315) do |x|
print mandelbrot(Complex(x,y)).abs < 2 ? '*' : ' '
end
puts
end
Translation of: Tcl

Uses the text progress bar from Median filter#Ruby

class RGBColour
def self.mandel_colour(i)
self.new( 16*(i % 15), 32*(i % 7), 8*(i % 31) )
end
end
 
class Pixmap
def self.mandelbrot(width, height)
mandel = Pixmap.new(width,height)
pb = ProgressBar.new(width) if $DEBUG
width.times do |x|
height.times do |y|
x_ish = Float(x - width*11/15) / (width/3)
y_ish = Float(y - height/2) / (height*3/10)
mandel[x,y] = RGBColour.mandel_colour(mandel_iters(x_ish, y_ish))
end
pb.update(x) if $DEBUG
end
pb.close if $DEBUG
mandel
end
 
def self.mandel_iters(cx,cy)
x = y = 0.0
count = 0
while Math.hypot(x,y) < 2 and count < 255
x, y = (x**2 - y**2 + cx), (2*x*y + cy)
count += 1
end
count
end
end
 
Pixmap.mandelbrot(300,300).save('mandel.ppm')

[edit] Scala

Works with: Scala version 2.8

Uses RgbBitmap from Basic Bitmap Storage task and Complex number class from this programming task.

import org.rosettacode.ArithmeticComplex._
import java.awt.Color
 
object Mandelbrot
{
def generate(width:Int =600, height:Int =400)={
val bm=new RgbBitmap(width, height)
 
val maxIter=1000
val xMin = -2.0
val xMax = 1.0
val yMin = -1.0
val yMax = 1.0
 
val cx=(xMax-xMin)/width
val cy=(yMax-yMin)/height
 
for(y <- 0 until bm.height; x <- 0 until bm.width){
val c=Complex(xMin+x*cx, yMin+y*cy)
val iter=itMandel(c, maxIter, 4)
bm.setPixel(x, y, getColor(iter, maxIter))
}
bm
}
 
def itMandel(c:Complex, imax:Int, bailout:Int):Int={
var z=Complex()
for(i <- 0 until imax){
z=z*z+c;
if(z.abs > bailout) return i
}
imax;
}
 
def getColor(iter:Int, max:Int):Color={
if (iter==max) return Color.BLACK
 
var c=3*math.log(iter)/math.log(max-1.0)
if(c<1) new Color((255*c).toInt, 0, 0)
else if(c<2) new Color(255, (255*(c-1)).toInt, 0)
else new Color(255, 255, (255*(c-2)).toInt)
}
}

Read–eval–print loop

import scala.swing._
import javax.swing.ImageIcon
val imgMandel=Mandelbrot.generate()
val mainframe=new MainFrame(){title="Test"; visible=true
contents=new Label(){icon=new ImageIcon(imgMandel.image)}
}

[edit] Scheme

This implementation writes an image of the Mandelbrot set to a plain pgm file. The set itself is drawn in white, while the exterior is drawn in black.

(define x-centre -0.5)
(define y-centre 0.0)
(define width 4.0)
(define i-max 800)
(define j-max 600)
(define n 100)
(define r-max 2.0)
(define file "out.pgm")
(define colour-max 255)
(define pixel-size (/ width i-max))
(define x-offset (- x-centre (* 0.5 pixel-size (+ i-max 1))))
(define y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1))))
 
(define (inside? z)
(define (*inside? z-0 z n)
(and (< (magnitude z) r-max)
(or (= n 0)
(*inside? z-0 (+ (* z z) z-0) (- n 1)))))
(*inside? z 0 n))
 
(define (boolean->integer b)
(if b colour-max 0))
 
(define (pixel i j)
(boolean->integer
(inside?
(make-rectangular (+ x-offset (* pixel-size i))
(- y-offset (* pixel-size j))))))
 
(define (plot)
(with-output-to-file file
(lambda ()
(begin (display "P2") (newline)
(display i-max) (newline)
(display j-max) (newline)
(display colour-max) (newline)
(do ((j 1 (+ j 1))) ((> j j-max))
(do ((i 1 (+ i 1))) ((> i i-max))
(begin (display (pixel i j)) (newline))))))))
 
(plot)

[edit] Scratch

Scratch-mandelbrot.gif

[edit] SCSS/SASS

 
 
@function square($n) {
@return $n * $n;
}
 
@function complex-add($x, $y) {
@return square($y) + square($x);
}
 
@function complex-subtract($x, $y) {
@return square($x) - square($y);
}
 
@function complex-multiply($x, $y) {
@return 2 * $x * $y;
}
 
@function complex-next($z) {
$x: nth($z, 1);
$y: nth($z, 2);
$a: complex-subtract($x, $y) + $xx;
$b: complex-multiply($x, $y) + $yy;
$ret: complex-add($a, $b);
@return $a, $b, $ret;
}
 
 
$factor: 50;
$iterations: 15;
$pixel-size: 2px;
 
 
$count: $factor * 4 + 1;
$start: -2;
$end: 2;
$xx: 0;
$yy: 0;
$size: ($count * $pixel-size);
$color: 255;
$next: ();
 
*,
*:before,
*:after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
 
section {
position: relative;
width: $size;
height: $size;
font-size: 0;
line-height: 0;
}
 
span {
height: ($size/$count);
width: ($size/$count);
display: inline-block;
}
 
@for $x from $start * $factor through $end * $factor {
@for $y from $start * $factor through $end * $factor {
 
$xx: $x/$factor !global;
$yy: $y/$factor !global;
$done: false;
$first: complex-add($xx, $yy);
$next: ($xx, $yy)!global;
 
._#{$xx*1000}_#{$yy*1000} {
 
$h: 0;
$s: 100%;
$l: 50%;
 
@if $first > 4 {
@if $done == false {
$h: 20deg;
$done: true;
}
} @else {
@for $i from 2 through $iterations {
$next: complex-next($next)!global;
@if $i % 2 == 0 {
@if nth($next, 3) > 2 {
@if $done == false {
$h: $i * 20deg;
$done: true;
}
}
} @else {
@if nth($next, 3) > 4 {
@if $done == false {
$h: $i * 20deg;
$done: true;
}
}
}
}
}
@if $done == false {
$l: 0%;
$done: true;
}
background-color: hsl($h, 100%, $l);
}
}
}
 

Jade code for markup

 
- f = 50
- c = f * 2 + 1
- n = c * c
section
- for (i = 0; i < n; i++)
- x = Math.round((((c - 1) / 2) - i % c) / ((c - 1) / 2) * -2000)
- y = Math.round((((c - 1) / 2) - (i % n - i % c) / c) / ((c - 1) / 2) * 2000)
span(class="_#{x}_#{y}")
 
Output:

live: http://mandelbrot.cssnerd.com/

[edit] Seed7

$ include "seed7_05.s7i";
  include "float.s7i";
  include "complex.s7i";
  include "draw.s7i";
  include "keybd.s7i";

# Display the Mandelbrot set, that are points z[0] in the complex plane
# for which the sequence z[n+1] := z[n] ** 2 + z[0] (n >= 0) is bounded.
# Since this program is computing intensive it should be compiled with
# hi comp -O2 mandelbr

const integer: pix is 200;
const integer: max_iter is 256;

var array color: colorTable is max_iter times black;

const func integer: iterate (in complex: z0) is func
  result
    var integer: iter is 1;
  local
    var complex: z is complex.value;
  begin
    z := z0;
    while sqrAbs(z) < 4.0 and  # not diverged
        iter < max_iter do     # not converged
      z *:= z;
      z +:= z0;
      incr(iter);
    end while;
  end func;

const proc: displayMandelbrotSet (in complex: center, in float: zoom) is func
  local
    var integer: x is 0;
    var integer: y is 0;
    var complex: z0 is complex.value;
  begin
    for x range -pix to pix do
      for y range -pix to pix do
        z0 := center + complex(flt(x) * zoom, flt(y) * zoom);
        point(x + pix, y + pix, colorTable[iterate(z0)]);
      end for;    
    end for;
  end func;

const proc: main is func
  local
    const integer: num_pix is 2 * pix + 1;
    var integer: col is 0;
  begin
    screen(num_pix, num_pix);
    clear(curr_win, black);
    KEYBOARD := GRAPH_KEYBOARD;
    for col range 1 to pred(max_iter) do
      colorTable[col] := color(65535 - (col * 5003) mod 65535,
                                       (col * 257)  mod 65535,
                                       (col * 2609) mod 65535);
    end for;
    displayMandelbrotSet(complex(-0.75, 0.0), 1.3 / flt(pix));
    DRAW_FLUSH;
    readln(KEYBOARD);
  end func;


Original source: [2]

[edit] Tcl

Library: Tk

This code makes extensive use of Tk's built-in photo image system, which provides a 32-bit RGBA plotting surface that can be then quickly drawn in any number of places in the application. It uses a computational color scheme that was easy to code...

package require Tk
 
proc mandelIters {cx cy} {
set x [set y 0.0]
for {set count 0} {hypot($x,$y) < 2 && $count < 255} {incr count} {
set x1 [expr {$x*$x - $y*$y + $cx}]
set y1 [expr {2*$x*$y + $cy}]
set x $x1; set y $y1
}
return $count
}
proc mandelColor {iter} {
set r [expr {16*($iter % 15)}]
set g [expr {32*($iter % 7)}]
set b [expr {8*($iter % 31)}]
format "#%02x%02x%02x" $r $g $b
}
image create photo mandel -width 300 -height 300
# Build picture in strips, updating as we go so we have "progress" monitoring
# Also set the cursor to tell the user to wait while we work.
pack [label .mandel -image mandel -cursor watch]
update
for {set x 0} {$x < 300} {incr x} {
for {set y 0} {$y < 300} {incr y} {
set i [mandelIters [expr {($x-220)/100.}] [expr {($y-150)/90.}]]
mandel put [mandelColor $i] -to $x $y
}
update
}
.mandel configure -cursor {}

[edit] TI-83 BASIC

Based on the BASIC Version. Due to the TI-83's lack of power, it takes around 2 hours to complete at 16 iterations.

PROGRAM:MANDELBR
:Input "ITER. ",D
:For(A,Xmin,Xmax,ΔX)
:For(B,Ymin,Ymax,ΔY)
:0→X
:0→Y
:0→I
:D→M
:While X^2+Y^2≤4 and I<M
:X^2-Y^2+A→R
:2XY+B→Y
:R→X
:I+1→I
:End
:If I≠M
:Then
:I→C
:Else
:0→C
:End
:If C<1
:Pt-On(A,B)
:End
:End
:End
 

[edit] TXR

Translation of: Scheme

Creates same mandelbrot.pgm file.

@(do 
(defvar x-centre -0.5)
(defvar y-centre 0.0)
(defvar width 4.0)
(defvar i-max 800)
(defvar j-max 600)
(defvar n 100)
(defvar r-max 2.0)
(defvar file "mandelbrot.pgm")
(defvar colour-max 255)
(defvar pixel-size (/ width i-max))
(defvar x-offset (- x-centre (* 0.5 pixel-size (+ i-max 1))))
(defvar y-offset (+ y-centre (* 0.5 pixel-size (+ j-max 1))))
 
 ;; with-output-to-file macro
(defmacro with-output-to-file (name . body)
^(let ((*stdout* (open-file ,name "w")))
(unwind-protect (progn ,*body) (close-stream *stdout*))))
 
 ;; complex number library
(defmacro cplx (x y) ^(cons ,x ,y))
(defmacro re (c) ^(car ,c))
(defmacro im (c) ^(cdr ,c))
 
(defsymacro c0 '(0 . 0))
 
(macro-time
(defun with-cplx-expand (specs body)
(tree-case specs
(((re im expr) . rest)
^(tree-bind (,re . ,im) ,expr ,(with-cplx-expand rest body)))
(() (tree-case body
((a b . rest) ^(progn ,a ,b ,*rest))
((a) a)
(x (error "with-cplx: invalid body ~s" body))))
(x (error "with-cplx: bad args ~s" x)))))
 
(defmacro with-cplx (specs . body)
(with-cplx-expand specs body))
 
(defun c+ (x y)
(with-cplx ((a b x) (c d y))
(cplx (+ a c) (+ b d))))
 
(defun c* (x y)
(with-cplx ((a b x) (c d y))
(cplx (- (* a c) (* b d)) (+ (* b c) (* a d)))))
 
(defun modulus (z)
(with-cplx ((a b z))
(sqrt (+ (* a a) (* b b)))))
 
 ;; Mandelbrot routines
(defun inside-p (z0 : (z c0) (n n))
(and (< (modulus z) r-max)
(or (zerop n)
(inside-p z0 (c+ (c* z z) z0) (- n 1)))))
 
(defmacro int-bool (b)
^(if ,b colour-max 0))
 
(defun pixel (i j)
(int-bool
(inside-p
(cplx (+ x-offset (* pixel-size i))
(- y-offset (* pixel-size j))))))
 
 ;; Mandelbrot loop and output
(defun plot ()
(with-output-to-file file
(format t "P2\n~s\n~s\n~s\n" i-max j-max colour-max)
(each ((j (range 1 j-max)))
(each ((i (range 1 i-max)))
(format *stdout* "~s " (pixel i j)))
(put-line "" *stdout*))))
 
(plot))

[edit] Vedit macro language

Vedit macro language does not support floating point calculations, so fixed point arithmetic is used, with Value 10000 representing 1.0. The Mandelbrot image is drawn using ASCII characters 1-9 to show number of iterations. Iteration count 10 or more is represented with '@'. To compensate the aspect ratio of the font, step sizes in x and y directions are different.

#1 =-21000              // left edge = -2.1
#2 = 15000 // right edge = 1.5
#3 = 15000 // top edge = 1.5
#4 =-15000 // bottom edge = -1.5
#5 = 200 // max iteration depth
#6 = 350 // x step size
#7 = 750 // y step size
 
Buf_Switch(Buf_Free)
for (#12 = #3; #12 > #4; #12 -= #7) { // y0
for (#11 = #1; #11 < #2; #11 += #6) { // x0
#22 = 0 // y
#21 = 0 // x
#9 = ' ' // char to be displayed
for (#15 = 0; #15 < #5; #15++) { // iteration
#31 = (#21/10 * #21) / 1000 // x*x
#32 = (#22/10 * #22) / 1000 // y*y
if (#31 + #32 > 40000) {
#9 = '0' + #15 // print digit 0...9
if (#15 > 9) { // if iteration count > 9,
#9 = '@' // print '@'
}
break
}
#33 = #31 - #32 + #11 // temp = x*x - y*y + x0
#22 = (#21/10 * #22) / 500 + #12 // y = 2*x*y + y0
#21 = #33 // x = temp
}
Ins_Char(#9)
}
Ins_Newline
}
BOF
 
Output:

1111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222211111
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222
1111111122222333333333333333333333344444444445556668@@@   @@@@76555544444333333322222222222222222222222
1111111122233333333333333333333344444444445566667778@@      @987666555544433333333222222222222222222222
111111122333333333333333333333444444455556@@@@@99@@@@@@    @@@@@@87777@95443333333322222222222222222222
1111112233333333333333333334444455555556678@@  @@                @@@@@@@8544333333333222222222222222222
1111122333333333333333334445555555555666789@@@                        @86554433333333322222222222222222
1111123333333333333444466666555556666778@@@@                         @@87655443333333332222222222222222
111123333333344444455568@887789@8777788@@@                            @@@@65443333333332222222222222222
1111333344444444455556679@@@@@@@@@@@99@@@                              @@765444333333333222222222222222
1111334444444455555567789@@         @@@@                                @855444333333333222222222222222
11114444444455555668@99@@@            @                                @@655444433333333322222222222222
11134555556666677789@@@ @                                             @86655444433333333322222222222222
111                                                                 @@876555444433333333322222222222222
11134555556666677789@@@ @                                             @86655444433333333322222222222222
11114444444455555668@99@@@            @                                @@655444433333333322222222222222
1111334444444455555567789@@         @@@@                                @855444333333333222222222222222
1111333344444444455556679@@@@@@@@@@@99@@@                              @@765444333333333222222222222222
111123333333344444455568@887789@8777788@@@                            @@@@65443333333332222222222222222
1111123333333333333444466666555556666778@@@@                         @@87655443333333332222222222222222
1111122333333333333333334445555555555666789@@@                        @86554433333333322222222222222222
1111112233333333333333333334444455555556678@@  @@                @@@@@@@8544333333333222222222222222222
111111122333333333333333333333444444455556@@@@@99@@@@@@    @@@@@@87777@95443333333322222222222222222222
1111111122233333333333333333333344444444445566667778@@      @987666555544433333333222222222222222222222
1111111122222333333333333333333333344444444445556668@@@   @@@@76555544444333333322222222222222222222222
1111111112222223333333333333333333333444444444455556789@@@@98655544444433333332222222222222222222222222
11111111111222222333333333333333333333334444444445555678@@@@7654444443333332222222222222222222222222222
1111111111112222222233333333333333333333333444444445567@@6665444444333333222222222222222222222222222222
1111111111111222222222233333333333333333333333344444457655544443333332222222222222222222222222222222222
1111111111111112222222222222333333333333333333333333333333333333322222222222222222222222222222222222222
1111111111111111222222222222222222233333333333333333333333222222222222222222222222222222222222222222222
1111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222
1111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222211

[edit] XPL0

include c:\cxpl\codes;          \intrinsic 'code' declarations
int X, Y, \screen coordinates of current point
Cnt; \iteration counter
real Cx, Cy, \coordinates scaled to +/-2 range
Zx, Zy, \complex accumulator
Temp; \temporary scratch
[SetVid($112); \set 640x480x24 graphics mode
for Y:= 0 to 480-1 do \for all points on the screen...
for X:= 0 to 640-1 do
[Cx:= (float(X)/640.0 - 0.5) * 4.0; \range: -2.0 to +2.0
Cy:= (float(Y-240)/240.0) * 1.5; \range: -1.5 to +1.5
Cnt:= 0; Zx:= 0.0; Zy:= 0.0; \initialize
loop [if Zx*Zx + Zy*Zy > 2.0 then \Z heads toward infinity
[Point(X, Y, Cnt<<21+Cnt<<10+Cnt<<3); \set color of pixel to
quit; \ rate it approached infinity
]; \move on to next point
Temp:= Zx*Zy;
Zx:= Zx*Zx - Zy*Zy + Cx; \calculate next iteration of Z
Zy:= 2.0*Temp + Cy;
Cnt:= Cnt+1; \count number of iterations
if Cnt >= 1000 then quit; \assume point is in Mandelbrot
]; \ set and leave it colored black
];
X:= ChIn(1); \wait for keystroke
SetVid($03); \restore normal text display
]
Output:

MandelXPL0.png

[edit] XSLT

The fact that you can create an image of the Mandelbrot Set with XSLT is sometimes under-appreciated. However, it has been discussed extensively on the internet so is best reproduced here, and the code can be executed directly in your browser at that site.

 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<!-- XSLT Mandelbrot - written by Joel Yliluoma 2007, http://iki.fi/bisqwit/ -->
 
<xsl:output method="html" indent="no"
doctype-public="-//W3C//DTD HTML 4.01//EN"
doctype-system="http://www.w3.org/TR/REC-html40/strict.dtd"
/>
 
<xsl:template match="/fractal">
<html>
<head>
<title>XSLT fractal</title>
<style type="text/css">
body { color:#55F; background:#000 }
pre { font-family:monospace; font-size:7px }
pre span { background:<xsl:value-of select="background" /> }
</style>
</head>
<body>
<div style="position:absolute;top:20px;left:20em">
Copyright © 1992,2007 Joel Yliluoma
(<a href="http://iki.fi/bisqwit/">http://iki.fi/bisqwit/</a>)
</div>
<h1 style="margin:0px">XSLT fractal</h1>
<pre><xsl:call-template name="bisqwit-mandelbrot" /></pre>
</body>
</html>
</xsl:template>
 
<xsl:template name="bisqwit-mandelbrot"
><xsl:call-template name="bisqwit-mandelbrot-line">
<xsl:with-param name="y" select="y/min"/>
</xsl:call-template
></xsl:template>
 
<xsl:template name="bisqwit-mandelbrot-line"
><xsl:param name="y"
/><xsl:call-template name="bisqwit-mandelbrot-column">
<xsl:with-param name="x" select="x/min"/>
<xsl:with-param name="y" select="$y"/>
</xsl:call-template
><xsl:if test="$y < y/max"
><br
/><xsl:call-template name="bisqwit-mandelbrot-line">
<xsl:with-param name="y" select="$y + y/step"/>
</xsl:call-template
></xsl:if
></xsl:template>
 
<xsl:template name="bisqwit-mandelbrot-column"
><xsl:param name="x"
/><xsl:param name="y"
/><xsl:call-template name="bisqwit-mandelbrot-slot">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="y" select="$y" />
<xsl:with-param name="zr" select="$x" />
<xsl:with-param name="zi" select="$y" />
</xsl:call-template
><xsl:if test="$x < x/max"
><xsl:call-template name="bisqwit-mandelbrot-column">
<xsl:with-param name="x" select="$x + x/step"/>
<xsl:with-param name="y" select="$y" />
</xsl:call-template
></xsl:if
></xsl:template>
 
<xsl:template name="bisqwit-mandelbrot-slot"
><xsl:param name="x"
/><xsl:param name="y"
/><xsl:param name="zr"
/><xsl:param name="zi"
/><xsl:param name="iter" select="0"
/><xsl:variable name="zrsqr" select="($zr * $zr)"
/><xsl:variable name="zisqr" select="($zi * $zi)"
/><xsl:choose>
<xsl:when test="(4*scale*scale >= $zrsqr + $zisqr) and (maxiter > $iter+1)"
><xsl:call-template name="bisqwit-mandelbrot-slot">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="y" select="$y" />
<xsl:with-param name="zi" select="(2 * $zr * $zi) div scale + $y" />
<xsl:with-param name="zr" select="($zrsqr - $zisqr) div scale + $x" />
<xsl:with-param name="iter" select="$iter + 1" />
</xsl:call-template
></xsl:when>
<xsl:otherwise
><xsl:variable name="magnitude" select="magnitude[@value=$iter]"
/><span style="color:{$magnitude/color}"
><xsl:value-of select="$magnitude/symbol"
/></span></xsl:otherwise>
</xsl:choose
></xsl:template>
 
</xsl:stylesheet>
 

[edit] Z80 Assembly

 
;
; Compute a Mandelbrot set on a simple Z80 computer.
;
; Porting this program to another Z80 platform should be easy and straight-
; forward: The only dependencies on my homebrew machine are the system-calls
; used to print strings and characters. These calls are performed by loading
; IX with the number of the system-call and performing an RST 08. To port this
; program to another operating system just replace these system-calls with
; the appropriate versions. Only three system-calls are used in the following:
; _crlf: Prints a CR/LF, _puts: Prints a 0-terminated string (the adress of
; which is expected in HL), and _putc: Print a single character which is
; expected in A. RST 0 give control back to the monitor.
;
#include "mondef.asm"
 
org ram_start
 
scale equ 256 ; Do NOT change this - the
; arithmetic routines rely on
; this scaling factor! :-)
divergent equ scale * 4
 
ld hl, welcome ; Print a welcome message
ld ix, _puts
rst 08
 
; for (y = <initial_value> ; y <= y_end; y += y_step)
; {
outer_loop ld hl, (y_end) ; Is y <= y_end?
ld de, (y)
and a ; Clear carry
sbc hl, de ; Perform the comparison
jp m, mandel_end ; End of outer loop reached
 
; for (x = x_start; x <= x_end; x += x_step)
; {
ld hl, (x_start) ; x = x_start
ld (x), hl
inner_loop ld hl, (x_end) ; Is x <= x_end?
ld de, (x)
and a
sbc hl, de
jp m, inner_loop_end ; End of inner loop reached
 
; z_0 = z_1 = 0;
ld hl, 0
ld (z_0), hl
ld (z_1), hl
 
; for (iteration = iteration_max; iteration; iteration--)
; {
ld a, (iteration_max)
ld b, a
iteration_loop push bc ; iteration -> stack
; z2 = (z_0 * z_0 - z_1 * z_1) / SCALE;
ld de, (z_1) ; Compute DE HL = z_1 * z_1
ld bc, de
call mul_16
ld (z_0_square_low), hl ; z_0 ** 2 is needed later again
ld (z_0_square_high), de
 
ld de, (z_0) ; Compute DE HL = z_0 * z_0
ld bc, de
call mul_16
ld (z_1_square_low), hl ; z_1 ** 2 will be also needed
ld (z_1_square_high), de
 
and a ; Compute subtraction
ld bc, (z_0_square_low)
sbc hl, bc
ld (scratch_0), hl ; Save lower 16 bit of result
ld hl, de
ld bc, (z_0_square_high)
sbc hl, bc
ld bc, (scratch_0) ; HL BC = z_0 ** 2 - z_1 ** 2
 
ld c, b ; Divide by scale = 256
ld b, l ; Discard the rest
push bc ; We need BC later
 
; z3 = 2 * z0 * z1 / SCALE;
ld hl, (z_0) ; Compute DE HL = 2 * z_0 * z_1
add hl, hl
ld de, hl
ld bc, (z_1)
call mul_16
 
ld b, e ; Divide by scale (= 256)
ld c, h ; BC contains now z_3
 
; z1 = z3 + y;
ld hl, (y)
add hl, bc
ld (z_1), hl
 
; z_0 = z_2 + x;
pop bc ; Here BC is needed again :-)
ld hl, (x)
add hl, bc
ld (z_0), hl
 
; if (z0 * z0 / SCALE + z1 * z1 / SCALE > 4 * SCALE)
ld hl, (z_0_square_low) ; Use the squares computed
ld de, (z_1_square_low) ; above
add hl, de
ld bc, hl ; BC contains lower word of sum
 
ld hl, (z_0_square_high)
ld de, (z_1_square_high)
adc hl, de
 
ld h, l ; HL now contains (z_0 ** 2 +
ld l, b ; z_1 ** 2) / scale
 
ld bc, divergent
and a
sbc hl, bc
 
; break;
jp c, iteration_dec ; No break
pop bc ; Get latest iteration counter
jr iteration_end ; Exit loop
 
; iteration++;
iteration_dec pop bc ; Get iteration counter
djnz iteration_loop ; We might fall through!
; }
iteration_end
; printf("%c", display[iteration % 7]);
ld a, b
and $7 ; lower three bits only (c = 0)
sbc hl, hl
ld l, a
ld de, display ; Get start of character array
add hl, de ; address and load the
ld a, (hl) ; character to be printed
ld ix, _putc ; Print the character
rst 08
 
ld de, (x_step) ; x += x_step
ld hl, (x)
add hl, de
ld (x), hl
 
jp inner_loop
; }
; printf("\n");
inner_loop_end ld ix, _crlf ; Print a CR/LF pair
rst 08
 
ld de, (y_step) ; y += y_step
ld hl, (y)
add hl, de
ld (y), hl ; Store new y-value
 
jp outer_loop
; }
 
mandel_end ld hl, finished ; Print finished-message
ld ix, _puts
rst 08
 
rst 0 ; Return to the monitor
 
welcome defb "Generating a Mandelbrot set"
defb cr, lf, eos
finished defb "Computation finished.", cr, lf, eos
 
iteration_max defb 10 ; How many iterations
x defw 0 ; x-coordinate
x_start defw -2 * scale ; Minimum x-coordinate
x_end defw 5 * scale / 10 ; Maximum x-coordinate
x_step defw 4 * scale / 100 ; x-coordinate step-width
y defw -1 * scale ; Minimum y-coordinate
y_end defw 1 * scale ; Maximum y-coordinate
y_step defw 1 * scale / 10 ; y-coordinate step-width
z_0 defw 0
z_1 defw 0
scratch_0 defw 0
z_0_square_high defw 0
z_0_square_low defw 0
z_1_square_high defw 0
z_1_square_low defw 0
display defb " .-+*=#@" ; 8 characters for the display
 
;
; Compute DEHL = BC * DE (signed): This routine is not too clever but it
; works. It is based on a standard 16-by-16 multiplication routine for unsigned
; integers. At the beginning the sign of the result is determined based on the
; signs of the operands which are negated if necessary. Then the unsigned
; multiplication takes place, followed by negating the result if necessary.
;
mul_16 xor a ; Clear carry and A (-> +)
bit 7, b ; Is BC negative?
jr z, bc_positive ; No
sub c ; A is still zero, complement
ld c, a
ld a, 0
sbc a, b
ld b, a
scf ; Set carry (-> -)
bc_positive bit 7, D ; Is DE negative?
jr z, de_positive ; No
push af ; Remember carry for later!
xor a
sub e
ld e, a
ld a, 0
sbc a, d
ld d, a
pop af ; Restore carry for complement
ccf ; Complement Carry (-> +/-?)
de_positive push af ; Remember state of carry
and a ; Start multiplication
sbc hl, hl
ld a, 16 ; 16 rounds
mul_16_loop add hl, hl
rl e
rl d
jr nc, mul_16_exit
add hl, bc
jr nc, mul_16_exit
inc de
mul_16_exit dec a
jr nz, mul_16_loop
pop af ; Restore carry from beginning
ret nc ; No sign inversion necessary
xor a ; Complement DE HL
sub l
ld l, a
ld a, 0
sbc a, h
ld h, a
ld a, 0
sbc a, e
ld e, a
ld a, 0
sbc a, d
ld d, a
ret
 
Output:
Generating a Mandelbrot set
.......       @@@@@@@@@@@@@@@@@@@@########===*+  .  *######@@@@@ 
......     @@@@@@@@@@@@@@@@@@@@#########====+-.    -*===#####@@@@
.....   @@@@@@@@@@@@@@@@@@@@#########===**+-         +*====####@@
....  @@@@@@@@@@@@@@@@@@@########==*+-.-+-..         .-+****+*##@
...  @@@@@@@@@@@@@@@@@#####=====**+-                          -=#
.. @@@@@@@@@@@@@@@###=========***+-                          -*==
..@@@@@@@@@@####==- +*******++++-                             -+=
. @@@@#######===**-          ...                               -*
.@@#######======++-                                            +=
.#######=****+-                                               +*=
.=**++ .-....                                               .+*==
.#=====****+++.                                              -*==
.@#######=====*---                                            .*=
.@@@########====*++.                                           +=
. @@@@@@@######==*+ .-++- --++--.                               =
.. @@@@@@@@@@@@@##==*=======****+                            -+*=
... @@@@@@@@@@@@@@@@####=======***+-                          +==
...  @@@@@@@@@@@@@@@@@@@######====*-    .               --+-  *##
....   @@@@@@@@@@@@@@@@@@@@########==****++-        .-+**====###@
.....    @@@@@@@@@@@@@@@@@@@@##########===*+         *===#####@@@
.......     @@@@@@@@@@@@@@@@@@@@@########===*+-.  .+*=######@@@@@
Computation finished.

[edit] zkl

Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl

Translation of: XPL0
fcn mandelbrot{  // lord this is slooooow
bitmap:=PPM(640,480);
foreach y,x in ([0..479],[0..639]){
cx:=(x.toFloat()/640 - 0.5)*4.0; //range: -2.0 to +2.0
cy:=((y-240).toFloat()/240.0)*1.5; //range: -1.5 to +1.5
cnt:=0; zx:=0.0; zy:=0.0;
do(1000){
if(zx*zx + zy*zy > 2.0){ //z heads toward infinity
//set color of pixel to rate it approaches infinity
bitmap[x,y]=cnt.shiftLeft(21) + cnt.shiftLeft(10) + cnt*8;
break;
}
temp:=zx*zy;
zx=zx*zx - zy*zy + cx; //calculate next iteration of z
zy=2.0*temp + cy;
cnt+=1;
}
}
bitmap.write(File("foo.ppm","wb"));
}();
Output:

Same as the XPL0 image: MandelXPL0.png

Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox