Chapter 7: Resonance and Forced OscillationsΒΆ

Driving a SystemΒΆ

What happens when you apply an external force to an oscillator?

The EquationΒΆ

\[ m\frac{d^2x}{dt^2} + b\frac{dx}{dt} + kx = F_0\cos(\omega t) \]

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