Chapter 7: Resonance and Forced OscillationsΒΆ
Driving a SystemΒΆ
What happens when you apply an external force to an oscillator?
The EquationΒΆ
Mass-spring-damper with external force!
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
sns.set_style('whitegrid')
plt.rcParams['figure.figsize'] = (14, 10)
np.set_printoptions(precision=3, suppress=True)
Resonance: When Driving Frequency Matches Natural FrequencyΒΆ
Resonance occurs when the external driving frequency \(\omega\) matches the systemβs natural frequency \(\omega_0 = \sqrt{k/m}\). At resonance, energy from the driving force is absorbed maximally efficiently, causing the amplitude to grow dramatically β in the undamped case, it grows linearly without bound as \(x(t) \propto t \sin(\omega_0 t)\).
With damping (\(b > 0\)), the amplitude reaches a finite but potentially very large peak near \(\omega = \omega_0\). The sharpness of this peak depends on the quality factor \(Q = \omega_0 m / b\) β higher \(Q\) means sharper resonance.
Connection to ML/AI: Resonance-like phenomena appear in neural network training. When the learning rate creates oscillatory dynamics that align with the curvature of the loss landscape, training can either accelerate (constructive resonance, exploited by cyclical learning rates) or destabilize (destructive resonance, causing divergence). The damping term is analogous to momentum decay in optimizers like Adam. Understanding resonance helps explain why certain hyperparameter combinations cause training instability while others lead to rapid convergence.
def resonance_demo():
"""Show resonance phenomenon."""
t = np.linspace(0, 50, 1000)
omega_0 = 1.0 # Natural frequency
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
omegas = [0.5, 0.9, 1.0, 1.5] # Driving frequencies
for ax, omega in zip(axes.flat, omegas):
# Simplified response
if abs(omega - omega_0) < 0.01:
x = t * np.sin(omega_0 * t) # Resonance!
else:
x = np.sin(omega * t) / abs(omega**2 - omega_0**2)
ax.plot(t, x, 'b-', linewidth=1)
ax.set_title(f'Ο = {omega} (Οβ = {omega_0})', fontweight='bold')
ax.set_xlabel('Time')
ax.set_ylabel('Amplitude')
ax.grid(True, alpha=0.3)
ax.set_ylim(-15, 15)
plt.tight_layout()
plt.show()
resonance_demo()