#!/usr/bin/env python
# coding: utf-8
# # Lorenz Attractor
# by [Paulo Marques](http://pmarques.eu), 2013/09/21
#
# ---
#
# This notebook implements the beautiful Lorenz Attractor in Python. The Lorenz Attractor is probably the
# most ilustrative example of a system that exibits cahotic behaviour. Slightly changing the initial conditions
# of the system leads to completely different solutions. The system itself corresponds to the movement of a point
# particle in a 3D space over time.
#
#
# ![Lorenz Attractor](http://upload.wikimedia.org/wikipedia/commons/e/e0/Lorenz.png)
#
#
# The system is formally described by three different differential equations. These equations represent the movement
# of a point $(x, y, z)$ in space over time. In the following equations, $t$ represents time, $\sigma$, $\rho$, $\beta$ are constants.
#
# $$ \frac{dx}{dt} = \sigma (y - x) $$
#
# $$ \frac{dy}{dt} = x (\rho - z) - y $$
#
# $$ \frac{dz}{dt} = x y - \beta z $$
#
# Let's implement it in python.
#
# ---
# Let's start by importing some basic libraries.
# In[1]:
get_ipython().run_line_magic('matplotlib', 'inline')
from scipy.integrate import odeint
from mpl_toolkits.mplot3d.axes3d import Axes3D
from pylab import *
# We need to define the system of differential equations as an equation of the form: ${\bf r}' = {\bf f}({\bf r},t)$ where ${\bf r} = (x, y, z)$ and ${\bf f}({\bf r},t)$ is the mapping function.
# In[2]:
def f(r, t):
(x, y, z) = r
# The Lorenz equations
dx_dt = sigma*(y - x)
dy_dt = x*(rho - z) - y
dz_dt = x*y - beta*z
return [dx_dt, dy_dt, dz_dt]
# Let's define the initial conditions of the system ${\bf r}_0 = (x_0, y_0, z_0)$, the constants $\sigma$, $\rho$ and $\beta$ and a time grid.
# In[3]:
# Initial position in space
r0 = [0.1, 0.0, 0.0]
# Constants sigma, rho and beta
sigma = 10.0
rho = 28.0
beta = 8.0/3.0
# Time grid
tf = 100.0
t = linspace(0, tf, int(tf*100))
# Now let's solve the differencial equations numericaly and extract the corresponding $(x, y, z)$:
# In[4]:
pos = odeint(f, r0, t)
x = pos[:, 0]
y = pos[:, 1]
z = pos[:, 2]
# Let's see how it looks in 3D.
# In[5]:
fig = figure(figsize=(16,10))
ax = fig.gca(projection='3d')
ax.plot(x, y, z)
# Let's see different cuts around the axes:
# In[6]:
fig, ax = subplots(1, 3, sharex=True, sharey=True, figsize=(16,8))
ax[0].plot(x, y)
ax[0].set_title('X-Y cut')
ax[1].plot(x, z)
ax[1].set_title('X-Z cut')
ax[2].plot(y, z)
ax[2].set_title('Y-Z cut')
# ---
#
# # MIT LICENSE
#
# > Copyright (C) 2013 Paulo Marques (pjp.marques@gmail.com)
# >
# > Permission is hereby granted, free of charge, to any person obtaining a copy of
# > this software and associated documentation files (the "Software"), to deal in
# > the Software without restriction, including without limitation the rights to
# > use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# > the Software, and to permit persons to whom the Software is furnished to do so,
# > subject to the following conditions:
# >
# > The above copyright notice and this permission notice shall be included in all
# > copies or substantial portions of the Software.
# >
# > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# > FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# > COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# > IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# > CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.