#set document(title: "2.2 Beats and Resonance", author: "XYZ Homework") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy — section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 — AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 2.2#h(0.6em)Beats and Resonance #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Objectives] - Solve a forced undamped oscillator with the method of undetermined coefficients. - Rewrite a difference of cosines as a product to expose the fast oscillation and the slow envelope. - Explain why the amplitude blows up as the forcing frequency approaches the natural frequency. ] Attach the mass to a shaker and drive it. With no damping, and with the spring tuned so the system's #emph[natural frequency] is #math.equation(block: false, alt: "2")[$2$], the equation is #math.equation(block: true, alt: "x double prime plus 4 x equals cos open parenthesis a t close parenthesis ,")[$x^(″) + 4 x = cos ( a t ) ,$] where #math.equation(block: false, alt: "a")[$a$] is the frequency you choose to push at. The method of undetermined coefficients says: guess a response of the same shape as the input, #math.equation(block: false, alt: "x sub p equals A cos open parenthesis a t close parenthesis")[$x_(p) = A cos ( a t )$]. Substituting gives #math.equation(block: false, alt: "minus a squared A cos open parenthesis a t close parenthesis plus 4 A cos open parenthesis a t close parenthesis equals cos open parenthesis a t close parenthesis")[$− a^(2) A cos ( a t ) + 4 A cos ( a t ) = cos ( a t )$], so #math.equation(block: false, alt: "A equals 1 / open parenthesis 4 minus a squared close parenthesis")[$A = 1 / ( 4 − a^(2) )$] — provided #math.equation(block: false, alt: "a not equal to 2")[$a ≠ 2$]. Adding the homogeneous solution and imposing rest initial conditions #math.equation(block: false, alt: "x open parenthesis 0 close parenthesis equals x prime open parenthesis 0 close parenthesis equals 0")[$x ( 0 ) = x^(′) ( 0 ) = 0$] produces #math.equation(block: true, alt: "x open parenthesis t close parenthesis equals the fraction cos open parenthesis a t close parenthesis minus cos open parenthesis 2 t close parenthesis over 4 minus a squared .")[$x ( t ) = frac(cos ( a t ) − cos ( 2 t ), 4 − a^(2)) .$] The denominator is the whole story in miniature. Push at a frequency far from #math.equation(block: false, alt: "2")[$2$] and the response is small; push near #math.equation(block: false, alt: "2")[$2$] and #math.equation(block: false, alt: "4 minus a squared")[$4 − a^(2)$] is tiny, so the response is enormous. But the shape is stranger than "big" — as the figure shows, the motion swells and collapses in slow packets. {"camera":{"fov":50,"position":\[20,0,30\],"projection":"perspective","target":\[20,0,0\]},"grid":{"axisColors":{"x":"\#ef4444","y":"\#22c55e","z":"\#3b82f6"},"divisions":20,"gridColor":"\#e5e7eb","showAxes":true,"showLabels":true,"size":40,"visible":true},"id":"cb96b1ee-1328-42c1-b47c-78ea86df279d","metadata":{"alt\_text":"A red wave along the time axis whose amplitude swells and shrinks in slow packets: fast oscillations inside a slowly waving envelope, the classic picture of beats. Dragging the slider a toward the natural frequency 2 stretches the packets longer and taller, so near a = 1.95 a single enormous swell fills the window - the approach to resonance.","created\_at":"2026-08-01T00:00:00.000Z","description":"Rest-start response x(t) = (cos(a t) - cos(2 t))/(4 - a^2) of the forced oscillator x'' + 4x = cos(a t) on t in \[0, 40\], with the forcing frequency slider a in \[1, 1.95\] closing in on the natural frequency 2.","tags":\["diffeq","second-order","beats","resonance","slider"\],"updated\_at":"2026-08-01T00:00:00.000Z"},"objects":\[{"id":"87903b77-fb5b-4833-972b-6a512c8e66ee","kind":"parameter","label":{"text":"a = forcing frequency (natural = 2)","visible":true},"max":1.95,"min":1,"name":"a","step":0.01,"value":1.6,"visible":true},{"id":"e7f08e23-a0d8-42da-8bae-d0f2ec2ac125","kind":"parametric-curve","label":{"text":"x(t) = (cos at - cos 2t)/(4 - a^2)","visible":true},"samples":2400,"style":{"color":"\#ef4444","dash":\[\],"lineWidth":4},"tDomain":\[0,40\],"visible":true,"xExpr":"t","yExpr":"(1/(4 - a\*a))\*(cos(a\*t) - cos(2\*t))","zExpr":"0"}\],"title":"Forced oscillator: beats grow into resonance as a approaches 2","version":1} The rest-start response of #math.equation(block: false, alt: "x double prime plus 4 x equals cos open parenthesis a t close parenthesis")[$x^(″) + 4 x = cos ( a t )$], an undamped oscillator with natural frequency #math.equation(block: false, alt: "2")[$2$]. Dragging the forcing frequency #math.equation(block: false, alt: "a")[$a$] toward #math.equation(block: false, alt: "2")[$2$] lengthens and heightens the beat packets — the run-up to resonance. === Explore + #strong[Observe.] Set #math.equation(block: false, alt: "a equals 1")[$a = 1$], well away from resonance. The motion is bounded and busy. Estimate the largest height it ever reaches, and compare it to the coefficient #math.equation(block: false, alt: "1 / open parenthesis 4 minus a squared close parenthesis equals 1 / 3")[$1 / ( 4 − a^(2) ) = 1 / 3$]. + #strong[Predict.] Move #math.equation(block: false, alt: "a")[$a$] to #math.equation(block: false, alt: "1.6")[$1.6$]. Will the packets get longer, shorter, taller, or shorter and taller? Write your guess down first. + #strong[Verify.] Drag to #math.equation(block: false, alt: "a equals 1.6")[$a = 1.6$], then #math.equation(block: false, alt: "a equals 1.8")[$a = 1.8$], then #math.equation(block: false, alt: "a equals 1.9")[$a = 1.9$]. Record roughly how many packets fit in the window at each setting. The packet count is falling — toward what, as #math.equation(block: false, alt: "a → 2")[$a → 2$]? + #strong[Observe.] At #math.equation(block: false, alt: "a equals 1.95")[$a = 1.95$] a single swell nearly fills the window. The amplitude scale has changed dramatically. Compute #math.equation(block: false, alt: "1 / open parenthesis 4 minus a squared close parenthesis")[$1 / ( 4 − a^(2) )$] at this setting and see whether it matches the height you observe. + #strong[Predict, then reason.] What does the formula do at exactly #math.equation(block: false, alt: "a equals 2")[$a = 2$]? The slider stops just short — explain from the algebra why the figure cannot draw the resonant case, and what the true resonant solution must look like instead. === Connect The product-to-sum identity turns the response into #math.equation(block: true, alt: "x open parenthesis t close parenthesis equals the fraction 2 over 4 minus a squared sin open parenthesis the fraction 2 plus a over 2 t close parenthesis sin open parenthesis the fraction 2 minus a over 2 t close parenthesis ,")[$x ( t ) = frac(2, 4 − a^(2)) sin ( frac(2 + a, 2) t ) sin ( frac(2 − a, 2) t ) ,$] and now the two time scales are visible separately. The first sine oscillates at roughly the average frequency — that is the fast wiggle you see. The second oscillates at half the #emph[difference] #math.equation(block: false, alt: "2 minus a")[$2 − a$], which is small when #math.equation(block: false, alt: "a")[$a$] is near #math.equation(block: false, alt: "2")[$2$], and it acts as a slowly varying amplitude: the envelope. This is the phenomenon of #emph[beats], the same effect a piano tuner hears as a slow throb when a string is close to but not on pitch. As #math.equation(block: false, alt: "a → 2")[$a → 2$] the envelope period #math.equation(block: false, alt: "4 π / open parenthesis 2 minus a close parenthesis")[$4 π / ( 2 − a )$] grows without bound and the coefficient #math.equation(block: false, alt: "2 / open parenthesis 4 minus a squared close parenthesis")[$2 / ( 4 − a^(2) )$] grows with it. At exactly #math.equation(block: false, alt: "a equals 2")[$a = 2$] the guess #math.equation(block: false, alt: "A cos 2 t")[$A cos 2 t$] fails, because #math.equation(block: false, alt: "cos 2 t")[$cos 2 t$] already solves the homogeneous equation — the standard repair is to multiply by #math.equation(block: false, alt: "t")[$t$], and the true resonant solution is #math.equation(block: false, alt: "x open parenthesis t close parenthesis equals the fraction 1 over 4 t sin 2 t")[$x ( t ) = frac(1, 4) t sin 2 t$]. The envelope is no longer a slow sine but the straight line #math.equation(block: false, alt: "± t / 4")[$± t / 4$]: amplitude that grows forever. Real systems have damping, which caps the growth at a large but finite value, and real structures are designed to keep their natural frequencies away from the frequencies they will be driven at. #examplebox("Example 1")[How close is too close?][ For #math.equation(block: false, alt: "x double prime plus 4 x equals cos open parenthesis a t close parenthesis")[$x^(″) + 4 x = cos ( a t )$] with rest initial conditions, find the forcing frequency #math.equation(block: false, alt: "a less than 2")[$a < 2$] at which the steady amplitude coefficient first exceeds #math.equation(block: false, alt: "5")[$5$], and find the beat period there. The coefficient is #math.equation(block: false, alt: "1 / open parenthesis 4 minus a squared close parenthesis")[$1 / ( 4 − a^(2) )$], and #math.equation(block: false, alt: "1 / open parenthesis 4 minus a squared close parenthesis greater than 5")[$1 / ( 4 − a^(2) ) > 5$] requires #math.equation(block: false, alt: "4 minus a squared less than 1 / 5")[$4 − a^(2) < 1 / 5$], so #math.equation(block: false, alt: "a squared greater than 3.8")[$a^(2) > 3.8$] and #math.equation(block: false, alt: "a greater than the square root of 3.8 approximately equals 1.949")[$a > sqrt(3.8) ≈ 1.949$]. The beat envelope has period #math.equation(block: false, alt: "4 π / open parenthesis 2 minus a close parenthesis approximately equals 4 π / 0.051 approximately equals 246")[$4 π / ( 2 − a ) ≈ 4 π / 0.051 ≈ 246$] — vastly longer than the window in the figure, which is why at #math.equation(block: false, alt: "a equals 1.95")[$a = 1.95$] you see a single rising swell rather than a repeating pattern. Detuning by less than #math.equation(block: false, alt: "3")[$3$] has both multiplied the response fivefold and pushed the beat period past anything an observer would recognize as a beat. ]