MATH40006: An Introduction to Mathematical Computing
¶
Final Assessment: Specimen
¶
The complex recurrence relation $$z_{n+1} = {z_{n}}^2+c,$$ where $z_0=0$ and $c$ is a complex constant, exhibits different behaviours depending on the value of $c$. It can be shown that once $|z_n|>2$, the iteration must then diverge to infinity; but for some values of $c$ this never happens.
The values of $c$ for which the iterates remain bounded for all time is called the Mandelbrot set. Your task is to write a function for creating an image of the Mandelbrot set, showing also the behaviour of the iteration in the neighbourhood of the set.
Recommended strategy:
I. First, write and test a function called escape_time which takes as its arguments a complex number c, and a maximum number of iterations max_iterations, and returns: either
(a) the number of iterations of $z_{n+1} = {z_n}^2 + c$, starting with $z_0 = 0$, until $|z_n| > 2$ or
(b) if this does not happen, the value of max_iterations.
II. Then, find the value of escape_time for various values of $x + i\, y$, for $-2.0 \le x \le 2.0$, $-2.0 \le y \le 2.0$, using quite a large step size in the first instance. Choose a value of max_iterations that seems sensible to you.
Once you have this working, try reducing the step size, if necessary adjusting the value of max_iterations.
III. Finally, write a function called mandelbrot_plot. Your function should take as its arguments:
• xmin,xmax and xstep; consider giving these default values;
• ymin,ymax and ystep; consider giving these default values;
• a maximum number of iterations max_iterations.
It should return no output, but should instead create an image showing the interior of the Mandelbrot set in one colour, and points near its boundary in other colours that depend on how long it takes the iteration, for that value of $c$, to attain an absolute value greater than 2.
If you have time, consider strategies for vectorizing your code.
Phil’s answer follows¶
I wrote a function called mandelbrot_array which my mandelbrot_plot function calls; you don’t have to do it like that. I’ve sort of vectorized it, using vectorized; there are probably smarter ways to do that.
In [33]:
def escape_time(c, max_iterations):
“””
Number of iterations for z -> z^2 + c to attain
absolute value greater than 2
“””
# initialize
z = 0
# iterate
for n in range(max_iterations):
if abs(z) > 2:
# return iteration count if sequence is diverging
return n
# iterate
z = z**2 + c
# return final iteration count if sequence does not diverge
return max_iterations
In [74]:
import numpy as np
escape_time_vec = np.vectorize(escape_time)
In [84]:
def mandelbrot_array(xmin, xmax, xstep, ymin, ymax, ystep, max_iterations):
“””
Array of logs of escape times
“””
import numpy as np
# calculate x and y values
xvalues = np.arange(xmin, xmax+xstep, xstep)
yvalues = np.arange(ymin, ymax+ystep, ystep)
# meshgrid
x, y = np.meshgrid(xvalues, yvalues)
# values of c
c = x + 1j*y
# calculate escape times
# note flipping along y-axis
et_array = np.flip(escape_time_vec(c, max_iterations),0)
# return logarithm for best results
return np.log(et_array)
In [85]:
def mandelbrot_plot(xmin, xmax, xstep, ymin, ymax, ystep, max_iterations):
“””
Plot of mandelbrot set
“””
import matplotlib.pyplot as plt
# array of logs of escape times
et_array = mandelbrot_array(xmin, xmax, xstep, ymin, ymax, ystep, max_iterations)
# plot
plt.figure(figsize=(10,10))
plt.imshow(et_array, extent = [xmin, xmax, ymin, ymax])
In [86]:
%matplotlib inline
mandelbrot_plot(-2.0, 2.0, 0.1, -2.0, 2.0, 0.1, 100)

In [87]:
%matplotlib inline
mandelbrot_plot(-2.0, 2.0, 0.01, -2.0, 2.0, 0.01, 100)

In [90]:
mandelbrot_plot(-0.4, 0.0, 0.001, 0.5, 0.9, 0.001, 100)

In [ ]: