summaryrefslogtreecommitdiff
path: root/tutorials/module_1/errorPlots.py
diff options
context:
space:
mode:
Diffstat (limited to 'tutorials/module_1/errorPlots.py')
-rw-r--r--tutorials/module_1/errorPlots.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/tutorials/module_1/errorPlots.py b/tutorials/module_1/errorPlots.py
new file mode 100644
index 0000000..8351fc8
--- /dev/null
+++ b/tutorials/module_1/errorPlots.py
@@ -0,0 +1,144 @@
+# Import required packages
+import numpy as np
+import matplotlib.pyplot as plt
+
+# ---------------------------------------------------------------------------
+# PART 1: Visualizing Truncation Error and Approximate Integral
+# ---------------------------------------------------------------------------
+
+# Generate true curve: y = sin(x)
+x_fine = np.linspace(0, np.pi/2, 400)
+y_fine = np.sin(x_fine)
+
+# Linear approximation (straight line between 0 and pi/2)
+x_line = np.array([0, np.pi/2])
+y_line = np.sin(x_line)
+
+# Plot true curve and linear approximation
+plt.figure(figsize=(8, 6))
+
+plt.plot(x_fine, y_fine, label='True function: $y = \sin(x)$', color='black', linewidth=3)
+plt.plot(x_line, y_line, label='Linear approximation', color='red', linestyle='--', linewidth=2)
+
+# Shade area between true curve and linear approximation (truncation error)
+plt.fill_between(x_fine, y_fine, np.interp(x_fine, x_line, y_line),
+ where=(y_fine > np.interp(x_fine, x_line, y_line)),
+ interpolate=True, color='gray', alpha=0.5, label='Truncation Error')
+
+# Shade approximate integral (area under linear approximation)
+plt.fill_between(x_fine, 0, np.interp(x_fine, x_line, y_line),
+ color='lightblue', alpha=0.5, label='Approximate Integral')
+
+# Remove ticks
+plt.xticks([])
+plt.yticks([])
+plt.grid(False)
+
+# Labels and title
+plt.xlabel('x', fontsize=20)
+plt.ylabel('y', fontsize=20)
+plt.title('Truncation Error', fontsize=22)
+plt.legend(fontsize=16, loc='lower right')
+plt.tight_layout()
+plt.show()
+
+# ---------------------------------------------------------------------------
+# PART 2: Error Plot for Truncation, Round-off, and Total Errors
+# ---------------------------------------------------------------------------
+
+# Set up for log-log error plot
+h = np.logspace(-16, -1, 400)
+truncation_error = 1e-1 * h
+roundoff_error = 1e-16 / h
+total_error = truncation_error + roundoff_error
+
+# Find minimum total error point
+min_idx = np.argmin(total_error)
+min_h = h[min_idx]
+arrow_target_h = 2.5 * min_h
+arrow_target_err = total_error[np.argmin(np.abs(h - arrow_target_h))]
+
+# Plot errors
+plt.figure(figsize=(10, 7))
+
+plt.loglog(h, truncation_error, label='Truncation error', linewidth=3, color='blue')
+plt.loglog(h, roundoff_error, label='Round-off error', linewidth=3, color='orange')
+plt.loglog(h, total_error, label='Total error', linewidth=4, color='black')
+
+# Annotation
+plt.annotate('Point of\n diminishing\n returns',
+ xy=(arrow_target_h, arrow_target_err), xycoords='data',
+ xytext=(arrow_target_h, 15 * arrow_target_err), textcoords='data',
+ arrowprops=dict(arrowstyle='->', lw=2),
+ fontsize=20, ha='center')
+
+# Remove ticks and grid
+plt.xticks([])
+plt.yticks([])
+plt.grid(False)
+
+# Labels and legend
+plt.xlabel('Log step size', fontsize=22)
+plt.ylabel('Log error', fontsize=22)
+plt.legend(fontsize=20, loc='upper right')
+plt.tight_layout()
+plt.show()
+
+
+# ---------------------------------------------------------------------------
+# PART 3: Error Plot for Truncation with more steps
+# ---------------------------------------------------------------------------
+
+# Fix legend duplication and improve clarity
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Generate true curve: y = sin(x) over 0 to π
+x_fine = np.linspace(0, np.pi, 800)
+y_fine = np.sin(x_fine)
+
+# Choose multiple linear segments
+n_steps = 3 # number of straight line segments
+x_steps = np.linspace(0, np.pi, n_steps + 1)
+y_steps = np.sin(x_steps)
+
+# Plot true curve
+plt.figure(figsize=(8, 6))
+plt.plot(x_fine, y_fine, label='True function: $y = \\sin(x)$', color='black', linewidth=3)
+
+# Plot piecewise linear approximation
+plt.plot(x_steps, y_steps, label='Linear approximation', color='red', linestyle='--', linewidth=2)
+
+# Track whether we've added the truncation label already
+truncation_label_added = False
+
+# Shade truncation error (avoid duplicate legend entry)
+for i in range(n_steps):
+ x_segment = np.linspace(x_steps[i], x_steps[i+1], 100)
+ y_segment_line = np.interp(x_segment, [x_steps[i], x_steps[i+1]], [y_steps[i], y_steps[i+1]])
+ y_segment_true = np.sin(x_segment)
+
+ label = 'Truncation error' if not truncation_label_added else None
+ plt.fill_between(x_segment, y_segment_true, y_segment_line,
+ where=(y_segment_true > y_segment_line),
+ interpolate=True, color='gray', alpha=0.5, label=label)
+ truncation_label_added = True
+
+# Shade approximate integral under the piecewise linear approximation
+plt.fill_between(x_fine, 0, np.interp(x_fine, x_steps, y_steps),
+ color='lightblue', alpha=0.5, label='Approximate integral')
+
+# Remove ticks
+plt.xticks([])
+plt.yticks([])
+plt.grid(False)
+
+# Labels and title
+plt.xlabel('x', fontsize=20)
+plt.ylabel('y', fontsize=20)
+plt.title('Truncation Error', fontsize=24)
+plt.legend(fontsize=16, loc='lower right')
+plt.tight_layout()
+plt.show()
+
+