Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Image: ubuntu2204
Double click here and enter the student numbers for all group members. Don't enter any names.
Before you start work on the project, click on this link to read the MATH0011 project instructions.
23009447
Bifurcation Diagrams
This project explores the behaviour of iterative sequences, such as the one defined by and
for . You will see that as increases the behaviour of the sequence changes in an interesting way. For less than about 5, the sequence converges: e.g. if then
When the sequence doesn't converge to a limit, but instead tends to cycle between two values. For example, if then
As increases the limiting behaviour becomes a cycle of 4 values, then of 8, then 16, and so on. For gamma around 9.4 stops tending to a cycle at all and becomes completely non-periodic, but there are larger values of at which the sequence again tends to a cycle.
A bifurcation diagram is a diagram which summarises this behaviour. The horizontal axis shows values of , and the vertical axis shows values taken by the sequence after some large number of terms.
You will generate iterative sequences, plot bifurcation diagrams, and try to estimate the Feigenbaum constant, defined as the limiting ratio of differences between parameter values at which the length of the cycle changes. You will get experience in using matplotlib to produce beautiful plots and in writing code that is as efficient as possible. Approximating the Feigenbaum constant is a bit awkward, and you'll need to think carefully about the best way to do it in Python.
Use the next cell for any import
s you need.
Exercise 1 - defining and iterating some functions
Write a Python function h(x, g)
whose output is .
If is a function, we define to be the function obtained by composing with itself times. Thus and so on.
Write a function iterate(f, x0, n)
which takes a function , a number , and a positive whole number and returns ,
Exercise 2 - finding the period of an iteration
The number is said to be -periodic for the function if is the smallest positive whole number such that . We'd like to check whether is -periodic for some , but because of rounding errors we can't expect to be exactly equal to . For this reason we'll relax our definition a bit by allowing to be within of , where is some small number.
Write a function periodicity(y0, f, epsilon=0.0001, max_iter=1000)
which takes as input a number , a function , a number , and a positive whole number max_iter
, and returns the smallest such that
if there is such an which is less than max_iter
. If there is no such less than max_iter
it should return .
I've written the first line of the function definition for you, specifying default values for epsilon
and max_iter
. If you can't remember how these work, review the weekly notebooks or read this link or ask a chatbot.
Here's one test case for your function. Your function h
above takes two inputs, but sometimes we want to fix the value of the second input g
and use the one-input function that sends a number x
to h(x, g)
. You can create that function with def
as usual, or you can write lambda x: h(x, g)
which is sometimes simpler. Read more about Python lambda
s at this link. If your periodicity function works correctly, then periodicity(0.3507810470182891, lambda x: h(x, 8.5))
should be 4.
Exercise 3 - plotting a bifurcation diagram
In this exercise you are going to write a function to produce bifurcation diagrams for the function . The function will take the following inputs:
g_min
andg_max
, the maximum and minimum values of on the x-axis of your plot.n_values
, the number of equally spaced values of to use.preiterations
, the number referred to in the description below.n_points
, the number referred to in the description below.
I've written the first line of the function for you and suggested some default values for these quantities.
Inside the function, generate n_values
equally spaced values of between g_min
and g_max
. To make the finished diagram look good you probably need n_values
to be a few thousand, but you might want to make n_values
smaller to begin with to make the code run quickly.
For each of these values of , compute where and is the input preiterations
of your function (experiment to see which values make the plot look best - roughly 500 seems to work well). This allows the iterations to settle down to a cycle, if they're going to. If is -periodic - which you can check using your periodicity
function with epsilon = 0.0001
say - plot all the points with coordinates
If isn't -periodic for any , plot all points with coordinates
where is the input n_points
to your function. I suggest a value of of about 500 in your final diagram.
Here are some suggestions to help you create the diagram.
np.linspace
generates equally spaced points between given limits.You can plot points using plt.scatter. Given lists
xs = [a0, a1, a2,...]
of x-coordinates andys = [b0, b1, b2, ...]
of y-coordinates,plt.scatter(xs, ys)
plots the points with coordinates(a0, b0), (a1, b1), ...
. You may need to useplt.scatter(xs, ys, s = e, marker='.')
wheree
is some small number to get the plot looking good.Experiment with parameter values to get a balance between making the plot look good and making the code run quickly. Start with smaller values of
n_value, preiterations, n_points
so that the code runs quickly, and increase them when you're confident everything works correctly.Only call
plt.scatter
once - you should generate all of the points in your plot, then useplt.scatter
to plot them. If you callplt.scatter
lots of times, your code will take a long time to run.
Now call your generate_bifurcation_diagram
function to make a plot.
Make a new version of generate_bifurcation_diagram
that works for the sequence defined by and use it to generate another bifurcation diagram. Good values for the maximum and minimum values of are 2.5 and 4.
Exercise 4 - the Feigenbaum constant
In this final part you are going to try and estimate the Feigenbaum constant . This is difficult to do well, and you will only get a very rough approximation by this method.
What you should see in your bifurcation diagram for is that for values of up to about 5, the iterations converge to a single value. For between approximately 5 and 8, the iterations eventually have period 2. For between roughly 8 and 9, they have period 4. This pattern continues with the periods doubling and the intervals of values getting geometrically smaller.
Let be the value of at which period 1 changes to period 2, be the value at which period 2 changes to period 4, be the value at which period 4 changes to period 8, and so on, so that . The Feigenbaum constant is defined to be
Try to calculate as many of the as you can, and use them to approximate . You can probably only get reliable values for the up to or 6 because of issues with the precision of Python floats. The simplest way to find the is
produce a list of equally spaced values between 5 and 9.5
for each value of , work out the eventual periodicity of the sequence by iterating 1000 times starting at with your
iterate
function and then using yourperiodicity
function. Store the period for the th value of in position of another list.use a loop to find the values where the periodicity changes from 1 to 2, 2 to 4, 4 to 8, 8 to 16, and so on - these are your .
Now calculate as many of the values as you can for the iteration . You should get different to the ones above, but the limiting value of the ratio of the differences of the is known to be the same!
Submitting your project
Check you have done the following.
Included all group members' student numbers at the top of this notebook.
Read through every exercise to check you have answered every part.
Carefully read and followed all of the MATH0011 project instructions.
Checked that all of the code in this notebook works correctly.
One group member should download the completed notebook (in CoCalc, click the File menu next to the green Save button, then click Download) and submit it on the MATH0011 Moodle page in the projects section. Please submit only one file per group.