Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
139 views
ubuntu2404
1
\documentclass[11pt,a4paper]{article}
2
3
% Mathematical Modeling and Simulation Template
4
% SEO Keywords: mathematical modeling latex template, simulation methods latex, dynamical systems latex
5
6
\usepackage[utf8]{inputenc}
7
\usepackage[T1]{fontenc}
8
\usepackage{amsmath,amsfonts,amssymb}
9
\usepackage{mathtools}
10
\usepackage{siunitx}
11
\usepackage{graphicx}
12
\usepackage{float}
13
\usepackage{hyperref}
14
\usepackage{cleveref}
15
\usepackage{booktabs}
16
\usepackage{pythontex}
17
18
\usepackage[style=numeric,backend=biber]{biblatex}
19
\addbibresource{references.bib}
20
21
\title{Mathematical Modeling and Simulation:\\
22
Dynamical Systems and Computational Methods}
23
\author{CoCalc Scientific Templates}
24
\date{\today}
25
26
\begin{document}
27
28
\maketitle
29
30
\begin{abstract}
31
This comprehensive mathematical modeling template demonstrates dynamical systems analysis, population dynamics, epidemiological models, and Monte Carlo simulations. Features include stability analysis, bifurcation theory, stochastic processes, and agent-based modeling with professional visualizations for research in applied mathematics and computational biology.
32
33
\textbf{Keywords:} mathematical modeling, dynamical systems, simulation methods, population dynamics, epidemiology, Monte Carlo methods
34
\end{abstract}
35
36
\tableofcontents
37
\newpage
38
39
\section{Dynamical Systems and Population Models}
40
\label{sec:dynamical-systems}
41
42
This section demonstrates the analysis of nonlinear dynamical systems including the classical Lotka-Volterra predator-prey model:
43
\begin{align}
44
\frac{dx}{dt} &= \alpha x - \beta xy \\
45
\frac{dy}{dt} &= \gamma xy - \delta y
46
\end{align}
47
where $x$ is the prey population, $y$ is the predator population, and $\alpha, \beta, \gamma, \delta > 0$ are parameters.
48
49
We also analyze the SIR epidemic model:
50
\begin{align}
51
\frac{dS}{dt} &= -\beta SI/N \\
52
\frac{dI}{dt} &= \beta SI/N - \gamma I \\
53
\frac{dR}{dt} &= \gamma I
54
\end{align}
55
where $S$, $I$, $R$ represent susceptible, infected, and recovered populations, and $R_0 = \beta/\gamma$ is the basic reproduction number.
56
57
\begin{pycode}
58
import matplotlib
59
matplotlib.use("Agg") # non-GUI backend; set before importing pyplot
60
import numpy as np
61
import matplotlib.pyplot as plt
62
from scipy.integrate import solve_ivp
63
from scipy.signal import find_peaks
64
65
np.random.seed(42)
66
67
def lotka_volterra_system(alpha=1.0, beta=0.5, gamma=0.2, delta=0.8, y0=None, t_end=40, n_t=2000):
68
"""Lotka–Volterra predator–prey model with analysis and plotting helpers."""
69
def f(t, z):
70
x, y = z
71
dxdt = alpha * x - beta * x * y
72
dydt = gamma * x * y - delta * y
73
return [dxdt, dydt]
74
75
# Equilibrium
76
x_eq = delta / gamma
77
y_eq = alpha / beta
78
79
# Pick IC away from equilibrium to show oscillations
80
if y0 is None:
81
y0 = [1.25 * x_eq, 0.75 * y_eq] # off-equilibrium
82
83
# Solve
84
t_span = (0, t_end)
85
t_eval = np.linspace(0, t_end, n_t)
86
sol = solve_ivp(f, t_span, y0, t_eval=t_eval, method='RK45', rtol=1e-8, atol=1e-10)
87
88
# Peak timing (prey leads predator)
89
x_t, y_t = sol.y
90
peaks_x, _ = find_peaks(x_t)
91
peaks_y, _ = find_peaks(y_t)
92
t_x_peak = sol.t[peaks_x[0]] if len(peaks_x) else np.nan
93
t_y_peak = sol.t[peaks_y[0]] if len(peaks_y) else np.nan
94
lead = t_y_peak - t_x_peak # >0 means prey peaks first
95
96
# Period estimate from prey peaks
97
T = sol.t[peaks_x[1]] - sol.t[peaks_x[0]] if len(peaks_x) > 1 else np.nan
98
99
print("Lotka–Volterra Model (predator–prey):")
100
print(f" Parameters: alpha={alpha:.3f}, beta={beta:.3f}, gamma={gamma:.3f}, delta={delta:.3f}")
101
print(f" Equilibrium: $(x^*,y^*)=({x_eq:.3f},{y_eq:.3f})$")
102
print(f" Initial conditions: $x_0={y0[0]:.3f}$, $y_0={y0[1]:.3f}$")
103
if np.isfinite(lead):
104
who_leads = "Prey lead predator" if lead > 0 else "Predator lead prey"
105
print(f" {who_leads} by about {abs(lead):.2f} time units; estimated period $T\\approx{T:.2f}$")
106
107
return sol.t, sol.y, (x_eq, y_eq), (t_x_peak, t_y_peak), T
108
109
def sir_epidemic_model():
110
"""SIR epidemic model (kept for comparison)."""
111
def sir_system(t, y, beta, gamma, N):
112
S, I, R = y
113
dSdt = -beta * S * I / N
114
dIdt = beta * S * I / N - gamma * I
115
dRdt = gamma * I
116
return [dSdt, dIdt, dRdt]
117
118
beta = 0.5
119
gamma = 0.1
120
N = 1000
121
R0 = beta / gamma
122
123
S0, I0, R0_init = 999, 1, 0
124
y0 = [S0, I0, R0_init]
125
126
t_span = (0, 100)
127
t_eval = np.linspace(0, 100, 1000)
128
sol = solve_ivp(lambda t, y: sir_system(t, y, beta, gamma, N),
129
t_span, y0, t_eval=t_eval, method='RK45')
130
131
peak_idx = np.argmax(sol.y[1])
132
peak_time = sol.t[peak_idx]
133
peak_infections = sol.y[1][peak_idx]
134
135
print("\nSIR Epidemic Model:")
136
print(f" beta={beta}, gamma={gamma}, N={N}, $R_0={R0:.2f}$")
137
print(f" Peak infections: {peak_infections:.0f} at $t={peak_time:.1f}$")
138
139
return sol.t, sol.y, R0, peak_time, peak_infections
140
141
# Plot style
142
try:
143
plt.style.use('seaborn-v0_8-colorblind')
144
except Exception:
145
plt.style.use('seaborn-colorblind')
146
plt.rcParams.update({
147
"figure.dpi": 120,
148
"axes.grid": True,
149
"grid.alpha": 0.3,
150
"axes.spines.top": False,
151
"axes.spines.right": False,
152
})
153
154
# Analyze LV and SIR
155
lv_time, lv_solution, (x_eq, y_eq), (t_x_peak, t_y_peak), T = lotka_volterra_system()
156
sir_time, sir_solution, R0, peak_t, peak_I = sir_epidemic_model()
157
158
# Improved LV plots: time series with peak annotations
159
x_lv, y_lv = lv_solution
160
fig1, ax = plt.subplots(1, 1, figsize=(9, 4), constrained_layout=True)
161
ax.plot(lv_time, x_lv, label='Prey $x(t)$', color='#1f77b4', lw=2)
162
ax.plot(lv_time, y_lv, label='Predator $y(t)$', color='#ff7f0e', lw=2)
163
ax.axhline(x_eq, color='gray', ls='--', lw=1, label='$x^*$ nullcline ($y=\\alpha/\\beta$)')
164
ax.axhline(y_eq, color='gray', ls=':', lw=1, label='$y^*$ nullcline ($x=\\delta/\\gamma$)')
165
166
# Mark first peaks and lead–lag
167
from math import isfinite
168
if isfinite(t_x_peak):
169
ax.axvline(t_x_peak, color='#1f77b4', ls='--', lw=1, alpha=0.8)
170
ax.plot([t_x_peak], [np.interp(t_x_peak, lv_time, x_lv)], 'o', color='#1f77b4', ms=4)
171
if isfinite(t_y_peak):
172
ax.axvline(t_y_peak, color='#ff7f0e', ls='--', lw=1, alpha=0.8)
173
ax.plot([t_y_peak], [np.interp(t_y_peak, lv_time, y_lv)], 'o', color='#ff7f0e', ms=4)
174
175
if isfinite(t_x_peak) and isfinite(t_y_peak):
176
lead = t_y_peak - t_x_peak
177
txt = f"Prey peak leads predator by {lead:.2f}"
178
ax.annotate(txt, xy=(0.02, 0.95), xycoords='axes fraction',
179
ha='left', va='top', fontsize=10,
180
bbox=dict(boxstyle='round,pad=0.25', fc='white', ec='0.7', alpha=0.9))
181
182
ax.set_xlabel('$t$')
183
ax.set_ylabel('Population')
184
ax.set_title('Lotka–Volterra predator–prey: oscillations and phase lead')
185
ax.legend(loc='best')
186
187
# LV phase plane with vector field, nullclines, and multiple trajectories
188
fig2, ax2 = plt.subplots(1, 1, figsize=(6.5, 5.5), constrained_layout=True)
189
190
# Vector field (streamplot)
191
x_max = 2.5 * x_eq
192
y_max = 2.5 * y_eq
193
X, Y = np.meshgrid(np.linspace(0, x_max, 32), np.linspace(0, y_max, 32))
194
U = (1.0 * X) - (0.5 * X * Y) # using alpha=1.0, beta=0.5
195
V = (0.2 * X * Y) - (0.8 * Y) # using gamma=0.2, delta=0.8
196
speed = np.hypot(U, V)
197
ax2.streamplot(X, Y, U, V, density=1.2, color='#cccccc', arrowsize=1.2, linewidth=1)
198
199
# Nullclines
200
ax2.axhline(y_eq, color='gray', ls=':', lw=1.5, label='$dx/dt=0: y=\\alpha/\\beta$')
201
ax2.axvline(x_eq, color='gray', ls='--', lw=1.5, label='$dy/dt=0: x=\\delta/\\gamma$')
202
203
# Multiple trajectories around equilibrium
204
ics = [
205
[1.15 * x_eq, 0.85 * y_eq],
206
[0.75 * x_eq, 1.35 * y_eq],
207
[1.60 * x_eq, 0.55 * y_eq],
208
]
209
colors = ['#2ca02c', '#9467bd', '#8c564b']
210
t_eval = np.linspace(0, 60, 4000)
211
def solve_ic(ic):
212
def f(t, z):
213
x, y = z
214
return [1.0 * x - 0.5 * x * y, 0.2 * x * y - 0.8 * y]
215
return solve_ivp(f, (0, t_eval[-1]), ic, t_eval=t_eval, rtol=1e-8, atol=1e-10)
216
217
for (ic, c) in zip(ics, colors):
218
sol_ic = solve_ic(ic)
219
ax2.plot(sol_ic.y[0], sol_ic.y[1], color=c, lw=2, label=f'Traj from $(x_0,y_0)=({ic[0]:.1f},{ic[1]:.1f})$')
220
221
# Highlight equilibrium
222
ax2.plot([x_eq], [y_eq], 'r*', ms=12, label='Equilibrium $(x^*,y^*)$')
223
224
ax2.set_xlim(0, x_max)
225
ax2.set_ylim(0, y_max)
226
ax2.set_xlabel('Prey $x$')
227
ax2.set_ylabel('Predator $y$')
228
ax2.set_title('Lotka–Volterra: phase plane, nullclines, and trajectories')
229
ax2.legend(loc='best', fontsize=9)
230
231
# SIR model plot (unchanged logic, improved styling)
232
S, I, R = sir_solution
233
fig3, ax3 = plt.subplots(figsize=(8, 4), constrained_layout=True)
234
ax3.plot(sir_time, S, label='$S(t)$', color='#1f77b4', lw=2)
235
ax3.plot(sir_time, I, label='$I(t)$', color='#d62728', lw=2)
236
ax3.plot(sir_time, R, label='$R(t)$', color='#2ca02c', lw=2)
237
ax3.axvline(peak_t, color='k', ls='--', lw=1, label=f'Peak $I$ at $t={peak_t:.1f}$')
238
ax3.plot([peak_t], [peak_I], 'ko', ms=4)
239
ax3.set_xlabel('$t$')
240
ax3.set_ylabel('Population')
241
ax3.set_title(f'SIR model ($R_0={R0:.2f}$)')
242
ax3.legend(loc='best')
243
244
# Save figures instead of showing
245
fig1.savefig("lv_timeseries.png", bbox_inches="tight")
246
fig2.savefig("lv_phaseplane.png", bbox_inches="tight")
247
fig3.savefig("sir_model.png", bbox_inches="tight")
248
\end{pycode}
249
250
\section{Monte Carlo Methods and Stochastic Simulation}
251
\label{sec:monte-carlo}
252
253
Monte Carlo methods use random sampling to solve computational problems. For numerical integration, we approximate:
254
\begin{equation}
255
I = \int_a^b f(x) \, dx \approx \frac{b-a}{N} \sum_{i=1}^N f(X_i)
256
\end{equation}
257
where $X_i$ are uniformly distributed random samples on $[a,b]$, and the error typically decreases as $\mathcal{O}(N^{-1/2})$.
258
259
We also simulate 2D random walks where position after $n$ steps satisfies:
260
\begin{equation}
261
\mathbf{X}_n = \sum_{i=1}^n \mathbf{S}_i
262
\end{equation}
263
where $\mathbf{S}_i$ are independent random step vectors, and $\mathbb{E}[|\mathbf{X}_n|] \sim \sqrt{n}$.
264
265
\begin{pycode}
266
def monte_carlo_integration():
267
"""Demonstrate Monte Carlo integration methods"""
268
269
def integrand(x):
270
"""Test function: f(x) = exp(-x^2)*sin(x)"""
271
return np.exp(-x**2) * np.sin(x)
272
273
# Integration domain
274
a, b = 0, 2
275
276
# Analytical approximation for comparison
277
from scipy.integrate import quad
278
analytical_result, _ = quad(integrand, a, b)
279
280
# Monte Carlo integration with different sample sizes
281
sample_sizes = [100, 500, 1000, 5000, 10000, 50000]
282
mc_estimates = []
283
mc_errors = []
284
285
for n in sample_sizes:
286
# Generate random samples
287
x_samples = np.random.uniform(a, b, n)
288
f_samples = integrand(x_samples)
289
290
# Monte Carlo estimate
291
mc_estimate = (b - a) * np.mean(f_samples)
292
mc_estimates.append(mc_estimate)
293
294
# Error estimate
295
error = abs(mc_estimate - analytical_result)
296
mc_errors.append(error)
297
298
print(f"\nMonte Carlo Integration:")
299
print(f" Integrand: exp(-x squared)*sin(x) on [0, 2]")
300
print(f" Analytical result: {analytical_result:.6f}")
301
print(f" Sample sizes: {sample_sizes}")
302
303
return sample_sizes, mc_estimates, mc_errors, analytical_result
304
305
def random_walk_simulation():
306
"""Simulate 2D random walk and analyze properties"""
307
308
n_steps = 10000
309
n_walks = 100
310
311
# Store final positions
312
final_positions = np.zeros((n_walks, 2))
313
314
# Generate random walks
315
for walk in range(n_walks):
316
# Random steps: +1 or -1 in each direction
317
steps_x = np.random.choice([-1, 1], n_steps)
318
steps_y = np.random.choice([-1, 1], n_steps)
319
320
# Cumulative position
321
position_x = np.cumsum(steps_x)
322
position_y = np.cumsum(steps_y)
323
324
final_positions[walk] = [position_x[-1], position_y[-1]]
325
326
# Store one example trajectory
327
if walk == 0:
328
example_trajectory = np.column_stack([position_x, position_y])
329
330
# Analyze displacement statistics
331
displacements = np.linalg.norm(final_positions, axis=1)
332
mean_displacement = np.mean(displacements)
333
std_displacement = np.std(displacements)
334
335
# Theoretical expectation: E[|X_n|] ~ sqrt(n)
336
theoretical_rms = np.sqrt(n_steps)
337
338
print(f"\nRandom Walk Simulation:")
339
print(f" Steps per walk: {n_steps}")
340
print(f" Number of walks: {n_walks}")
341
print(f" Mean displacement: {mean_displacement:.1f}")
342
print(f" Theoretical RMS: {theoretical_rms:.1f}")
343
print(f" Displacement std: {std_displacement:.1f}")
344
345
return example_trajectory, final_positions, displacements
346
347
# Perform Monte Carlo simulations
348
sample_sizes, mc_est, mc_err, analytical = monte_carlo_integration()
349
trajectory, final_pos, displacements = random_walk_simulation()
350
\end{pycode}
351
352
\section{Agent-Based Modeling}
353
\label{sec:agent-based}
354
355
Agent-based models simulate complex systems by modeling individual agents and their interactions. We implement a simplified flocking model based on three behavioral rules:
356
357
\begin{itemize}
358
\item \textbf{Separation}: Agents avoid crowding neighbors
359
\item \textbf{Alignment}: Agents steer towards average heading of neighbors
360
\item \textbf{Cohesion}: Agents steer towards average position of neighbors
361
\end{itemize}
362
363
Each agent's velocity is updated according to:
364
\begin{equation}
365
\mathbf{v}_{i}^{t+1} = \mathbf{v}_{i}^{t} + \mathbf{F}_{\text{sep}} + \mathbf{F}_{\text{align}} + \mathbf{F}_{\text{coh}}
366
\end{equation}
367
where the forces depend on local neighborhood interactions.
368
369
\begin{pycode}
370
def flocking_simulation():
371
"""Implement simplified boids flocking model"""
372
373
class Boid:
374
def __init__(self, x, y, vx, vy):
375
self.x = x
376
self.y = y
377
self.vx = vx
378
self.vy = vy
379
380
def update(self, boids, width, height, dt=0.1):
381
"""Update boid position and velocity based on flocking rules"""
382
383
# Flocking parameters
384
separation_radius = 5.0
385
alignment_radius = 10.0
386
cohesion_radius = 15.0
387
max_speed = 2.0
388
389
separation_force = np.array([0.0, 0.0])
390
alignment_force = np.array([0.0, 0.0])
391
cohesion_force = np.array([0.0, 0.0])
392
393
neighbors = []
394
395
for other in boids:
396
if other is not self:
397
dx = other.x - self.x
398
dy = other.y - self.y
399
distance = np.sqrt(dx**2 + dy**2)
400
401
if distance < cohesion_radius:
402
neighbors.append(other)
403
404
# Separation: steer away from neighbors
405
if distance < separation_radius and distance > 0:
406
separation_force[0] -= dx / distance
407
separation_force[1] -= dy / distance
408
409
# Alignment: match neighbor velocities
410
if distance < alignment_radius:
411
alignment_force[0] += other.vx
412
alignment_force[1] += other.vy
413
414
# Cohesion: steer toward center of neighbors
415
cohesion_force[0] += dx
416
cohesion_force[1] += dy
417
418
if len(neighbors) > 0:
419
# Normalize forces
420
separation_force *= 1.5
421
alignment_force /= len(neighbors)
422
cohesion_force /= len(neighbors)
423
cohesion_force *= 0.01
424
425
# Apply forces
426
self.vx += separation_force[0] * dt + alignment_force[0] * dt + cohesion_force[0] * dt
427
self.vy += separation_force[1] * dt + alignment_force[1] * dt + cohesion_force[1] * dt
428
429
# Limit speed
430
speed = np.sqrt(self.vx**2 + self.vy**2)
431
if speed > max_speed:
432
self.vx = self.vx / speed * max_speed
433
self.vy = self.vy / speed * max_speed
434
435
# Update position
436
self.x += self.vx * dt
437
self.y += self.vy * dt
438
439
# Periodic boundary conditions
440
self.x = self.x % width
441
self.y = self.y % height
442
443
# Initialize simulation
444
n_boids = 50
445
width, height = 100, 100
446
boids = []
447
448
for _ in range(n_boids):
449
x = np.random.uniform(0, width)
450
y = np.random.uniform(0, height)
451
vx = np.random.uniform(-1, 1)
452
vy = np.random.uniform(-1, 1)
453
boids.append(Boid(x, y, vx, vy))
454
455
# Simulate for several time steps
456
n_steps = 200
457
positions_history = []
458
459
for step in range(n_steps):
460
# Update all boids
461
for boid in boids:
462
boid.update(boids, width, height)
463
464
# Record positions every 10 steps
465
if step % 10 == 0:
466
positions = [(boid.x, boid.y) for boid in boids]
467
positions_history.append(positions)
468
469
print(f"\nFlocking Simulation:")
470
print(f" Number of boids: {n_boids}")
471
print(f" Domain size: {width}×{height}")
472
print(f" Simulation steps: {n_steps}")
473
print(f" Recorded snapshots: {len(positions_history)}")
474
475
return positions_history, width, height
476
477
# Run agent-based modeling simulation
478
flock_history, domain_width, domain_height = flocking_simulation()
479
\end{pycode}
480
481
\begin{pycode}
482
# Create comprehensive modeling and simulation visualization
483
import os
484
os.makedirs('assets', exist_ok=True)
485
486
fig, axes = plt.subplots(3, 3, figsize=(18, 15))
487
fig.suptitle('Mathematical Modeling and Simulation', fontsize=16, fontweight='bold')
488
489
# Lotka-Volterra time series
490
ax1 = axes[0, 0]
491
ax1.plot(lv_time, lv_solution[0], 'b-', linewidth=2, label='Prey')
492
ax1.plot(lv_time, lv_solution[1], 'r-', linewidth=2, label='Predator')
493
ax1.plot([0, lv_time[-1]], [x_eq, x_eq], 'b--', alpha=0.7, label='Prey equilibrium')
494
ax1.plot([0, lv_time[-1]], [y_eq, y_eq], 'r--', alpha=0.7, label='Predator equilibrium')
495
ax1.set_xlabel('Time')
496
ax1.set_ylabel('Population')
497
ax1.set_title('Lotka-Volterra System')
498
ax1.legend()
499
ax1.grid(True, alpha=0.3)
500
501
# Lotka-Volterra phase portrait
502
ax2 = axes[0, 1]
503
ax2.plot(lv_solution[0], lv_solution[1], 'g-', linewidth=2)
504
ax2.plot(x_eq, y_eq, 'ko', markersize=8, label='Equilibrium')
505
ax2.plot(lv_solution[0][0], lv_solution[1][0], 'go', markersize=8, label='Initial')
506
ax2.set_xlabel('Prey Population')
507
ax2.set_ylabel('Predator Population')
508
ax2.set_title('Phase Portrait')
509
ax2.legend()
510
ax2.grid(True, alpha=0.3)
511
512
# SIR model
513
ax3 = axes[0, 2]
514
ax3.plot(sir_time, sir_solution[0], 'b-', linewidth=2, label='Susceptible')
515
ax3.plot(sir_time, sir_solution[1], 'r-', linewidth=2, label='Infected')
516
ax3.plot(sir_time, sir_solution[2], 'g-', linewidth=2, label='Recovered')
517
ax3.axvline(peak_t, color='red', linestyle='--', alpha=0.7, label=f'Peak at t={peak_t:.1f}')
518
ax3.set_xlabel('Time (days)')
519
ax3.set_ylabel('Population')
520
ax3.set_title(f'SIR Epidemic Model (R0={R0:.1f})')
521
ax3.legend()
522
ax3.grid(True, alpha=0.3)
523
524
# Monte Carlo convergence
525
ax4 = axes[1, 0]
526
ax4.loglog(sample_sizes, mc_err, 'bo-', linewidth=2, markersize=6)
527
ax4.loglog(sample_sizes, [1/np.sqrt(n) for n in sample_sizes], 'r--', linewidth=2, label='1/√n')
528
ax4.set_xlabel('Sample Size')
529
ax4.set_ylabel('Integration Error')
530
ax4.set_title('Monte Carlo Convergence')
531
ax4.legend()
532
ax4.grid(True, alpha=0.3)
533
534
# Random walk trajectory
535
ax5 = axes[1, 1]
536
ax5.plot(trajectory[:1000, 0], trajectory[:1000, 1], 'b-', linewidth=1, alpha=0.7)
537
ax5.plot(trajectory[0, 0], trajectory[0, 1], 'go', markersize=8, label='Start')
538
ax5.plot(trajectory[-1, 0], trajectory[-1, 1], 'ro', markersize=8, label='End')
539
ax5.set_xlabel('x-position')
540
ax5.set_ylabel('y-position')
541
ax5.set_title('Random Walk Trajectory')
542
ax5.legend()
543
ax5.grid(True, alpha=0.3)
544
545
# Displacement distribution
546
ax6 = axes[1, 2]
547
ax6.hist(displacements, bins=20, alpha=0.7, density=True, color='skyblue')
548
ax6.axvline(np.mean(displacements), color='red', linestyle='--', linewidth=2, label='Mean')
549
ax6.axvline(np.sqrt(len(trajectory)), color='green', linestyle='--', linewidth=2, label='Theoretical')
550
ax6.set_xlabel('Final Displacement')
551
ax6.set_ylabel('Density')
552
ax6.set_title('Displacement Distribution')
553
ax6.legend()
554
ax6.grid(True, alpha=0.3)
555
556
# Flocking simulation snapshots
557
ax7 = axes[2, 0]
558
# Show initial positions
559
if len(flock_history) > 0:
560
initial_pos = np.array(flock_history[0])
561
ax7.scatter(initial_pos[:, 0], initial_pos[:, 1], c='blue', s=20, alpha=0.6)
562
ax7.set_xlim(0, domain_width)
563
ax7.set_ylim(0, domain_height)
564
ax7.set_xlabel('x')
565
ax7.set_ylabel('y')
566
ax7.set_title('Flocking: Initial State')
567
ax7.grid(True, alpha=0.3)
568
569
ax8 = axes[2, 1]
570
# Show final positions
571
if len(flock_history) > 0:
572
final_pos = np.array(flock_history[-1])
573
ax8.scatter(final_pos[:, 0], final_pos[:, 1], c='red', s=20, alpha=0.6)
574
ax8.set_xlim(0, domain_width)
575
ax8.set_ylim(0, domain_height)
576
ax8.set_xlabel('x')
577
ax8.set_ylabel('y')
578
ax8.set_title('Flocking: Final State')
579
ax8.grid(True, alpha=0.3)
580
581
# Model comparison summary
582
ax9 = axes[2, 2]
583
model_types = ['Deterministic\n(ODE)', 'Stochastic\n(Monte Carlo)', 'Agent-Based\n(Flocking)']
584
y_pos = np.arange(len(model_types))
585
586
# Dummy data for illustration
587
complexity = [2, 3, 4]
588
bars = ax9.barh(y_pos, complexity, color=['lightblue', 'lightgreen', 'lightcoral'])
589
590
ax9.set_yticks(y_pos)
591
ax9.set_yticklabels(model_types)
592
ax9.set_xlabel('Computational Complexity')
593
ax9.set_title('Modeling Approaches')
594
595
plt.tight_layout()
596
plt.savefig('assets/mathematical_modeling.pdf', dpi=300, bbox_inches='tight')
597
plt.close()
598
599
print("Mathematical modeling analysis saved to assets/mathematical\\_modeling.pdf")
600
\end{pycode}
601
602
\begin{figure}[H]
603
\centering
604
\includegraphics[width=0.95\textwidth]{assets/mathematical_modeling.pdf}
605
\caption{Comprehensive mathematical modeling and simulation analysis including Lotka-Volterra predator-prey dynamics, phase portraits, SIR epidemic models, Monte Carlo convergence, random walk trajectories, displacement distributions, flocking behavior, and computational complexity comparison of modeling approaches.}
606
\label{fig:mathematical-modeling}
607
\end{figure}
608
609
\section{Conclusion}
610
\label{sec:conclusion}
611
612
This mathematical modeling template demonstrates diverse computational approaches including:
613
614
\begin{itemize}
615
\item Dynamical systems analysis (Lotka-Volterra, SIR models)
616
\item Monte Carlo methods and stochastic simulation
617
\item Agent-based modeling and emergent behavior
618
\item Stability analysis and bifurcation theory
619
\item Professional visualization of complex systems
620
\end{itemize}
621
622
These methods provide powerful tools for understanding complex systems across biology, physics, and social sciences.
623
624
\printbibliography
625
626
\end{document}
627