Simple chaotic behavior in non-linear systems#
In the last lecture, we discussed how floating point arithmetic can be subtle: its finite precision leads to the fact that even simple properties of elementary arithmetic, like the associativity of addition, don’t hold:
a, b, c = 1.0, 1e-16, 1.2222e-16
print(f"(a + b) + c = {(a + b) + c}")
print(f"a + (b + c) = {a + (b + c)}")
(a + b) + c = 1.0000000000000002
a + (b + c) = 1.0000000000000002
This behavior can have serious implications in a variety of numerical work scenarios.
Consider the seemingly trivial problem of evaluating with a computer the expression
where \(r\) and \(x\) are real numbers with \(r \in [0,4]\) and \(x \in (0,1)\). This expression can also be written in an algebraically equivalent form:
We will see, however, that when using a computer these two forms don’t necessarily produce the same answer. Computers can not represent the real numbers (a mathematical abstraction with infinite precision) but instead must use finite-precision numbers that can fit in finite memory. The two expressions above can, therefore, lead to slightly different answers as the various (algebraically equivalent) operations are carried by the computer.
First a look at a few simple tests:
def f1(x): return r*x*(1-x)
def f2(x): return r*x - r*x**2
r = 0.5
x = 0.8
print('f1:', f1(x))
print('f2:', f2(x))
f1: 0.07999999999999999
f2: 0.07999999999999996
r = 3.9
x = 0.8
print('f1:', f1(x))
print('f2:', f2(x))
f1: 0.6239999999999999
f2: 0.6239999999999997
The difference is small but not zero:
print('difference:', (f1(x)-f2(x)))
difference: 2.220446049250313e-16
More importantly, this difference begins to accumulate as we perform the same operations over and over. Let’s illustrate this behavior by using the formulas above iteratively, that is, by feeding the result of the evaluation back into the same formula:
We can experiment with different values of \(r\) and different starting points \(x_0\) to observe the different results. We will simply build a python list that contains the results of three different (algebraically equivalent) forms of evaluating the above expression.
Exercise
Build a little script that computes the iteration of $f(x)$ using three different ways of writing the expression. Store your results and plot them using the `plt.plot()` function (the solution follows).