Wrapping the core calculation into a function#

Now its about time to start speeding up things.

The first idea here might be to just prepare that by cleaning up the code a bit and bring more structure to it.

We have the outer two loops to iterate the complex grid and the innermost for loop to execute the actual algorithm.

So let’s start off with wrapping the core algorithm in its own function.

Hide code cell content
%matplotlib widget
import time
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 300

x_min, x_max = -2.5, 1.0
y_min, y_max = -1.25, 1.25
max_iterations = 100
resolution = 1000
def mandel(x, y, max_iterations):
    c = complex(x, y)
    c0 = c
    
    for iteration in range(max_iterations):
        c = c**2 + c0
        if abs(c) > 2.0:
            break
    
    return iteration
tic = time.perf_counter()

x = [x_min + (x_max - x_min) / (resolution - 1) * index for index in range(resolution)]
y = [y_min + (y_max - y_min) / (resolution - 1) * index for index in range(resolution)]

iterations = []
for _y in y:
    row = []
    for _x in x:
        row.append(mandel(_x, _y, max_iterations))
        
    iterations.append(row)
    
toc = time.perf_counter()
print(f"Calculating the mandelbrot set took {toc-tic:.1f} seconds.")
Calculating the mandelbrot set took 3.6 seconds.
Hide code cell content
fig, axes = plt.subplots()
axes.imshow(iterations[::-1], extent=(x_min, x_max, y_min, y_max), cmap="RdGy")
plt.tight_layout()

This already gave a permance win.

But why?