Mandelbrot set: Difference between revisions

Content added Content deleted
(→‎Normalized Counting, Distance Estimation, Mercator Maps and Perturbation Theory: Finally, the rebasing can be calculated faster (about 7 times faster).)
Line 6,692: Line 6,692:
setrounding(BigFloat, RoundNearest) # set rounding mode (default)
setrounding(BigFloat, RoundNearest) # set rounding mode (default)


d, h = 20, 400 # pixel density (= image width) and image height
d, h = 60, 1200 # pixel density (= image width) and image height
n, r = 60000, 100000 # number of iterations and escape radius (r > 2)
n, r = 60000, 100000 # number of iterations and escape radius (r > 2)


Line 6,717: Line 6,717:
C = (.- 4.0) .* exp.((A' .+ B .* im) .* im)
C = (.- 4.0) .* exp.((A' .+ B .* im) .* im)


Z, dZ = zero(C), zero(C)
Z, dZ, E = zero(C), zero(C), zero(C)
D = zeros(size(C))
D, I, J = zeros(Float64, size(C)), ones(Int64, size(C)), ones(Int64, size(C))


iteration(s, epsilon, delta) = (2 * s + epsilon) * epsilon + delta
iteration(S, E, C) = (2 .* S .+ E) .* E .+ C
for i in 1:h+1, j in 1:d+1
for k in 1:n
M = abs2.(Z) .< abs2(r)
z, dz, delta = Z[i, j], dZ[i, j], C[i, j]
E[M] = iteration(S[I[M]], E[M], C[M])
epsilon, index = z, 1
for k in 1:n
I[M] = I[M] .+ 1
Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1
if abs2(z) < abs2(r)
if abs2(z) < abs2(epsilon) # rebase if z is closer to zero
R = abs2.(Z) .< abs2.(E) # rebase if z is closer to zero
epsilon, index = z, 1
E[R], I[R] = Z[R], J[R]
end
epsilon = iteration(S[index], epsilon, delta)
z, dz = S[index + 1] + epsilon, 2 * z * dz + 1
index = index + 1
else
break
end
end
Z[i, j], dZ[i, j] = z, dz
end
end


Line 6,745: Line 6,736:
savefig("Mercator_Mandelbrot_rebase_map.png")</lang>
savefig("Mercator_Mandelbrot_rebase_map.png")</lang>


The condition abs(z) < abs(epsilon) does not define a circular area but a half-plane. If you insert a factor, the condition abs(z) < gamma * abs(epsilon) for 0 < gamma < 1 defines a circular area containing the origin. For gamma = 1/2 and below, the circle lies entirely within a bailout circle around the origin with escape radius r > 2. For example, if the reference point is at S(6, 0), the equation abs(z) = abs(epsilon) defines the set of all points that are equidistant from O(0, 0) and S(6, 0). This is exactly the perpendicular bisector x = 3. Considering instead the equation abs(z) = 1/2 * abs(epsilon), one finds all points half as far from O(0, 0) as from S(6, 0). All these points lie on a circle, which has center M(-2, 0) and radius R = 4. This circle lies completely in a bailout circle around the origin O(0, 0) with escape radius r = 6. If you choose a factor gamma > 1, you get corresponding circles containing the reference point S. However, the condition abs(z) < abs(epsilon) is optimal because it keeps the differences epsilon to the reference sequence as small as possible. Rebasing occurs if and only if the distance abs(epsilon) to the reference sequence becomes smaller as a result. You can only rebase to the beginning of the reference sequence. If you want to rebase to the reference point S[m], the distance epsilon = z - S[m] must be calculated. With this subtraction, however, the entire precision is lost due to cancellation. Only at the first reference point there is no cancellation due to S[1] = 0, because epsilon = z - S[1] = z - 0 = z. The images can be verified by a (slow) calculation with BigFloats.
The rebasing condition abs(z) < abs(epsilon) does not define a circular area but a half-plane. If you insert a factor, the condition abs(z) < gamma * abs(epsilon) for 0 < gamma < 1 defines a circular area containing the origin. For gamma = 1/2 and below, the circle lies entirely within a bailout circle around the origin with escape radius r > 2. For example, if the reference point is at S(6, 0), the equation abs(z) = abs(epsilon) defines the set of all points that are equidistant from O(0, 0) and S(6, 0). This is exactly the perpendicular bisector x = 3. Considering instead the equation abs(z) = 1/2 * abs(epsilon), one finds all points half as far from O(0, 0) as from S(6, 0). All these points lie on a circle, which has center M(-2, 0) and radius R = 4. This circle lies completely in a bailout circle around the origin O(0, 0) with escape radius r = 6. If you choose a factor gamma > 1, you get corresponding circles containing the reference point S. However, the condition abs(z) < abs(epsilon) is optimal because it keeps the differences epsilon to the reference sequence as small as possible. Rebasing occurs if and only if the distance abs(epsilon) to the reference sequence becomes smaller as a result. You can only rebase to the beginning of the reference sequence. If you want to rebase to the reference point S[m], the difference epsilon = z - S[m] must be calculated. With this subtraction, however, the entire precision is lost due to cancellation. Only at the first reference point there is no cancellation due to S[1] = 0, because epsilon = z - S[1] = z - 0 = z. The images can be verified by a (slow) calculation with BigFloats.
<lang julia>using Plots
<lang julia>using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)