Mandelbrot set: Difference between revisions

m
Replace deprecated functions
(→‎Normal Map Effect, Mercator Projection and Perturbation Theory: Correcting recent changes (they contained a silly bug))
m (Replace deprecated functions)
(77 intermediate revisions by 12 users not shown)
Line 1,856:
!!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""
</pre>
 
=={{header|bc}}==
 
[[File:Mandelbrot-bc.jpg|thumb|right]]
Producing a [https://fr.wikipedia.org/wiki/Portable_pixmap PGM] image.
 
To work properly, this needs to run with the environment variable BC_LINE_LENGTH set to 0.
 
<syntaxhighlight lang=bc>max_iter = 50
width = 400; height = 401
scale = 10
xmin = -2; xmax = 1/2
ymin = -5/4; ymax = 5/4
 
define mandelbrot(c_re, c_im) {
auto i
 
# z = 0
z_re = 0; z_im = 0
z2_re = 0; z2_im = 0
 
for (i=0; i<max_iter; i++) {
# z *= z
z_im = 2*z_re*z_im
z_re = z2_re - z2_im
# z += c
z_re += c_re
z_im += c_im
# z2 = z.*z
z2_re = z_re*z_re
z2_im = z_im*z_im
if (z2_re + z2_im > 4) return i
}
return 0
}
 
print "P2\n", width, " ", height, "\n255\n"
 
for (i = 0; i < height; i++) {
y = ymin + (ymax - ymin) / height * i
for (j = 0; j < width; j++) {
x = xmin + (xmax - xmin) / width * j
tmp_scale = scale
scale = 0
m = (255 * mandelbrot(x, y) + max_iter + 1) / max_iter
print m
if ( j < width - 1 ) print " "
scale = tmp_scale
 
}
print "\n"
}
 
quit</syntaxhighlight>
 
=={{header|BASIC}}==
Line 2,488 ⟶ 2,542:
180 GOTO 180
</syntaxhighlight>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
{{trans|Microsoft Super Extended Color BASIC}}
<syntaxhighlight lang="qbasic">100 SCREEN 2
110 CLS
120 x1 = 256 : y1 = 192
130 i1 = -1 : i2 = 1
140 r1 = -2 : r2 = 1
150 s1 = (r2-r1)/x1 : s2 = (i2-i1)/y1
160 FOR y = 0 TO y1
170 i3 = i1+s2*y
180 FOR x = 0 TO x1
190 r3 = r1+s1*x
200 z1 = r3 : z2 = i3
210 FOR n = 0 TO 30
220 a = z1*z1 : b = z2*z2
230 IF a+b > 4 GOTO 270
240 z2 = 2*z1*z2+i3
250 z1 = a-b+r3
260 NEXT n
270 PSET (x,y),n-16*INT(n/16)
280 NEXT x
290 NEXT y
300 GOTO 300</syntaxhighlight>
{{out}}
[[File:Mandelbrot-MS-BASIC.png]]
 
==={{header|Nascom BASIC}}===
Line 2,890 ⟶ 2,971:
Pt-On(real(C),imag(C),N
End
End</syntaxhighlight>
End
 
</syntaxhighlight>
==={{header|True BASIC}}===
{{trans|Microsoft Super Extended Color BASIC}}
<syntaxhighlight lang="qbasic">SET WINDOW 0, 256, 0, 192
 
LET x1 = 256/2
LET y1 = 192/2
LET i1 = -1
LET i2 = 1
LET r1 = -2
LET r2 = 1
LET s1 = (r2-r1) / x1
LET s2 = (i2-i1) / y1
 
FOR y = 0 TO y1 STEP .05
LET i3 = i1 + s2 * y
FOR x = 0 TO x1 STEP .05
LET r3 = r1 + s1 * x
LET z1 = r3
LET z2 = i3
FOR n = 0 TO 30
LET a = z1 * z1
LET b = z2 * z2
IF a+b > 4 THEN EXIT FOR
LET z2 = 2 * z1 * z2 + i3
LET z1 = a - b + r3
NEXT n
SET COLOR n - 16*INT(n/16)
PLOT POINTS: x,y
NEXT x
NEXT y
END</syntaxhighlight>
 
==={{header|Visual BASIC for Applications on Excel}}===
{{works with|Excel 2013}}
Based on the BBC BASIC version. Create a spreadsheet with -2 to 2 in row 1 and -2 to 2 in the A column (in steps of your choosing). In the cell B2, call the function with =mandel(B$1,$A2) and copy the cell to all others in the range. Conditionally format the cells to make the colours pleasing (eg based on values, 3-color scale, min value 2 [colour red], midpoint number 10 [green] and highest value black. Then format the cells with the custom type "";"";"" to remove the numbers.
<syntaxhighlight lang="vba">Function mandel(xi As Double, yi As Double)
Function mandel(xi As Double, yi As Double)
 
maxiter = 256
Line 2,911 ⟶ 3,022:
mandel = i
End Function</syntaxhighlight>
</syntaxhighlight>
[[File:vbamandel.png]]
Edit: I don't seem to be able to upload the screenshot, so I've shared it here: https://goo.gl/photos/LkezpuQziJPAtdnd9
Line 4,751 ⟶ 4,861:
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">titledefine "Mandelbrot"max = 15, w = 640, h = 480
 
define max = 15, w = 640, h = 480
define py = 0, px = 0, sx = 0, sy = 0
define xx = 0, xy = 0
 
bgcolor 0, 0, 0
cls graphics
alert "mandelbrot"
fill on
 
Line 4,798 ⟶ 4,905:
let py = py + 4
 
loop py < h</syntaxhighlight>
 
fgcolor 255, 255, 0
print "done"
 
end</syntaxhighlight>
 
=={{header|D}}==
Line 4,955 ⟶ 5,057:
=={{header|Dc}}==
===ASCII output===
{{works with|GNU Dcdc}}
{{works with|OpenBSD Dcdc}}
 
This can be done in a more Dc-ish way, e.g. by moving the loop macros' definitions to the initialisations in the top instead of saving the macro definition of inner loops over and over again in outer loops.
Line 5,123 ⟶ 5,225:
=={{header|EasyLang}}==
 
[https://easylang.onlinedev/apps/mandelbrot.html Run it]
 
<syntaxhighlight lang="easylang">
# Mandelbrot
for y0 = 0 to 299
#
cy = (y0 - 150) / 120
res = 4
for x0 = 0 to 299
maxiter = 200
cx = (x0 - 220) / 120
#
x = 0 ; y = 0 ; iter = 0
# better but slower:
while iter < 64 and x * x + y * y < 4
# res = 8
h = x * x - y * y + cx
# maxiter = 300
#
#
mid = res * 50
center_x = 3 * mid / 2
center_y = mid
scale = mid
#
background 000
textsize 2
#
fastfunc iter cx cy maxiter .
while xx + yy < 4 and it < maxiter
y = 2 * x * y + cy
x = hxx - yy + cx
iterxx += 1x * x
. yy = y * y
if iter it += 641
iter = 0.
return .it
.
color3 iter / 16 0 0
proc draw . .
move x0 / 3 y0 / 3
clear
rect 0.4 0.4
for scr_y = 0 to 2 * mid - 1
.
cy = (scr_y - center_y) / scale
for scr_x = 0 to 2 * mid - 1
cx = (scr_x - center_x) / scale
it = iter cx cy maxiter
if it < maxiter
color3 it / 20 it / 100 it / 150
move scr_x / res scr_y / res
rect 1 / res 1 / res
.
.
.
color 990
move 1 1
text "Short press to zoom in, long to zoom out"
.
on mouse_down
time0 = systime
.
on mouse_up
center_x += mid - mouse_x * res
center_y += mid - mouse_y * res
if systime - time0 < 0.3
center_x -= mid - center_x
center_y -= mid - center_y
scale *= 2
else
center_x += (mid - center_x) * 3 / 4
center_y += (mid - center_y) * 3 / 4
scale /= 4
.
draw
.
draw
</syntaxhighlight>
 
Line 6,345 ⟶ 6,492:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Mandelbrot_set}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
We need first to generate a color palette, this is, a list of colors:
In '''[https://formulae.org/?example=Mandelbrot_set this]''' page you can see the program(s) related to this task and their results.
 
[[File:Fōrmulæ - Julia set 01.png]]
 
[[File:Fōrmulæ - Julia set 02.png]]
 
[[File:Fōrmulæ - Julia set 03.png]]
 
The following function draw the Mandelbrot set:
 
[[File:Fōrmulæ - Mandelbrot set 01.png]]
 
'''Test Case 1. Grayscale palette'''
 
[[File:Fōrmulæ - Mandelbrot set 02.png]]
 
[[File:Fōrmulæ - Mandelbrot set 03.png]]
 
'''Test case 2. Black & white palette'''
 
[[File:Fōrmulæ - Mandelbrot set 04.png]]
 
[[File:Fōrmulæ - Mandelbrot set 05.png]]
 
=={{header|GLSL}}==
Line 7,330 ⟶ 7,499:
 
[[File:Mandelbrot-Inform7.png]]
 
=={{Header|Insitux}}==
 
<syntaxhighlight lang="insitux">
(function mandelbrot width height depth
(.. str
(for yy (range height)
xx (range width)
(let c_re (/ (* (- xx (/ width 2)) 4) width)
c_im (/ (* (- yy (/ height 2)) 4) width)
x 0 y 0 i 0)
(while (and (<= (+ (** x) (** y)) 4)
(< i depth))
(let x2 (+ c_re (- (** x) (** y)))
y (+ c_im (* 2 x y))
x x2
i (inc i)))
(strn ((zero? xx) "\n") (i "ABCDEFGHIJ ")))))
 
(mandelbrot 48 24 10)
</syntaxhighlight>
 
{{out}}
 
<pre>
 
BBBBCCCDDDDDDDDDEEEEFGJJ EEEDDCCCCCCCCCCCCCCCBBB
BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB
BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB
BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB
BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB
BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB
BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC
BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC
BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC
BDEEEFFFHJ FEDDDDCCCCCCCCCCCC
BEEEFFFIJ FEEDDDCCCCCCCCCCCC
BEEFGGH HFEEDDDCCCCCCCCCCCC
JGFEEDDDDCCCCCCCCCCC
BEEFGGH HFEEDDDCCCCCCCCCCCC
BEEEFFFIJ FEEDDDCCCCCCCCCCCC
BDEEEFFFHJ FEDDDDCCCCCCCCCCCC
BDDEEEEFG J JI GEDDDDCCCCCCCCCCCC
BDDDDDEEFJGGGHHI IFEDDDDCCCCCCCCCCCC
BCDDDDDDEEFFFFGG GFEDDDCCCCCCCCCCCCC
BBDDDDDDDDEEFFFGH IEDDDDCCCCCCCCCCCCB
BBCDDDDDDDDEEEEFG HIGEDDDCCCCCCCCCCCCCB
BBCCDDDDDDDDDEEEEGGHI HGFFEDDDCCCCCCCCCCCCCCB
BBBCDDDDDDDDDDEEEEFFH GFFEEDDDCCCCCCCCCCCCCBB
BBBCCDDDDDDDDDDEEEEFFH HFEEEDDDCCCCCCCCCCCCCCBB
</pre>
 
=={{header|J}}==
Line 7,958 ⟶ 8,178:
 
===Normal Map Effect, Mercator Projection and Perturbation Theory===
 
This is a translation of the corresponding Python section: see there for more explanations. The Mandelbrot set is represented by distance estimation and normal maps using complex matrices (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']).
'''Normalization, Distance Estimation and Boundary Detection'''
 
This is a translation of the corresponding Python section: see there for more explanations. The ''e^(-|z|)-smoothing'', ''normalized iteration count'' and ''exterior distance estimation'' algorithms are used. Partial antialiasing is used for boundary detection.
<syntaxhighlight lang="julia">using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
Line 7,964 ⟶ 8,187:
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
 
direction, height = 45, 1.5 # direction and height of the incoming light
v = exp(direction / 180 * pi * im) # unit 2D vector in this direction
 
x = range(0, 2, length=d+1)
Line 7,972 ⟶ 8,192:
 
A, B = collect(x) .- 1, collect(y) .- h / d
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
 
Z, dZ, ddZ = zero(C), zero(C), zero(C)
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
 
iteration(Z, dZ, ddZ, C) = Z .^ 2 .+ C, 2 .* Z .* dZ .+ 1, 2 .* (dZ .^ 2 .+ Z .* ddZ)
for k in 1:n
M = abs2abs.(Z) .< abs2(r)
ZS[M], dZT[M], ddZ= S[M] =.+ iterationexp.(.- abs.(Z[M])), dZT[M], ddZ[M],.+ C[M])1
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
end
 
heatmap(S .^ 0.1, c=:balance)
savefig("Mandelbrot_set_1.png")
 
N = abs.(Z) .>= r # normalized iteration count
T[N] = T[N] .- log2.(log.(abs.(Z[N])) ./ log(r))
 
heatmap(T .^ 0.1, c=:balance)
savefig("Mandelbrot_set_2.png")
 
N = abs.(Z) .> 2 # exterior distance estimation
Line 7,987 ⟶ 8,216:
 
heatmap(D .^ 0.1, c=:balance)
savefig("Mandelbrot_distance_estMandelbrot_set_3.png")
 
N, thickness = D .> 0, 0.01 # boundary detection
N = abs.(Z) .> 2 # normal map effect 1 (potential function)
D[N] = max.(1 .- D[N] ./ thickness, 0)
U = Z[N] ./ dZ[N] # normal vectors to the equipotential lines
U, S = U ./ abs.(U), 1 .+ sin.(100 .* angle.(U)) ./ 10 # unit vectors and stripes
T[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ S .* height) ./ (1 + height), 0)
 
heatmap(TD .^ 12.0, c=:bone_1binary)
savefig("Mandelbrot_set_4.png")</syntaxhighlight>
 
'''Normal Map Effect and Stripe Average Coloring'''
 
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the ''density'' of the stripes, use ''cos'' instead of ''sin'', and set the colormap to ''binary''.
<syntaxhighlight lang="julia">using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
 
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
 
direction, height = 45.0, 1.5 # direction and height of the light
density, intensity = 4.0, 0.5 # density and intensity of the stripes
 
x = range(0, 2, length=d+1)
y = range(0, 2 * h / d, length=h+1)
 
A, B = collect(x) .- 1, collect(y) .- h / d
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
 
Z, dZ, ddZ = zero(C), zero(C), zero(C)
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
 
for k in 1:n
M = abs.(Z) .< r
S[M], T[M] = S[M] .+ sin.(density .* angle.(Z[M])), T[M] .+ 1
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M])
end
 
