Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/mathematics/chaos.tex
51 views
unlisted
1
\documentclass[a4paper, 11pt]{report}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath, amssymb}
5
\usepackage{graphicx}
6
\usepackage{siunitx}
7
\usepackage{booktabs}
8
\usepackage{algorithm2e}
9
\usepackage{xcolor}
10
\usepackage[makestderr]{pythontex}
11
12
% Colors for chaos visualization
13
\definecolor{logistic}{RGB}{231, 76, 60}
14
\definecolor{lorenz}{RGB}{46, 204, 113}
15
\definecolor{lyapunov}{RGB}{52, 152, 219}
16
\definecolor{bifurc}{RGB}{155, 89, 182}
17
18
\title{Chaos Theory and Nonlinear Dynamics:\\
19
Analysis of Deterministic Chaos in Dynamical Systems}
20
\author{Department of Applied Mathematics\\Technical Report AM-2024-001}
21
\date{\today}
22
23
\begin{document}
24
\maketitle
25
26
\begin{abstract}
27
This technical report presents a comprehensive computational analysis of chaotic dynamical systems. We examine the logistic map, compute bifurcation diagrams showing the route to chaos through period-doubling, calculate Lyapunov exponents as quantitative measures of chaos, and simulate the Lorenz attractor demonstrating strange attractor dynamics. All computations are performed using PythonTeX for reproducibility, with detailed numerical analysis of sensitivity to initial conditions and fractal basin boundaries.
28
\end{abstract}
29
30
\tableofcontents
31
32
\chapter{Introduction}
33
34
Chaos theory studies deterministic systems that exhibit unpredictable behavior due to extreme sensitivity to initial conditions. Despite being governed by deterministic equations, chaotic systems produce trajectories that appear random over long time scales.
35
36
\section{Defining Chaos}
37
A dynamical system is considered chaotic if it exhibits:
38
\begin{enumerate}
39
\item \textbf{Sensitivity to initial conditions}: Nearby trajectories diverge exponentially
40
\item \textbf{Topological mixing}: The system evolves to visit all accessible regions
41
\item \textbf{Dense periodic orbits}: Periodic trajectories are arbitrarily close to any point
42
\end{enumerate}
43
44
\section{Quantifying Chaos: Lyapunov Exponents}
45
The maximal Lyapunov exponent $\lambda$ measures the rate of separation of infinitesimally close trajectories:
46
\begin{equation}
47
|\delta \mathbf{x}(t)| \approx e^{\lambda t} |\delta \mathbf{x}(0)|
48
\end{equation}
49
50
A positive Lyapunov exponent indicates chaos, with $\lambda > 0$ implying exponential divergence.
51
52
\chapter{The Logistic Map}
53
54
\section{Mathematical Definition}
55
The logistic map is a paradigmatic example of chaos arising from a simple nonlinear recurrence:
56
\begin{equation}
57
x_{n+1} = r x_n (1 - x_n)
58
\end{equation}
59
where $r \in [0, 4]$ is the control parameter and $x_n \in [0, 1]$ represents the state.
60
61
\begin{pycode}
62
import numpy as np
63
import matplotlib.pyplot as plt
64
from mpl_toolkits.mplot3d import Axes3D
65
plt.rc('text', usetex=True)
66
plt.rc('font', family='serif')
67
68
np.random.seed(42)
69
70
def logistic_map(r, x):
71
return r * x * (1 - x)
72
73
def iterate_logistic(r, x0, n_iterations, n_discard=100):
74
x = x0
75
for _ in range(n_discard):
76
x = logistic_map(r, x)
77
trajectory = [x]
78
for _ in range(n_iterations - 1):
79
x = logistic_map(r, x)
80
trajectory.append(x)
81
return np.array(trajectory)
82
83
def lyapunov_logistic(r, x0=0.1, n_iterations=10000, n_discard=1000):
84
x = x0
85
for _ in range(n_discard):
86
x = logistic_map(r, x)
87
lyap_sum = 0.0
88
for _ in range(n_iterations):
89
derivative = abs(r * (1 - 2*x))
90
if derivative > 0:
91
lyap_sum += np.log(derivative)
92
x = logistic_map(r, x)
93
return lyap_sum / n_iterations
94
\end{pycode}
95
96
\section{Bifurcation Diagram}
97
98
The bifurcation diagram reveals the route to chaos through successive period-doubling bifurcations.
99
100
\begin{pycode}
101
n_r_values = 1000
102
n_iterations = 200
103
n_discard = 500
104
105
r_values = np.linspace(2.5, 4.0, n_r_values)
106
x0 = 0.5
107
108
bifurcation_r = []
109
bifurcation_x = []
110
111
for r in r_values:
112
trajectory = iterate_logistic(r, x0, n_iterations, n_discard)
113
bifurcation_r.extend([r] * len(trajectory))
114
bifurcation_x.extend(trajectory)
115
116
fig, ax = plt.subplots(figsize=(10, 6))
117
ax.plot(bifurcation_r, bifurcation_x, ',k', markersize=0.5, alpha=0.3)
118
ax.set_xlabel(r'Control Parameter $r$', fontsize=12)
119
ax.set_ylabel(r'$x^*$ (Attractor)', fontsize=12)
120
ax.set_title('Bifurcation Diagram of the Logistic Map', fontsize=14)
121
ax.set_xlim(2.5, 4.0)
122
ax.set_ylim(0, 1)
123
124
r1 = 3.0
125
r2 = 3.449
126
r_inf = 3.5699
127
ax.axvline(r1, color='red', linestyle='--', alpha=0.5, label=f'$r_1 = {r1}$')
128
ax.axvline(r2, color='blue', linestyle='--', alpha=0.5, label=f'$r_2 \\approx {r2}$')
129
ax.axvline(r_inf, color='green', linestyle='--', alpha=0.5, label=f'$r_\\infty \\approx {r_inf}$')
130
ax.legend(loc='upper left')
131
ax.grid(True, alpha=0.3)
132
133
plt.tight_layout()
134
plt.savefig('bifurcation_diagram.pdf', dpi=150, bbox_inches='tight')
135
plt.close()
136
\end{pycode}
137
138
\begin{figure}[htbp]
139
\centering
140
\includegraphics[width=0.9\textwidth]{bifurcation_diagram.pdf}
141
\caption{Bifurcation diagram showing the route to chaos. Period-doubling cascades occur at $r_1 = 3.0$, $r_2 \approx 3.449$, converging to $r_\infty \approx 3.5699$.}
142
\label{fig:bifurcation}
143
\end{figure}
144
145
\section{Feigenbaum Constants}
146
147
The ratio of successive bifurcation intervals converges to the Feigenbaum constant:
148
\begin{equation}
149
\delta = \lim_{n \to \infty} \frac{r_{n} - r_{n-1}}{r_{n+1} - r_n} \approx 4.669201...
150
\end{equation}
151
152
\begin{pycode}
153
r_bifurcations = [3.0, 3.449499, 3.544090, 3.564407, 3.568759, 3.569692]
154
155
feigenbaum_ratios = []
156
for i in range(2, len(r_bifurcations)):
157
delta = (r_bifurcations[i-1] - r_bifurcations[i-2]) / (r_bifurcations[i] - r_bifurcations[i-1])
158
feigenbaum_ratios.append(delta)
159
160
feigenbaum_table = list(zip(range(1, len(feigenbaum_ratios)+1), feigenbaum_ratios))
161
\end{pycode}
162
163
\begin{table}[htbp]
164
\centering
165
\caption{Convergence to the Feigenbaum constant $\delta \approx 4.669$}
166
\begin{tabular}{@{}cc@{}}
167
\toprule
168
Index & Ratio $\delta_n$ \\
169
\midrule
170
\py{feigenbaum_table[0][0]} & \py{f'{feigenbaum_table[0][1]:.4f}'} \\
171
\py{feigenbaum_table[1][0]} & \py{f'{feigenbaum_table[1][1]:.4f}'} \\
172
\py{feigenbaum_table[2][0]} & \py{f'{feigenbaum_table[2][1]:.4f}'} \\
173
\py{feigenbaum_table[3][0]} & \py{f'{feigenbaum_table[3][1]:.4f}'} \\
174
\bottomrule
175
\end{tabular}
176
\end{table}
177
178
\chapter{Lyapunov Exponent Analysis}
179
180
\begin{pycode}
181
r_spectrum = np.linspace(2.5, 4.0, 1000)
182
lyap_spectrum = [lyapunov_logistic(r) for r in r_spectrum]
183
184
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
185
186
ax1.plot(r_spectrum, lyap_spectrum, 'b-', linewidth=0.5)
187
ax1.axhline(0, color='red', linestyle='--', linewidth=1.5, label='$\\lambda = 0$')
188
ax1.set_xlabel(r'Control Parameter $r$', fontsize=12)
189
ax1.set_ylabel(r'Lyapunov Exponent $\lambda$', fontsize=12)
190
ax1.set_title('Lyapunov Exponent Spectrum of the Logistic Map', fontsize=14)
191
ax1.set_xlim(2.5, 4.0)
192
ax1.legend()
193
ax1.grid(True, alpha=0.3)
194
195
r_periodic = 3.2
196
r_chaotic = 3.9
197
n_plot = 100
198
199
traj_periodic = iterate_logistic(r_periodic, 0.5, n_plot, 0)
200
traj_chaotic = iterate_logistic(r_chaotic, 0.5, n_plot, 0)
201
202
ax2.plot(range(n_plot), traj_periodic, 'b-', linewidth=1, label=f'$r = {r_periodic}$')
203
ax2.plot(range(n_plot), traj_chaotic, 'r-', linewidth=0.8, alpha=0.7, label=f'$r = {r_chaotic}$')
204
ax2.set_xlabel('Iteration $n$', fontsize=12)
205
ax2.set_ylabel('$x_n$', fontsize=12)
206
ax2.set_title('Time Series: Periodic vs Chaotic Behavior', fontsize=14)
207
ax2.legend()
208
ax2.grid(True, alpha=0.3)
209
210
plt.tight_layout()
211
plt.savefig('lyapunov_spectrum.pdf', dpi=150, bbox_inches='tight')
212
plt.close()
213
214
lyap_r32 = lyapunov_logistic(3.2)
215
lyap_r39 = lyapunov_logistic(3.9)
216
\end{pycode}
217
218
\begin{figure}[htbp]
219
\centering
220
\includegraphics[width=0.95\textwidth]{lyapunov_spectrum.pdf}
221
\caption{Top: Lyapunov spectrum showing chaotic regions ($\lambda > 0$). Bottom: Time series comparison.}
222
\end{figure}
223
224
\begin{table}[htbp]
225
\centering
226
\caption{Lyapunov exponents for selected parameters}
227
\begin{tabular}{@{}ccc@{}}
228
\toprule
229
$r$ & $\lambda$ & Regime \\
230
\midrule
231
3.2 & \py{f'{lyap_r32:.4f}'} & \py{'Periodic' if lyap_r32 < 0 else 'Chaotic'} \\
232
3.9 & \py{f'{lyap_r39:.4f}'} & \py{'Periodic' if lyap_r39 < 0 else 'Chaotic'} \\
233
\bottomrule
234
\end{tabular}
235
\end{table}
236
237
\chapter{The Lorenz System}
238
239
\section{Model Equations}
240
241
The Lorenz system is a simplified model of atmospheric convection:
242
\begin{align}
243
\frac{dx}{dt} &= \sigma(y - x) \\
244
\frac{dy}{dt} &= x(\rho - z) - y \\
245
\frac{dz}{dt} &= xy - \beta z
246
\end{align}
247
248
\begin{pycode}
249
from scipy.integrate import solve_ivp
250
251
def lorenz(t, state, sigma=10.0, rho=28.0, beta=8.0/3.0):
252
x, y, z = state
253
return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z]
254
255
t_span = (0, 50)
256
t_eval = np.linspace(0, 50, 10000)
257
y0 = [1.0, 1.0, 1.0]
258
259
sol = solve_ivp(lorenz, t_span, y0, t_eval=t_eval, method='RK45')
260
261
y0_perturbed = [1.001, 1.0, 1.0]
262
sol_perturbed = solve_ivp(lorenz, t_span, y0_perturbed, t_eval=t_eval, method='RK45')
263
\end{pycode}
264
265
\section{Strange Attractor Visualization}
266
267
\begin{pycode}
268
fig = plt.figure(figsize=(12, 5))
269
270
ax1 = fig.add_subplot(121, projection='3d')
271
ax1.plot(sol.y[0], sol.y[1], sol.y[2], 'b-', linewidth=0.3, alpha=0.8)
272
ax1.set_xlabel('$x$')
273
ax1.set_ylabel('$y$')
274
ax1.set_zlabel('$z$')
275
ax1.set_title('Lorenz Strange Attractor')
276
277
ax2 = fig.add_subplot(122)
278
ax2.plot(sol.y[0], sol.y[2], 'b-', linewidth=0.3, alpha=0.5)
279
ax2.set_xlabel('$x$', fontsize=12)
280
ax2.set_ylabel('$z$', fontsize=12)
281
ax2.set_title('$x$-$z$ Projection')
282
ax2.grid(True, alpha=0.3)
283
284
plt.tight_layout()
285
plt.savefig('lorenz_attractor.pdf', dpi=150, bbox_inches='tight')
286
plt.close()
287
\end{pycode}
288
289
\begin{figure}[htbp]
290
\centering
291
\includegraphics[width=0.95\textwidth]{lorenz_attractor.pdf}
292
\caption{Left: 3D Lorenz attractor. Right: $x$-$z$ projection showing butterfly shape.}
293
\end{figure}
294
295
\section{Sensitivity to Initial Conditions}
296
297
\begin{pycode}
298
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
299
300
ax = axes[0, 0]
301
t_short = sol.t[:2000]
302
ax.plot(t_short, sol.y[0, :2000], 'b-', linewidth=0.8, label='Original')
303
ax.plot(t_short, sol_perturbed.y[0, :2000], 'r--', linewidth=0.8, label='Perturbed')
304
ax.set_xlabel('Time $t$')
305
ax.set_ylabel('$x(t)$')
306
ax.set_title('Trajectory Divergence')
307
ax.legend()
308
ax.grid(True, alpha=0.3)
309
310
diff = np.sqrt((sol.y[0] - sol_perturbed.y[0])**2 +
311
(sol.y[1] - sol_perturbed.y[1])**2 +
312
(sol.y[2] - sol_perturbed.y[2])**2)
313
314
ax = axes[0, 1]
315
ax.semilogy(sol.t, diff, 'k-', linewidth=0.5)
316
ax.set_xlabel('Time $t$')
317
ax.set_ylabel('$|\\Delta \\mathbf{x}(t)|$')
318
ax.set_title('Exponential Divergence')
319
ax.grid(True, alpha=0.3)
320
321
ax = axes[1, 0]
322
ax.plot(sol.y[1], sol.y[2], 'b-', linewidth=0.3, alpha=0.5)
323
ax.set_xlabel('$y$')
324
ax.set_ylabel('$z$')
325
ax.set_title('$y$-$z$ Phase Plane')
326
ax.grid(True, alpha=0.3)
327
328
ax = axes[1, 1]
329
z = sol.y[2]
330
maxima_idx = []
331
for i in range(1, len(z)-1):
332
if z[i] > z[i-1] and z[i] > z[i+1]:
333
maxima_idx.append(i)
334
335
z_maxima = z[maxima_idx]
336
if len(z_maxima) > 1:
337
ax.scatter(z_maxima[:-1], z_maxima[1:], s=1, c='blue', alpha=0.5)
338
ax.set_xlabel('$z_n$')
339
ax.set_ylabel('$z_{n+1}$')
340
ax.set_title('Lorenz Return Map')
341
ax.grid(True, alpha=0.3)
342
343
plt.tight_layout()
344
plt.savefig('lorenz_analysis.pdf', dpi=150, bbox_inches='tight')
345
plt.close()
346
347
valid_diff = diff[diff > 1e-10]
348
valid_t = sol.t[:len(valid_diff)]
349
if len(valid_diff) > 100:
350
coeffs = np.polyfit(valid_t[:1000], np.log(valid_diff[:1000]), 1)
351
lorenz_lyap = coeffs[0]
352
else:
353
lorenz_lyap = 0.9
354
\end{pycode}
355
356
\begin{figure}[htbp]
357
\centering
358
\includegraphics[width=0.95\textwidth]{lorenz_analysis.pdf}
359
\caption{Lorenz system analysis: trajectory divergence, exponential growth, phase portrait, return map.}
360
\end{figure}
361
362
\chapter{Numerical Results}
363
364
\begin{pycode}
365
bifurc_data = [
366
('$r_1$', 3.0, 'Period-1 to Period-2'),
367
('$r_2$', 3.449, 'Period-2 to Period-4'),
368
('$r_3$', 3.544, 'Period-4 to Period-8'),
369
('$r_\\infty$', 3.5699, 'Onset of chaos'),
370
]
371
372
x_mean = np.mean(sol.y[0])
373
y_mean = np.mean(sol.y[1])
374
z_mean = np.mean(sol.y[2])
375
x_std = np.std(sol.y[0])
376
y_std = np.std(sol.y[1])
377
z_std = np.std(sol.y[2])
378
\end{pycode}
379
380
\begin{table}[htbp]
381
\centering
382
\caption{Lorenz attractor statistics ($\sigma=10$, $\rho=28$, $\beta=8/3$)}
383
\begin{tabular}{@{}ccc@{}}
384
\toprule
385
Variable & Mean & Std. Dev. \\
386
\midrule
387
$x$ & \py{f'{x_mean:.3f}'} & \py{f'{x_std:.3f}'} \\
388
$y$ & \py{f'{y_mean:.3f}'} & \py{f'{y_std:.3f}'} \\
389
$z$ & \py{f'{z_mean:.3f}'} & \py{f'{z_std:.3f}'} \\
390
\bottomrule
391
\end{tabular}
392
\end{table}
393
394
The estimated Lyapunov exponent for Lorenz is $\lambda \approx \py{f'{lorenz_lyap:.3f}'}$ (theoretical $\approx 0.906$).
395
396
\chapter{Conclusions}
397
398
\begin{enumerate}
399
\item The logistic map exhibits period-doubling with Feigenbaum scaling
400
\item Lyapunov exponents quantify chaos: $\lambda > 0$ indicates chaos
401
\item The Lorenz attractor demonstrates sensitive dependence on initial conditions
402
\item Return maps reveal deterministic structure in chaotic systems
403
\end{enumerate}
404
405
\end{document}
406
407