The Lorenz Attractor

We start with exploring Lorenz differential equations using Python through examples and look at how we create machine learning models.

Every book on chaos or non-linear dynamics contain the Lorenz differential equations, prints the unmistakable image of the attractor, or mentions the "butterfly effect". It has been intensely studied by scientist from many disciplines since its publication by Edward Lorenz in 1963. In it, he described a simplified mathematical model for atmospheric convection [1] . Nowadays, these equations are simply known as Lorenz attractor. However, for many years scientist have argued if Lorenz attractor was truly chaos or an artifact of exponential and explosive amplifications of numerical truncation errors. The existence of Lorenz attractor was finally settled by Tucker in 2002 [2]

Lorenz was a meteorologist and a mathematician in search of a model that was capable of generating long stretches of data statistically similar to atmospheric conditions. He set out to build a nonlinear model with an aperiodic solution that was simple enough for the computing power available at the time. After a long search, Lorenz came up with the now-famous set of equations [3] :

$$ \begin{aligned} \dot{x} & = \sigma(y-x) \\ \dot{y} & = \rho x - y - xz \\ \dot{z} & = -\beta z + xy \end{aligned} $$

where $\sigma$, $\beta$, $\rho$ are real numbers.

Like many nonlinear equations, there isn't an analytical solution for Lorenz attractor. So, with practicality in mind, I will use numerical methods (more specifically discrete numerical methods with finite time-steps) to solve these equations and share some of the surprising features using the generated time-series. Besides, time-series are often the only observable data available to quantify the complicated dynamics in real life situations or experiments. So, let's jump right into it!

In [1]:
%matplotlib inline

import utils
from IPython.core.pylabtools import figsize

t, x_t = utils.solve_lorenz(10.0, 8./3, 28.0)

I will not get into what variables ($x$, $y$, $z$) and parameters ($sigma$, $rho$, $beta$) represent. However, for wide range of values of parameters numerical solutions of the equations above generate extremely complicated trajectories. The figure above, plotted in 3 dimensions, shows 30 random trajectories computed for $sigma = 10$, $rho = 2.\overline{6}$, and $beta = 28$. Notice that each trajectory exhibits aperiodic behavior, not cross itself. This is more apparent if we plot each variable separately.

In [2]:
import matplotlib.pyplot as plt

plt.style.use('bmh')
plt.figure(figsize=(12, 18))

x, y, z = x_t[20,:,:].T

ax1 = plt.subplot(311)
ax1.plot(z)
ax1.set_ylabel('$z$')

ax2 = plt.subplot(312, sharex=ax1)
ax2.plot(y)
ax2.set_ylabel('$y$')

ax3 = plt.subplot(313, sharex=ax1)
ax3.plot(x)
ax3.set_ylabel('$x$')
ax3.set_xlabel('$n$')

plt.show()

Creating histograms of the average positions (across different trajectories) show that, on average, the trajectories swirl about the attractors.

In [3]:
xyz_avg = x_t.mean(axis=1)
# xyz_avg.shape

plt.hist(xyz_avg[:,0], 20)
plt.title('Average $x(t)$');
In [4]:
plt.hist(xyz_avg[:,1], 20)
plt.title('Average $y(t)$');

Many physical, chemical, and biological processes in nature are described by a set of coupled first-order autonomous differential equations, or autonomous flows. A widely used technique in the study of these systems is the Poincaré surface-of-section technique. On a Poincaré surface of section, the dynamics can be described by a discrete map whose phase-space dimension is one less than that of the original continuous flow. This sectioning technique thus provides a natural link between continuous flows and discrete maps. With a tremendous facilitation in analysis, numerical computation, and visualization, maps also capture many fundamental dynamical proper- ties of flows. These advantages have made the Pioncaré surface-of-section technique one of the most popular analysis tools in nonlinear dynamics and chaos.

A remarkable tool that extracts the essence by throwing away information is a technique called the surface of section or Poincaré section. A surface of section is generated by looking at successive intersections of a trajectory or a set of trajectories with a plane in the phase space. Typically, the plane is spanned by a coordinate axis and the canonically conjugate momentum axis. We will see that surfaces of section made in this way have nice properties.

In [5]:
utils.plot_poincare_surface()