N = abs.(Z) .>= r # basic normal map effect and stripe average coloring (potential function)
P, Q = S[N] ./ T[N], (S[N] .+ sin.(density .* angle.(Z[N]))) ./ (T[N] .+ 1)
U, V = Z[N] ./ dZ[N], 1 .+ (log2.(log.(abs.(Z[N])) ./ log(r)) .* (P .- Q) .+ Q) .* intensity
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0)
 
heatmap(D .^ 1.0, c=:bone_1)
savefig("Mandelbrot_normal_map_1.png")
 
N = abs.(Z) .> 2 # advanced normal map effect 2using higher derivatives (distance estimation)
normal(L, Z, A, B)U = Z[N] .* AdZ[N] .* ((1 .+ Llog.(abs.(Z[N]))) .* conj.(AdZ[N] .^ 2) .- Llog.(abs.(Z[N])) .* conj.(Z[N] .* BddZ[N]))
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and light vector
U = normal(log.(abs.(Z[N])), Z[N], dZ[N], ddZ[N])
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
U = U ./ abs.(U) # unit normal vectors to the equidistant lines
T[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
 
heatmap(TD .^ 1.0, c=:afmhot)
savefig("Mandelbrot_normal_map_2.png")</syntaxhighlight>
 
'''Mercator Mandelbrot Maps and Zoom Images'''
A small change in the code above creates Mercator maps and zoom images of the Mandelbrot set. See also the album [https://www.flickr.com/photos/arenamontanus/albums/72157615740829949 Mercator Mandelbrot Maps] by Anders Sandberg.
 
A small change in the code above creates Mercator maps and zoom images of the Mandelbrot set. See also the album [https://www.flickr.com/photos/arenamontanus/albums/72157615740829949 Mercator Mandelbrot Maps] by Anders Sandberg and [https://commons.wikimedia.org/wiki/File:Mandelbrot_sequence_new.gif ''Mandelbrot sequence new''] on Wikimedia for a zoom animation to the given coordinates.
<syntaxhighlight lang="julia">using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
 
d, h = 200, 1200 # pixel density (= image width) and image height
n, r = 8008000, 100010000 # number of iterations and escape radius (r > 2)
 
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800
 
x = range(0, 2, length=d+1)
Line 8,017 ⟶ 8,284:
 
A, B = collect(x) .* pi, collect(y) .* pi
C = (- 8.0im)0 .* exp.((A' .+ B .* im) .* im) .+ (- 0.7436636774a + 0.1318632144imb * im)
 
Z, dZ = zero(C), zero(C)
D = zeros(size(C))
 
iteration(Z, dZ, C) = Z .^ 2 .+ C, 2 .* Z .* dZ .+ 1
for k in 1:n
M = abs2.(Z) .< abs2(r)
Z[M], dZ[M] = iteration(Z[M], dZ.^ 2 .+ C[M], C2 .* Z[M]) .* dZ[M] .+ 1
end
 
Line 8,031 ⟶ 8,297:
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
 
heatmap(D' .^ 0.105, c=:nipy_spectral)
savefig("Mercator_Mandelbrot_map.png")
 
Line 8,038 ⟶ 8,304:
 
gr(c=:nipy_spectral, axis=true, ticks=true, legend=false, markerstrokewidth=0)
p1 = scatter(X[1z+1:1z+c,1:d], Y[1z+1:1z+c,1:d], markersize=R[1:c].^.5, marker_z=D[1z+1:1z+c,1:d].^.5)
p2 = scatter(X[2z+1:2z+c,1:d], Y[2z+1:2z+c,1:d], markersize=R[1:c].^.5, marker_z=D[2z+1:2z+c,1:d].^.4)
p3 = scatter(X[3z+1:3z+c,1:d], Y[3z+1:3z+c,1:d], markersize=R[1:c].^.5, marker_z=D[3z+1:3z+c,1:d].^.3)
p4 = scatter(X[4z+1:4z+c,1:d], Y[4z+1:4z+c,1:d], markersize=R[1:c].^.5, marker_z=D[4z+1:4z+c,1:d].^.2)
plot(p1, p2, p3, p4, layout=(2, 2))
savefig("Mercator_Mandelbrot_zoom.png")</syntaxhighlight>
 
'''Perturbation Theory and Deep Mercator Maps'''
 
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See [https://fractalforums.org/fractal-mathematics-and-new-theories/28/another-solution-to-perturbation-glitches/4360 Another solution to perturbation glitches] (Fractalforums) for details. See also the image [https://www.flickr.com/photos/arenamontanus/3430921497/in/album-72157615740829949/ Deeper Mercator Mandelbrot] by Anders Sandberg.
Line 8,061 ⟶ 8,329:
let c = a + b * im, z = zero(c)
for k in 1:n+1
S[k] = z
if abs2(z) < abs2(r)
S[k] = z
z = z ^ 2 + c
else
printprintln("ReferenceThe reference sequence diverges inwithin $(k-1) iterations (image may be damaged).\n")
print("Make sure that maximum(I) is below this limit.\n")
break
end
Line 8,076 ⟶ 8,343:
 
A, B = collect(x) .* pi, collect(y) .* pi
C = (- 48.0) .* exp.((A' .+ B .* im) .* im)
 
E, Z, dZ = zero(C), zero(C), zero(C)
D, I, J = zeros(size(C)), ones(Int64, size(C)), ones(Int64, size(C))
 
iteration(E, C, I) = (2 .* S[I] .+ E) .* E .+ C, I .+ 1
for k in 1:n
M, R = abs2.(Z) .< abs2(r), abs2.(Z) .< abs2.(E)
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero
E[M], I[M] = iteration(2 .* S[I[M]] .+ E[M],) .* E[M] .+ C[M], I[M]) .+ 1
Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1
end
Line 9,151 ⟶ 9,417:
Sample usage:
<syntaxhighlight lang="matlab">mandelbrotSet(-2.05-1.2i,0.004+0.0004i,0.45+1.2i,500);</syntaxhighlight>
 
=={{header|Maxima}}==
Using autoloded package plotdf
<syntaxhighlight lang="maxima">
mandelbrot ([iterations, 30], [x, -2.4, 0.75], [y, -1.2, 1.2],
[grid,320,320])$
</syntaxhighlight>
[[File:MandelbrotMaxima.png|thumb|center]]
 
=={{header|Metapost}}==
Line 10,886 ⟶ 11,160:
 
===Normal Map Effect, Mercator Projection and Deep Zoom Images===
 
The Mandelbrot set is represented by distance estimation and normal maps using NumPy and complex matrices (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). Note that the second derivative (ddZ) grows very fast, so the second method can only be used for small iteration numbers (n <= 400).
'''Normalization, Distance Estimation and Boundary Detection'''
 
The Mandelbrot set is printed with smooth colors. The ''e^(-|z|)-smoothing'', ''normalized iteration count'' and ''exterior distance estimation'' algorithms are used with NumPy and complex matrices (see Javier Barrallo & Damien M. Jones: [http://www.mi.sanu.ac.rs/vismath/javier/index.html ''Coloring Algorithms for Dynamical Systems in the Complex Plane''] and Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Boundary_detection_methods_via_distance_estimators ''Boundary detection methods via distance estimators'']). Partial antialiasing is used for boundary detection.
<syntaxhighlight lang="python">import numpy as np
import matplotlib.pyplot as plt
Line 10,892 ⟶ 11,169:
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
 
direction, height = 45, 1.5 # direction and height of the incoming light
v = np.exp(direction / 180 * np.pi * 1j) # unit 2D vector in this direction
 
x = np.linspace(0, 2, num=d+1)
Line 10,900 ⟶ 11,174:
 
A, B = np.meshgrid(x - 1, y - h / d)
C = (2.0 + 1.0j) * (A + B * 1j) - 0.5
 
Z, dZ, ddZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C)
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape)
 
for k in range(n):
M = abs(Z.real ** 2 + Z.imag ** 2) < r ** 2
ZM, dZMS[M], ddZM, CM = ZT[M], dZ= S[M], ddZ+ np.exp(- abs(Z[M])), CT[M] + 1
Z[M], dZ[M], ddZ= Z[M] = ZM ** 2 + CMC[M], 2 * ZMZ[M] * dZMdZ[M] + 1, 2 * (dZM ** 2 + ZM * ddZM)
 
plt.imshow(S ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_set_1.png", dpi=200)
 
N = abs(Z) >= r # normalized iteration count
T[N] = T[N] - np.log2(np.log(np.abs(Z[N])) / np.log(r))
 
plt.imshow(T ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_set_2.png", dpi=200)
 
N = abs(Z) > 2 # exterior distance estimation
Line 10,914 ⟶ 11,197:
 
plt.imshow(D ** 0.1, cmap=plt.cm.twilight_shifted, origin="lower")
plt.savefig("Mandelbrot_distance_estMandelbrot_set_3.png", dpi=200)
 
N, thickness = D > 0, 0.01 # boundary detection
N = abs(Z) > 2 # normal map effect 1 (potential function)
D[N] = np.maximum(1 - D[N] / thickness, 0)
U = Z[N] / dZ[N] # normal vectors to the equipotential lines
U, S = U / abs(U), 1 + np.sin(100 * np.angle(U)) / 10 # unit vectors and stripes
T[N] = np.maximum((U.real * v.real + U.imag * v.imag + S * height) / (1 + height), 0)
 
plt.imshow(TD ** 12.0, cmap=plt.cm.bonebinary, origin="lower")
plt.savefig("Mandelbrot_set_4.png", dpi=200)</syntaxhighlight>
 
'''Normal Map Effect and Stripe Average Coloring'''
 
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). Note that the second derivative (ddZ) grows very fast, so the second method can only be used for small iteration numbers (n <= 400). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, one can increase the ''density'' of the stripes, use ''cos'' instead of ''sin'', and set the colormap to ''binary''.
<syntaxhighlight lang="python">import numpy as np
import matplotlib.pyplot as plt
 
d, h = 800, 500 # pixel density (= image width) and image height
n, r = 200, 500 # number of iterations and escape radius (r > 2)
 
direction, height = 45.0, 1.5 # direction and height of the light
density, intensity = 4.0, 0.5 # density and intensity of the stripes
 
x = np.linspace(0, 2, num=d+1)
y = np.linspace(0, 2 * h / d, num=h+1)
 
A, B = np.meshgrid(x - 1, y - h / d)
C = (2.0 + 1.0j) * (A + B * 1j) - 0.5
 
Z, dZ, ddZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C)
D, S, T = np.zeros(C.shape), np.zeros(C.shape), np.zeros(C.shape)
 
for k in range(n):
M = abs(Z) < r
S[M], T[M] = S[M] + np.sin(density * np.angle(Z[M])), T[M] + 1
Z[M], dZ[M], ddZ[M] = Z[M] ** 2 + C[M], 2 * Z[M] * dZ[M] + 1, 2 * (dZ[M] ** 2 + Z[M] * ddZ[M])
 
N = abs(Z) >= r # basic normal map effect and stripe average coloring (potential function)
P, Q = S[N] / T[N], (S[N] + np.sin(density * np.angle(Z[N]))) / (T[N] + 1)
U, V = Z[N] / dZ[N], 1 + (np.log2(np.log(np.abs(Z[N])) / np.log(r)) * (P - Q) + Q) * intensity
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors and light vector
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + V * height) / (1 + height), 0)
 
plt.imshow(D ** 1.0, cmap=plt.cm.bone, origin="lower")
plt.savefig("Mandelbrot_normal_map_1.png", dpi=200)
 
N = abs(Z) > 2 # advanced normal map effect 2using higher derivatives (distance estimation)
LN,U ZN,= AN,Z[N] BN* =dZ[N] * ((1 + np.log(abs(Z[N])),) * np.conj(dZ[N] ** 2) - np.log(abs(Z[N],)) dZ* np.conj(Z[N], * ddZ[N]))
U, v = ZNU */ ANabs(U), * (np.exp(1direction +/ LN)180 * np.conj(ANpi ** 21j) - LN# *unit np.conj(ZNnormal *vectors BN))and light vector
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + height) / (1 + height), 0)
U = U / abs(U) # unit normal vectors to the equidistant lines
T[N] = np.maximum((U.real * v.real + U.imag * v.imag + height) / (1 + height), 0)
 
plt.imshow(TD ** 1.0, cmap=plt.cm.afmhot, origin="lower")
plt.savefig("Mandelbrot_normal_map_2.png", dpi=200)</syntaxhighlight>
 
'''Mercator Mandelbrot Maps and Zoom Images'''
A small change in the code above creates Mercator maps of the Mandelbrot set (see David Madore: [http://www.madore.org/~david/math/mandelbrot.html ''Mandelbrot set images and videos''] and Anders Sandberg: [https://www.flickr.com/photos/arenamontanus/sets/72157615740829949 ''Mercator Mandelbrot Maps'']). The maximum magnification is about <math>e ^ {2 \pi \cdot h / d} = e ^ {2 \pi \cdot 5.5} \approx 535.5 ^ {5.5} \approx 10 ^ {15}</math>, which is also the maximum for 64-bit arithmetic. Note that Anders Sandberg uses a different scaling. He uses <math>10 ^ {3 \cdot h / d} = 1000 ^ {h / d}</math> instead of <math>e ^ {2 \pi \cdot h / d} \approx 535.5 ^ {h / d}</math>, so his images appear somewhat compressed in comparison (but not much, because <math>1000 ^ {5.0} \approx 535.5 ^ {5.5}</math>). With the same pixel density and the same maximum magnification, the difference in height between the maps is only about 10 percent. By misusing a scatter plot, it is possible to create zoom images of the Mandelbrot set.
 
A small change in the code above creates Mercator maps of the Mandelbrot set (see David Madore: [http://www.madore.org/~david/math/mandelbrot.html ''Mandelbrot set images and videos''] and Anders Sandberg: [https://www.flickr.com/photos/arenamontanus/sets/72157615740829949 ''Mercator Mandelbrot Maps'']). The maximum magnification is about <math>e ^ {2 \pi \cdot h / d} = e ^ {2 \pi \cdot 5.5} \approx 535.5 ^ {5.5} \approx 10 ^ {15}</math>, which is also the maximum for 64-bit arithmetic. Note that Anders Sandberg uses a different scaling. He uses <math>10 ^ {3 \cdot h / d} = 1000 ^ {h / d}</math> instead of <math>e ^ {2 \pi \cdot h / d} \approx 535.5 ^ {h / d}</math>, so his images appear somewhat compressed in comparison (but not much, because <math>1000 ^ {5.0} \approx 535.5 ^ {5.5}</math>). With the same pixel density and the same maximum magnification, the difference in height between the maps is only about 10 percent. By misusing a scatter plot, it is possible to create zoom images of the Mandelbrot set. See also [https://commons.wikimedia.org/wiki/File:Mandelbrot_sequence_new.gif ''Mandelbrot sequence new''] on Wikimedia for a zoom animation to the given coordinates.
<syntaxhighlight lang="python">import numpy as np
import matplotlib.pyplot as plt
 
d, h = 200, 1200 # pixel density (= image width) and image height
n, r = 8008000, 100010000 # number of iterations and escape radius (r > 2)
 
a = -.743643887037158704752191506114774 # https://mathr.co.uk/web/m-location-analysis.html
b = 0.131825904205311970493132056385139 # try: a, b, n = -1.748764520194788535, 3e-13, 800
 
x = np.linspace(0, 2, num=d+1)
Line 10,944 ⟶ 11,264:
 
A, B = np.meshgrid(x * np.pi, y * np.pi)
C = (- 8.0j)0 * np.exp((A + B * 1j) * 1j) + (- 0.7436636774a + 0.1318632144jb * 1j)
 
Z, dZ = np.zeros_like(C), np.zeros_like(C)
Line 10,951 ⟶ 11,271:
for k in range(n):
M = Z.real ** 2 + Z.imag ** 2 < r ** 2
ZMZ[M], dZM, CMdZ[M] = Z[M], dZ** 2 + C[M], C2 * Z[M] * dZ[M] + 1
Z[M], dZ[M] = ZM ** 2 + CM, 2 * ZM * dZM + 1
 
N = abs(Z) > 2 # exterior distance estimation
D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N])
 
plt.imshow(D.T ** 0.105, cmap=plt.cm.nipy_spectral, origin="lower")
plt.savefig("Mercator_Mandelbrot_map.png", dpi=200)
 
X, Y = C.real, C.imag # zoom images (adjust circle size 120100 and zoom level 20 as needed)
R, c, z = 120100 * (2 / d) * np.pi * np.exp(- B), min(d, h) + 1, max(0, h - d) // 20
 
fig, ax = plt.subplots(2, 2, figsize=(12, 12))
ax[0, 0].scatter(X[1*z:1*z+c,0:d], Y[1*z:1*z+c,0:d], s=R[0:c,0:d]**2, c=D[1*z:1*z+c,0:d]**0.5, cmap=plt.cm.nipy_spectral)
ax[0, 1].scatter(X[2*z:2*z+c,0:d], Y[2*z:2*z+c,0:d], s=R[0:c,0:d]**2, c=D[2*z:2*z+c,0:d]**0.4, cmap=plt.cm.nipy_spectral)
ax[1, 0].scatter(X[3*z:3*z+c,0:d], Y[3*z:3*z+c,0:d], s=R[0:c,0:d]**2, c=D[3*z:3*z+c,0:d]**0.3, cmap=plt.cm.nipy_spectral)
ax[1, 1].scatter(X[4*z:4*z+c,0:d], Y[4*z:4*z+c,0:d], s=R[0:c,0:d]**2, c=D[4*z:4*z+c,0:d]**0.2, cmap=plt.cm.nipy_spectral)
plt.savefig("Mercator_Mandelbrot_zoom.png", dpi=100)</syntaxhighlight>
 
'''Perturbation Theory and Deep Mercator Maps'''
 
For deep zoom images it is sufficient to calculate a single point with high accuracy. A good approximation can then be found for all other points by means of a perturbation calculation with standard accuracy. Rebasing is used to reduce glitches. See [https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set#Perturbation_theory_and_series_approximation Perturbation theory] (Wikipedia) and [https://gbillotey.github.io/Fractalshades-doc/math.html#avoiding-loss-of-precision Avoiding loss of precision] (Fractalshades) for details. See also the image [https://www.flickr.com/photos/arenamontanus/3430921497/in/album-72157615740829949/ Deeper Mercator Mandelbrot] by Anders Sandberg.
Line 10,987 ⟶ 11,308:
 
for k in range(n+1):
S[k] = float(u) + float(v) * 1j
if u ** 2 + v ** 2 < r ** 2:
S[k] = float(u) + float(v) * 1j
u, v = u ** 2 - v ** 2 + a, 2 * u * v + b
else:
print("ReferenceThe reference sequence diverges inwithin %s iterations (image may be damaged)." % k)
print("Make sure that I.max() is below this limit.")
break
 
x = np.linspace(0, 2, num=d+1, dtype=np.float64)
y = np.linspace(0, 2 * h / d, num=h+1, dtype=np.float64)
 
A, B = np.meshgrid(x * np.pi, y * np.pi)
C = (- 48.0) * np.exp((A + B * 1j) * 1j)
 
E, Z, dZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C)
Line 11,008 ⟶ 11,328:
M, R = Z2 < r ** 2, Z2 < E.real ** 2 + E.imag ** 2
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero
EME[M], CM, IMI[M] = (2 * S[I[M]] + E[M],) * E[M] + C[M], I[M] + 1
E[M], I[M] = (2 * S[IM] + EM) * EM + CM, IM + 1
Z[M], dZ[M] = S[I[M]] + E[M], 2 * Z[M] * dZ[M] + 1
 
Line 11,196 ⟶ 11,515:
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|20162023.08-053-01g2f8234c22}}
[[File:Mandel-perl6.png|thumb]]
Variant of a Mandelbrot script from the [http://modules.raku.org/ Raku ecosystem]. Produces a [[Write ppm file|Portable Pixel Map]] to STDOUT.
Redirect into a file to save it.
Converted to a .png file for display here.
 
Using the [https://docs.raku.org/language/statement-prefixes#hyper,_race hyper statement prefix] for concurrency, the code below produces a [[Write ppm file|graymap]] to standard output.
<syntaxhighlight lang="raku" line>constant @color_map = map ~*.comb(/../).map({:16($_)}), <
 
000000 0000fc 4000fc 7c00fc bc00fc fc00fc fc00bc fc007c fc0040 fc0000 fc4000
[[File:mandelbrot-raku.jpg|300px|thumb|right]]
fc7c00 fcbc00 fcfc00 bcfc00 7cfc00 40fc00 00fc00 00fc40 00fc7c 00fcbc 00fcfc
<syntaxhighlight lang=raku>constant MAX-ITERATIONS = 64;
00bcfc 007cfc 0040fc 7c7cfc 9c7cfc bc7cfc dc7cfc fc7cfc fc7cdc fc7cbc fc7c9c
my $width = +(@*ARGS[0] // 800);
fc7c7c fc9c7c fcbc7c fcdc7c fcfc7c dcfc7c bcfc7c 9cfc7c 7cfc7c 7cfc9c 7cfcbc
my $height = $width + $width %% 2;
7cfcdc 7cfcfc 7cdcfc 7cbcfc 7c9cfc b4b4fc c4b4fc d8b4fc e8b4fc fcb4fc fcb4e8
say "P2";
fcb4d8 fcb4c4 fcb4b4 fcc4b4 fcd8b4 fce8b4 fcfcb4 e8fcb4 d8fcb4 c4fcb4 b4fcb4
say "$width $height";
b4fcc4 b4fcd8 b4fce8 b4fcfc b4e8fc b4d8fc b4c4fc 000070 1c0070 380070 540070
say MAX-ITERATIONS;
700070 700054 700038 70001c 700000 701c00 703800 705400 707000 547000 387000
 
1c7000 007000 00701c 007038 007054 007070 005470 003870 001c70 383870 443870
sub cut(Range $r, UInt $n where $n > 1 --> Seq) {
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
>;
constant MAX_ITERATIONS = 50;
my $width = my $height = +(@*ARGS[0] // 31);
sub cut(Range $r, UInt $n where $n > 1) {
$r.min, * + ($r.max - $r.min) / ($n - 1) ... $r.max
}
 
my @re = cut(-2 .. 1/2, $width);
my @im = cut( 0 .. 5/4, 1 + ($height div 2)) X* 1i;
sub mandelbrot(Complex $z is copy, Complex $c --> Int) {
my @re = cut(-2 .. 1/2, $height);
for 1 .. MAX-ITERATIONS {
my @im = cut( 0 .. 5/4, $width div 2 + 1) X* 1i;
$z = $z*$z + $c;
return $_ if $z.abs > 2;
sub mandelbrot(Complex $z is copy, Complex $c) {
for 1 .. MAX_ITERATIONS {
$z = $z*$z + $c;
return $_ if $z.abs > 2;
}
return 0;
}
my @lines = hyper for @im X+ @re {
say "P3";
mandelbrot(0i, $_);
say "$width $height";
}.rotor($width);
say "255";
 
.put for @lines[1..*].reverse;
for @re -> $re {
.put for @lines;</syntaxhighlight>
put @color_map[|.reverse, |.[1..*]][^$width] given
 
my @ = map &mandelbrot.assuming(0i, *), $re «+« @im;
<!-- # Not sure this version is that much modern or faster now.
}</syntaxhighlight>
 
Alternately, a more modern, faster version.
[[File:Mandelbrot-set-perl6.png|300px|thumb|right]]
<syntaxhighlight lang="rakuperl6" line>use Image::PNG::Portable;
 
my ($w, $h) = 800, 800;
Line 11,302 ⟶ 11,601:
}
}</syntaxhighlight>
 
-->
 
=={{header|REXX}}==
Line 12,153 ⟶ 12,454:
# 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 comps7c -O2 mandelbr
 
const integer: pix is 200;
Line 12,185 ⟶ 12,486:
z0 := center + complex(flt(x) * zoom, flt(y) * zoom);
point(x + pix, y + pix, colorTable[iterate(z0)]);
end for;
end for;
end func;
Line 12,203 ⟶ 12,504:
end for;
displayMandelbrotSet(complex(-0.75, 0.0), 1.3 / flt(pix));
DRAW_FLUSHflushGraphic;
readln(KEYBOARD);
end func;
Line 12,970 ⟶ 13,271:
:End
</syntaxhighlight>
=={{header|Transact-SQL‎}}==
This is a Transact-SQL version of SQL Server to generate Mandelbrot set. Export the final result to a .ppm file to view the image. More details are available [https://krishnakumarsql.wordpress.com/2023/07/12/drawing-a-colorful-mandelbrot-set-in-sql-server/ here].
<syntaxhighlight lang="Transact-SQL‎">
-- Mandelbrot Set
-- SQL Server 2017 and above
SET NOCOUNT ON
GO
 
-- Plot area 800 X 800
DECLARE @width INT = 800
DECLARE @height INT = 800
 
DECLARE @r_min DECIMAL (10, 8) = -2.5;
DECLARE @r_max DECIMAL (10, 8) = 1.5;
DECLARE @r_step DECIMAL (10, 8) = 0.005;
DECLARE @i_min DECIMAL (10, 8) = -2;
DECLARE @i_max DECIMAL (10, 8) = 2;
DECLARE @i_step DECIMAL (10, 8) = 0.005;
 
DECLARE @iter INT = 255; -- Iteration
 
DROP TABLE IF EXISTS dbo.Numbers
DROP TABLE IF EXISTS dbo.mandelbrot_set;
 
CREATE TABLE dbo.Numbers (n INT);
 
-- Generate a number table of 1000 rows
;WITH N1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
N2(n) AS (SELECT 1 FROM N1 CROSS JOIN N1 AS b), -- 10*10
N3(n) AS (SELECT 1 FROM N1 CROSS JOIN N2) -- 10*100
INSERT INTO dbo.Numbers (n)
SELECT n = ROW_NUMBER() OVER (ORDER BY n)
FROM N3 ORDER BY n;
/*
-- If the version is SQL Server 2022 and above
INSERT INTO dbo.Numbers (n)
SELECT value FROM GENERATE_SERIES(0, 1000);
*/
 
 
CREATE TABLE dbo.mandelbrot_set
(
a INT,
b INT,
c_re DECIMAL (10, 8),
c_im DECIMAL (10, 8),
z_re DECIMAL (10, 8) DEFAULT 0,
z_im DECIMAL (10, 8) DEFAULT 0,
znew_re DECIMAL (10, 8) DEFAULT 0,
znew_im DECIMAL (10, 8) DEFAULT 0,
steps INT DEFAULT 0,
active BIT DEFAULT 1,
)
 
-- Store all the c_re, c_im corresponding to each point in the plot area
-- Generate 640,000 rows (800 X 800)
INSERT INTO dbo.mandelbrot_set (a, b, c_re, c_im, steps)
SELECT a.n as a, b.n as b
,(@r_min + (a.n * @r_step)) AS c_re
,(@i_min + (b.n * @i_step)) AS c_im
,@iter AS steps
FROM
(
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @width
) as a
CROSS JOIN
(
SELECT n - 1 as n FROM dbo.Numbers WHERE n <= @height
) as b;
 
-- Iteration
WHILE (@iter > 1)
BEGIN
 
UPDATE dbo.mandelbrot_set
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 dbo.mandelbrot_set
SET
z_re=znew_re,
z_im=znew_im,
active= CASE
WHEN POWER(znew_re,2)+POWER(znew_im,2)>4 THEN 0
ELSE 1
END
WHERE active=1;
 
SET @iter = @iter - 1;
END
 
-- Generating PPM File
-- Save the below query results to a file with extension .ppm
-- NOTE : All the unwanted info like 'rows affected', 'completed time' etc. needs to be
-- removed from the file. Most of the image editing softwares and online viewers can display the .ppm file
SELECT 'P3' UNION ALL
SELECT CAST(@width AS VARCHAR(5)) + ' ' + CAST(@height AS VARCHAR(5)) UNION ALL
SELECT '255' UNION ALL
SELECT
STRING_AGG(CAST(CASE WHEN active = 1 THEN 0 ELSE 55 + steps % 200 END AS VARCHAR(10)) + ' ' -- R
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+POWER(steps,3) % 200 END AS VARCHAR(10)) + ' ' -- G
+ CAST(CASE WHEN active = 1 THEN 0 ELSE 55+ POWER(steps,2) % 200 END AS VARCHAR(10)) -- B
, ' ') WITHIN GROUP (ORDER BY c_re, c_im)
FROM dbo.mandelbrot_set
GROUP BY c_re, c_im;
</syntaxhighlight>
 
'''OUTPUT'''
[[File:Mandelbrot set transact-sql.png|thumb]]
 
=={{header|TXR}}==
Line 13,149 ⟶ 13,567:
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell|4}}
<syntaxhighlight lang="bash">function mandelbrot((xmin=-8601)) # int(-2.1*4096){
local -ir maxiter=100
((xmax=2867)) # int( 0.7*4096)
local -i i j {x,y}m{in,ax} d{x,y}
local -ra C=( {0..9} )
((ymin=-4915)) # int(-1.2*4096)
local -i lC=${#C[*]}
((ymax=4915)) # int( 1.2*4096)
local -i columns=${COLUMNS:-72} lines=${LINES:-24}
 
((
((maxiter=30))
xmin=-21*4096/10,
xmax= 7*4096/10,
ymin=-12*4096/10,
ymax= 12*4096/10,
 
(( dx=(xmax-xmin)/72))columns,
(( dy=(ymax-ymin)/24))lines
))
 
for ((cy=ymax, i=0; i<lines; cy-=dy, i++))
C='0123456789'
do for ((cx=xmin, j=0; j<columns; cx+=dx, j++))
((lC=${#C}))
do (( x=0, y=0, x2=0, y2=0 ))
 
for (( iter=0; iter<maxiter && x2+y2<=16384; iter++ ))
for((cy=ymax;cy>=ymin;cy-=dy)) ; do
do
for((cx=xmin;cx<=xmax;cx+=dx)) ; do
((
((x=0,y=0,x2=0,y2=0))
y=((x*y)>>11)+cy,
for((iter=0;iter<maxiter && x2+y2<=16384;iter++)) ; do
x=x2-y2+cx,
((y=((x*y)>>11)+cy,x=x2-y2+cx,x2=(x*x)>>12,y2=(y*y)>>12))
x2=(x*x)>>12,
done
y2=(y*y)>>12
((c=iter%lC))
))
echo -n ${C:$c:1}
done
((c=iter%lC))
echo
echo -n "${C[c]}"
done</syntaxhighlight>
done
echo
done
}</syntaxhighlight>
 
{{out}}
Line 13,607 ⟶ 14,036:
</pre>
</small>
 
=={{header|V (Vlang)}}==
Graphical
<syntaxhighlight lang="Go">
// updates and contributors at: github.com/vlang/v/blob/master/examples/gg/mandelbrot.v
// graphics are moveable by keyboard or mouse and resizable with window
import gg
import gx
import runtime
import time
 
const (
pwidth = 800
pheight = 600
chunk_height = 2 // image recalculated in chunks, each chunk processed in separate thread
zoom_factor = 1.1
max_iterations = 255
)
 
struct ViewRect {
mut:
x_min f64
x_max f64
y_min f64
y_max f64
}
 
fn (v &ViewRect) width() f64 {
return v.x_max - v.x_min
}
 
fn (v &ViewRect) height() f64 {
return v.y_max - v.y_min
}
 
struct AppState {
mut:
gg &gg.Context = unsafe { nil }
iidx int
pixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) }
npixels &u32 = unsafe { vcalloc(pwidth * pheight * sizeof(u32)) } // drawings here, results swapped at the end
view ViewRect = ViewRect{-3.0773593290970673, 1.4952456603855397, -2.019938598189011, 2.3106642054225945}
scale int = 1
ntasks int = runtime.nr_jobs()
}
 
const colors = [gx.black, gx.blue, gx.red, gx.green, gx.yellow, gx.orange, gx.purple, gx.white,
gx.indigo, gx.violet, gx.black, gx.blue, gx.orange, gx.yellow, gx.green].map(u32(it.abgr8()))
 
struct MandelChunk {
cview ViewRect
ymin f64
ymax f64
}
 
fn (mut state AppState) update() {
mut chunk_channel := chan MandelChunk{cap: state.ntasks}
mut chunk_ready_channel := chan bool{cap: 1000}
mut threads := []thread{cap: state.ntasks}
defer {
chunk_channel.close()
threads.wait()
}
for t in 0 .. state.ntasks {
threads << spawn state.worker(t, chunk_channel, chunk_ready_channel)
}
//
mut oview := ViewRect{}
mut sw := time.new_stopwatch()
for {
sw.restart()
cview := state.view
if oview == cview {
time.sleep(5 * time.millisecond)
continue
}
// schedule chunks, describing the work:
mut nchunks := 0
for start := 0; start < pheight; start += chunk_height {
chunk_channel <- MandelChunk{
cview: cview
ymin: start
ymax: start + chunk_height
}
nchunks++
}
// wait for all chunks to be processed:
for _ in 0 .. nchunks {
_ := <-chunk_ready_channel
}
// everything is done, swap the buffer pointers
state.pixels, state.npixels = state.npixels, state.pixels
println('${state.ntasks:2} threads; ${sw.elapsed().milliseconds():3} ms / frame; scale: ${state.scale:4}')
oview = cview
}
}
 
[direct_array_access]
fn (mut state AppState) worker(id int, input chan MandelChunk, ready chan bool) {
for {
chunk := <-input or { break }
yscale := chunk.cview.height() / pheight
xscale := chunk.cview.width() / pwidth
mut x, mut y, mut iter := 0.0, 0.0, 0
mut y0 := chunk.ymin * yscale + chunk.cview.y_min
mut x0 := chunk.cview.x_min
for y_pixel := chunk.ymin; y_pixel < chunk.ymax && y_pixel < pheight; y_pixel++ {
yrow := unsafe { &state.npixels[int(y_pixel * pwidth)] }
y0 += yscale
x0 = chunk.cview.x_min
for x_pixel := 0; x_pixel < pwidth; x_pixel++ {
x0 += xscale
x, y = x0, y0
for iter = 0; iter < max_iterations; iter++ {
x, y = x * x - y * y + x0, 2 * x * y + y0
if x * x + y * y > 4 {
break
}
}
unsafe {
yrow[x_pixel] = colors[iter & 15]
}
}
}
ready <- true
}
}
 
fn (mut state AppState) draw() {
mut istream_image := state.gg.get_cached_image_by_idx(state.iidx)
istream_image.update_pixel_data(unsafe { &u8(state.pixels) })
size := gg.window_size()
state.gg.draw_image(0, 0, size.width, size.height, istream_image)
}
 
fn (mut state AppState) zoom(zoom_factor f64) {
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min
state.view.x_min = c_x - zoom_factor * d_x
state.view.x_max = c_x + zoom_factor * d_x
state.view.y_min = c_y - zoom_factor * d_y
state.view.y_max = c_y + zoom_factor * d_y
state.scale += if zoom_factor < 1 { 1 } else { -1 }
}
 
fn (mut state AppState) center(s_x f64, s_y f64) {
c_x, c_y := (state.view.x_max + state.view.x_min) / 2, (state.view.y_max + state.view.y_min) / 2
d_x, d_y := c_x - state.view.x_min, c_y - state.view.y_min
state.view.x_min = s_x - d_x
state.view.x_max = s_x + d_x
state.view.y_min = s_y - d_y
state.view.y_max = s_y + d_y
}
 
// gg callbacks:
 
fn graphics_init(mut state AppState) {
state.iidx = state.gg.new_streaming_image(pwidth, pheight, 4, pixel_format: .rgba8)
}
 
fn graphics_frame(mut state AppState) {
state.gg.begin()
state.draw()
state.gg.end()
}
 
fn graphics_click(x f32, y f32, btn gg.MouseButton, mut state AppState) {
if btn == .right {
size := gg.window_size()
m_x := (x / size.width) * state.view.width() + state.view.x_min
m_y := (y / size.height) * state.view.height() + state.view.y_min
state.center(m_x, m_y)
}
}
 
fn graphics_move(x f32, y f32, mut state AppState) {
if state.gg.mouse_buttons.has(.left) {
size := gg.window_size()
d_x := (f64(state.gg.mouse_dx) / size.width) * state.view.width()
d_y := (f64(state.gg.mouse_dy) / size.height) * state.view.height()
state.view.x_min -= d_x
state.view.x_max -= d_x
state.view.y_min -= d_y
state.view.y_max -= d_y
}
}
 
fn graphics_scroll(e &gg.Event, mut state AppState) {
state.zoom(if e.scroll_y < 0 { zoom_factor } else { 1 / zoom_factor })
}
 
fn graphics_keydown(code gg.KeyCode, mod gg.Modifier, mut state AppState) {
s_x := state.view.width() / 5
s_y := state.view.height() / 5
// movement
mut d_x, mut d_y := 0.0, 0.0
if code == .enter {
println('> ViewRect{${state.view.x_min}, ${state.view.x_max}, ${state.view.y_min}, ${state.view.y_max}}')
}
if state.gg.pressed_keys[int(gg.KeyCode.left)] {
d_x -= s_x
}
if state.gg.pressed_keys[int(gg.KeyCode.right)] {
d_x += s_x
}
if state.gg.pressed_keys[int(gg.KeyCode.up)] {
d_y -= s_y
}
if state.gg.pressed_keys[int(gg.KeyCode.down)] {
d_y += s_y
}
state.view.x_min += d_x
state.view.x_max += d_x
state.view.y_min += d_y
state.view.y_max += d_y
// zoom in/out
if state.gg.pressed_keys[int(gg.KeyCode.left_bracket)]
|| state.gg.pressed_keys[int(gg.KeyCode.z)] {
state.zoom(1 / zoom_factor)
return
}
if state.gg.pressed_keys[int(gg.KeyCode.right_bracket)]
|| state.gg.pressed_keys[int(gg.KeyCode.x)] {
state.zoom(zoom_factor)
return
}
}
 
fn main() {
mut state := &AppState{}
state.gg = gg.new_context(
width: 800
height: 600
create_window: true
window_title: 'The Mandelbrot Set'
init_fn: graphics_init
frame_fn: graphics_frame
click_fn: graphics_click
move_fn: graphics_move
keydown_fn: graphics_keydown
scroll_fn: graphics_scroll
user_data: state
)
spawn state.update()
state.gg.run()
}
</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="ecmascriptwren">import "graphics" for Canvas, Color
import "dome" for Window
 
Line 13,656 ⟶ 14,332:
 
var Game = MandelbrotSet.new(800, 600)</syntaxhighlight>
 
{{out}}
[[File:Wren-Mandelbrot_set.png|400px]]
 
=={{header|XPL0}}==
29

edits