---
# System prepended metadata

title: Vanilla function

---

import numpy as np

center_grid = np.arange(100)
iteration = lambda z, c: z**2 + c
vfunc = np.vectorize(do_iteration)
vfunc(center_grid, CENTER)

def do_iteration(c, max_iter=MAX_ITER):
    z = 0
    # Per complex number, validate it for a finite number of iterations
    for k in range(max_iter):
        z = z**2 + c

        # if the modulus (or absolute value) of the complex number is greater than 2,
        # it will diverge, thus not within Mandelbrot set
        if np.absolute(z) > 2.0: 
            break
    return k
    


import dask.array as da
def compute_complex_number_array_dask(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT):
    scale = max(extent.real / width, extent.imag / height)

    # Loop through all selected complex number within the extent
    heights, widths = da.meshgrid(da.arange(height), da.arange(width))
    
    complex_numbers = center + (widths - width//2 + (heights - height//2)*1j) * scale
    
    return complex_numbers.compute()
    
    
    
import dask.array as da
def compute_complex_number_array_numpy(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT):
    scale = max(extent.real / width, extent.imag / height)

    # Loop through all selected complex number within the extent
    heights, widths = np.meshgrid(np.arange(height), np.arange(width))
    
    complex_numbers = center + (widths - width//2 + (heights - height//2)*1j) * scale
    
    return complex_numbers
    
#TEST 2
import numpy as np
import numba

def compute_complex_number_array_numpy(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT):
    scale = max(extent.real / width, extent.imag / height)

    # Loop through all selected complex number within the extent
    heights, widths = np.meshgrid(np.arange(height), np.arange(width))
    complex_numbers = center + (widths - width//2 + (heights - height//2)*1j) * scale
    
    return complex_numbers

@numba.vectorize
def do_iteration(c, max_iter=MAX_ITER):
    z = 0
    # Per complex number, validate it for a finite number of iterations
    for k in range(max_iter):
        z = z**2 + c

        # if the modulus (or absolute value) of the complex number is greater than 2,
        # it will diverge, thus not within Mandelbrot set
        if np.absolute(z) > 2.0: 
            break
    return k
            
def compute_mandelbrot(width=WIDTH, height=HEIGHT, max_iter=MAX_ITER, center=CENTER, extent=EXTENT):
    niters = np.zeros((width, height), int)
    scale = max(extent.real/width, extent.imag/height)

    # # Loop through all selected complex number within the extent
    # for h in range(height):
    #     for w in range(width):
    #         # calculate the complex value c corresponding to the pixel position given by (w, h)
    #         # // is floor division: the result is an integer if the inputs are integer
    #         c = center + (w - width // 2 + (h - height // 2) * 1j) * scale
    
    c = compute_complex_number_array_numpy(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT)
    # k = do_iteration(c, max_iter=MAX_ITER)
    k = do_iteration(c, MAX_ITER)
    #niters[h, w] = k
    return k
    
-------------------------------------------------

import numpy as np
import numba
import matplotlib.pyplot 

def compute_complex_number_array_numpy(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT):
    scale = max(extent.real / width, extent.imag / height)

    # Loop through all selected complex number within the extent
    heights, widths = np.meshgrid(np.arange(height), np.arange(width))
    
    complex_numbers = center + (widths - width//2 + (heights - height//2)*1j) * scale
    
    return complex_numbers

@numba.vectorize
def do_iteration(c, max_iter=MAX_ITER):
    z = 0
    # Per complex number, validate it for a finite number of iterations
    for k in range(max_iter):
        z = z**2 + c

        # if the modulus (or absolute value) of the complex number is greater than 2,
        # it will diverge, thus not within Mandelbrot set
        if np.absolute(z) > 2.0: 
            break
    return k

c = compute_complex_number_array_numpy(width=WIDTH, height=HEIGHT, center=CENTER, extent=EXTENT)
k = do_iteration(c, MAX_ITER)

plt.imshow(k)

---------------------------------------------------
# Vanilla function
def compute_mandelbrot_vanilla(width=WIDTH, height=HEIGHT, max_iter=MAX_ITER, center=CENTER, extent=EXTENT):
    niters = np.zeros((width, height), int)
    scale = max(extent.real/width, extent.imag/height)

    # Loop through all selected complex number within the extent
    for h in range(height):
        for w in range(width):
            # calculate the complex value c corresponding to the pixel position given by (w, h)
            # // is floor division: the result is an integer if the inputs are integer
            c = center + (w - width // 2 + (h - height // 2) * 1j) * scale
            z = 0

            # Per complex number, validate it for a finite number of iterations
            for k in range(max_iter):
                z = z**2 + c

                # if the modulus (or absolute value) of the complex number is greater than 2,
                # it will diverge, thus not within Mandelbrot set
                if np.absolute(z) > 2.0: 
                    break

            niters[h, w] = k
    return niters
    
    --------------------------------------
    