# 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()