Path: blob/main/latex-templates/templates/mathematics/chaos.tex
51 views
unlisted
\documentclass[a4paper, 11pt]{report}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath, amssymb}4\usepackage{graphicx}5\usepackage{siunitx}6\usepackage{booktabs}7\usepackage{algorithm2e}8\usepackage{xcolor}9\usepackage[makestderr]{pythontex}1011% Colors for chaos visualization12\definecolor{logistic}{RGB}{231, 76, 60}13\definecolor{lorenz}{RGB}{46, 204, 113}14\definecolor{lyapunov}{RGB}{52, 152, 219}15\definecolor{bifurc}{RGB}{155, 89, 182}1617\title{Chaos Theory and Nonlinear Dynamics:\\18Analysis of Deterministic Chaos in Dynamical Systems}19\author{Department of Applied Mathematics\\Technical Report AM-2024-001}20\date{\today}2122\begin{document}23\maketitle2425\begin{abstract}26This 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.27\end{abstract}2829\tableofcontents3031\chapter{Introduction}3233Chaos 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.3435\section{Defining Chaos}36A dynamical system is considered chaotic if it exhibits:37\begin{enumerate}38\item \textbf{Sensitivity to initial conditions}: Nearby trajectories diverge exponentially39\item \textbf{Topological mixing}: The system evolves to visit all accessible regions40\item \textbf{Dense periodic orbits}: Periodic trajectories are arbitrarily close to any point41\end{enumerate}4243\section{Quantifying Chaos: Lyapunov Exponents}44The maximal Lyapunov exponent $\lambda$ measures the rate of separation of infinitesimally close trajectories:45\begin{equation}46|\delta \mathbf{x}(t)| \approx e^{\lambda t} |\delta \mathbf{x}(0)|47\end{equation}4849A positive Lyapunov exponent indicates chaos, with $\lambda > 0$ implying exponential divergence.5051\chapter{The Logistic Map}5253\section{Mathematical Definition}54The logistic map is a paradigmatic example of chaos arising from a simple nonlinear recurrence:55\begin{equation}56x_{n+1} = r x_n (1 - x_n)57\end{equation}58where $r \in [0, 4]$ is the control parameter and $x_n \in [0, 1]$ represents the state.5960\begin{pycode}61import numpy as np62import matplotlib.pyplot as plt63from mpl_toolkits.mplot3d import Axes3D64plt.rc('text', usetex=True)65plt.rc('font', family='serif')6667np.random.seed(42)6869def logistic_map(r, x):70return r * x * (1 - x)7172def iterate_logistic(r, x0, n_iterations, n_discard=100):73x = x074for _ in range(n_discard):75x = logistic_map(r, x)76trajectory = [x]77for _ in range(n_iterations - 1):78x = logistic_map(r, x)79trajectory.append(x)80return np.array(trajectory)8182def lyapunov_logistic(r, x0=0.1, n_iterations=10000, n_discard=1000):83x = x084for _ in range(n_discard):85x = logistic_map(r, x)86lyap_sum = 0.087for _ in range(n_iterations):88derivative = abs(r * (1 - 2*x))89if derivative > 0:90lyap_sum += np.log(derivative)91x = logistic_map(r, x)92return lyap_sum / n_iterations93\end{pycode}9495\section{Bifurcation Diagram}9697The bifurcation diagram reveals the route to chaos through successive period-doubling bifurcations.9899\begin{pycode}100n_r_values = 1000101n_iterations = 200102n_discard = 500103104r_values = np.linspace(2.5, 4.0, n_r_values)105x0 = 0.5106107bifurcation_r = []108bifurcation_x = []109110for r in r_values:111trajectory = iterate_logistic(r, x0, n_iterations, n_discard)112bifurcation_r.extend([r] * len(trajectory))113bifurcation_x.extend(trajectory)114115fig, ax = plt.subplots(figsize=(10, 6))116ax.plot(bifurcation_r, bifurcation_x, ',k', markersize=0.5, alpha=0.3)117ax.set_xlabel(r'Control Parameter $r$', fontsize=12)118ax.set_ylabel(r'$x^*$ (Attractor)', fontsize=12)119ax.set_title('Bifurcation Diagram of the Logistic Map', fontsize=14)120ax.set_xlim(2.5, 4.0)121ax.set_ylim(0, 1)122123r1 = 3.0124r2 = 3.449125r_inf = 3.5699126ax.axvline(r1, color='red', linestyle='--', alpha=0.5, label=f'$r_1 = {r1}$')127ax.axvline(r2, color='blue', linestyle='--', alpha=0.5, label=f'$r_2 \\approx {r2}$')128ax.axvline(r_inf, color='green', linestyle='--', alpha=0.5, label=f'$r_\\infty \\approx {r_inf}$')129ax.legend(loc='upper left')130ax.grid(True, alpha=0.3)131132plt.tight_layout()133plt.savefig('bifurcation_diagram.pdf', dpi=150, bbox_inches='tight')134plt.close()135\end{pycode}136137\begin{figure}[htbp]138\centering139\includegraphics[width=0.9\textwidth]{bifurcation_diagram.pdf}140\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$.}141\label{fig:bifurcation}142\end{figure}143144\section{Feigenbaum Constants}145146The ratio of successive bifurcation intervals converges to the Feigenbaum constant:147\begin{equation}148\delta = \lim_{n \to \infty} \frac{r_{n} - r_{n-1}}{r_{n+1} - r_n} \approx 4.669201...149\end{equation}150151\begin{pycode}152r_bifurcations = [3.0, 3.449499, 3.544090, 3.564407, 3.568759, 3.569692]153154feigenbaum_ratios = []155for i in range(2, len(r_bifurcations)):156delta = (r_bifurcations[i-1] - r_bifurcations[i-2]) / (r_bifurcations[i] - r_bifurcations[i-1])157feigenbaum_ratios.append(delta)158159feigenbaum_table = list(zip(range(1, len(feigenbaum_ratios)+1), feigenbaum_ratios))160\end{pycode}161162\begin{table}[htbp]163\centering164\caption{Convergence to the Feigenbaum constant $\delta \approx 4.669$}165\begin{tabular}{@{}cc@{}}166\toprule167Index & Ratio $\delta_n$ \\168\midrule169\py{feigenbaum_table[0][0]} & \py{f'{feigenbaum_table[0][1]:.4f}'} \\170\py{feigenbaum_table[1][0]} & \py{f'{feigenbaum_table[1][1]:.4f}'} \\171\py{feigenbaum_table[2][0]} & \py{f'{feigenbaum_table[2][1]:.4f}'} \\172\py{feigenbaum_table[3][0]} & \py{f'{feigenbaum_table[3][1]:.4f}'} \\173\bottomrule174\end{tabular}175\end{table}176177\chapter{Lyapunov Exponent Analysis}178179\begin{pycode}180r_spectrum = np.linspace(2.5, 4.0, 1000)181lyap_spectrum = [lyapunov_logistic(r) for r in r_spectrum]182183fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))184185ax1.plot(r_spectrum, lyap_spectrum, 'b-', linewidth=0.5)186ax1.axhline(0, color='red', linestyle='--', linewidth=1.5, label='$\\lambda = 0$')187ax1.set_xlabel(r'Control Parameter $r$', fontsize=12)188ax1.set_ylabel(r'Lyapunov Exponent $\lambda$', fontsize=12)189ax1.set_title('Lyapunov Exponent Spectrum of the Logistic Map', fontsize=14)190ax1.set_xlim(2.5, 4.0)191ax1.legend()192ax1.grid(True, alpha=0.3)193194r_periodic = 3.2195r_chaotic = 3.9196n_plot = 100197198traj_periodic = iterate_logistic(r_periodic, 0.5, n_plot, 0)199traj_chaotic = iterate_logistic(r_chaotic, 0.5, n_plot, 0)200201ax2.plot(range(n_plot), traj_periodic, 'b-', linewidth=1, label=f'$r = {r_periodic}$')202ax2.plot(range(n_plot), traj_chaotic, 'r-', linewidth=0.8, alpha=0.7, label=f'$r = {r_chaotic}$')203ax2.set_xlabel('Iteration $n$', fontsize=12)204ax2.set_ylabel('$x_n$', fontsize=12)205ax2.set_title('Time Series: Periodic vs Chaotic Behavior', fontsize=14)206ax2.legend()207ax2.grid(True, alpha=0.3)208209plt.tight_layout()210plt.savefig('lyapunov_spectrum.pdf', dpi=150, bbox_inches='tight')211plt.close()212213lyap_r32 = lyapunov_logistic(3.2)214lyap_r39 = lyapunov_logistic(3.9)215\end{pycode}216217\begin{figure}[htbp]218\centering219\includegraphics[width=0.95\textwidth]{lyapunov_spectrum.pdf}220\caption{Top: Lyapunov spectrum showing chaotic regions ($\lambda > 0$). Bottom: Time series comparison.}221\end{figure}222223\begin{table}[htbp]224\centering225\caption{Lyapunov exponents for selected parameters}226\begin{tabular}{@{}ccc@{}}227\toprule228$r$ & $\lambda$ & Regime \\229\midrule2303.2 & \py{f'{lyap_r32:.4f}'} & \py{'Periodic' if lyap_r32 < 0 else 'Chaotic'} \\2313.9 & \py{f'{lyap_r39:.4f}'} & \py{'Periodic' if lyap_r39 < 0 else 'Chaotic'} \\232\bottomrule233\end{tabular}234\end{table}235236\chapter{The Lorenz System}237238\section{Model Equations}239240The Lorenz system is a simplified model of atmospheric convection:241\begin{align}242\frac{dx}{dt} &= \sigma(y - x) \\243\frac{dy}{dt} &= x(\rho - z) - y \\244\frac{dz}{dt} &= xy - \beta z245\end{align}246247\begin{pycode}248from scipy.integrate import solve_ivp249250def lorenz(t, state, sigma=10.0, rho=28.0, beta=8.0/3.0):251x, y, z = state252return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z]253254t_span = (0, 50)255t_eval = np.linspace(0, 50, 10000)256y0 = [1.0, 1.0, 1.0]257258sol = solve_ivp(lorenz, t_span, y0, t_eval=t_eval, method='RK45')259260y0_perturbed = [1.001, 1.0, 1.0]261sol_perturbed = solve_ivp(lorenz, t_span, y0_perturbed, t_eval=t_eval, method='RK45')262\end{pycode}263264\section{Strange Attractor Visualization}265266\begin{pycode}267fig = plt.figure(figsize=(12, 5))268269ax1 = fig.add_subplot(121, projection='3d')270ax1.plot(sol.y[0], sol.y[1], sol.y[2], 'b-', linewidth=0.3, alpha=0.8)271ax1.set_xlabel('$x$')272ax1.set_ylabel('$y$')273ax1.set_zlabel('$z$')274ax1.set_title('Lorenz Strange Attractor')275276ax2 = fig.add_subplot(122)277ax2.plot(sol.y[0], sol.y[2], 'b-', linewidth=0.3, alpha=0.5)278ax2.set_xlabel('$x$', fontsize=12)279ax2.set_ylabel('$z$', fontsize=12)280ax2.set_title('$x$-$z$ Projection')281ax2.grid(True, alpha=0.3)282283plt.tight_layout()284plt.savefig('lorenz_attractor.pdf', dpi=150, bbox_inches='tight')285plt.close()286\end{pycode}287288\begin{figure}[htbp]289\centering290\includegraphics[width=0.95\textwidth]{lorenz_attractor.pdf}291\caption{Left: 3D Lorenz attractor. Right: $x$-$z$ projection showing butterfly shape.}292\end{figure}293294\section{Sensitivity to Initial Conditions}295296\begin{pycode}297fig, axes = plt.subplots(2, 2, figsize=(12, 8))298299ax = axes[0, 0]300t_short = sol.t[:2000]301ax.plot(t_short, sol.y[0, :2000], 'b-', linewidth=0.8, label='Original')302ax.plot(t_short, sol_perturbed.y[0, :2000], 'r--', linewidth=0.8, label='Perturbed')303ax.set_xlabel('Time $t$')304ax.set_ylabel('$x(t)$')305ax.set_title('Trajectory Divergence')306ax.legend()307ax.grid(True, alpha=0.3)308309diff = np.sqrt((sol.y[0] - sol_perturbed.y[0])**2 +310(sol.y[1] - sol_perturbed.y[1])**2 +311(sol.y[2] - sol_perturbed.y[2])**2)312313ax = axes[0, 1]314ax.semilogy(sol.t, diff, 'k-', linewidth=0.5)315ax.set_xlabel('Time $t$')316ax.set_ylabel('$|\\Delta \\mathbf{x}(t)|$')317ax.set_title('Exponential Divergence')318ax.grid(True, alpha=0.3)319320ax = axes[1, 0]321ax.plot(sol.y[1], sol.y[2], 'b-', linewidth=0.3, alpha=0.5)322ax.set_xlabel('$y$')323ax.set_ylabel('$z$')324ax.set_title('$y$-$z$ Phase Plane')325ax.grid(True, alpha=0.3)326327ax = axes[1, 1]328z = sol.y[2]329maxima_idx = []330for i in range(1, len(z)-1):331if z[i] > z[i-1] and z[i] > z[i+1]:332maxima_idx.append(i)333334z_maxima = z[maxima_idx]335if len(z_maxima) > 1:336ax.scatter(z_maxima[:-1], z_maxima[1:], s=1, c='blue', alpha=0.5)337ax.set_xlabel('$z_n$')338ax.set_ylabel('$z_{n+1}$')339ax.set_title('Lorenz Return Map')340ax.grid(True, alpha=0.3)341342plt.tight_layout()343plt.savefig('lorenz_analysis.pdf', dpi=150, bbox_inches='tight')344plt.close()345346valid_diff = diff[diff > 1e-10]347valid_t = sol.t[:len(valid_diff)]348if len(valid_diff) > 100:349coeffs = np.polyfit(valid_t[:1000], np.log(valid_diff[:1000]), 1)350lorenz_lyap = coeffs[0]351else:352lorenz_lyap = 0.9353\end{pycode}354355\begin{figure}[htbp]356\centering357\includegraphics[width=0.95\textwidth]{lorenz_analysis.pdf}358\caption{Lorenz system analysis: trajectory divergence, exponential growth, phase portrait, return map.}359\end{figure}360361\chapter{Numerical Results}362363\begin{pycode}364bifurc_data = [365('$r_1$', 3.0, 'Period-1 to Period-2'),366('$r_2$', 3.449, 'Period-2 to Period-4'),367('$r_3$', 3.544, 'Period-4 to Period-8'),368('$r_\\infty$', 3.5699, 'Onset of chaos'),369]370371x_mean = np.mean(sol.y[0])372y_mean = np.mean(sol.y[1])373z_mean = np.mean(sol.y[2])374x_std = np.std(sol.y[0])375y_std = np.std(sol.y[1])376z_std = np.std(sol.y[2])377\end{pycode}378379\begin{table}[htbp]380\centering381\caption{Lorenz attractor statistics ($\sigma=10$, $\rho=28$, $\beta=8/3$)}382\begin{tabular}{@{}ccc@{}}383\toprule384Variable & Mean & Std. Dev. \\385\midrule386$x$ & \py{f'{x_mean:.3f}'} & \py{f'{x_std:.3f}'} \\387$y$ & \py{f'{y_mean:.3f}'} & \py{f'{y_std:.3f}'} \\388$z$ & \py{f'{z_mean:.3f}'} & \py{f'{z_std:.3f}'} \\389\bottomrule390\end{tabular}391\end{table}392393The estimated Lyapunov exponent for Lorenz is $\lambda \approx \py{f'{lorenz_lyap:.3f}'}$ (theoretical $\approx 0.906$).394395\chapter{Conclusions}396397\begin{enumerate}398\item The logistic map exhibits period-doubling with Feigenbaum scaling399\item Lyapunov exponents quantify chaos: $\lambda > 0$ indicates chaos400\item The Lorenz attractor demonstrates sensitive dependence on initial conditions401\item Return maps reveal deterministic structure in chaotic systems402\end{enumerate}403404\end{document}405406407