#set document(title: "3.1 Step Forcing", 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")) == 3.1#h(0.6em)Step Forcing #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Objectives] - Model an input that switches on at time #math.equation(block: false, alt: "t equals a")[$t = a$] with the Heaviside step function #math.equation(block: false, alt: "u sub a open parenthesis t close parenthesis")[$u_(a) ( t )$]. - Transform a constant-coefficient equation into algebra, solve for the transform of the response, and invert it by partial fractions. - Read the factor #math.equation(block: false, alt: "e to the power minus a s")[$e^(− a s)$] in the shifting rule as a pure delay of the whole response. ] A furnace, a relay, a charging circuit — real inputs are #emph[switched]. The cleanest model of a switch is the #emph[Heaviside step function] #math.equation(block: false, alt: "u sub a open parenthesis t close parenthesis")[$u_(a) ( t )$], equal to #math.equation(block: false, alt: "0")[$0$] for #math.equation(block: false, alt: "t less than a")[$t < a$] and to #math.equation(block: false, alt: "1")[$1$] for #math.equation(block: false, alt: "t greater than a")[$t > a$]: nothing, then suddenly something. (The figure below builds it arithmetically as #math.equation(block: false, alt: "the fraction 1 over 2 open parenthesis s i g n open parenthesis t minus a close parenthesis plus 1 close parenthesis")[$frac(1, 2) ( upright(s) upright(i) upright(g) upright(n) ( t − a ) + 1 )$], which is #math.equation(block: false, alt: "0")[$0$] before the switch and #math.equation(block: false, alt: "1")[$1$] after it.) An input with a jump defeats any method that wants one smooth formula for all time, so this section adopts a tool that ingests the whole history at once. The #emph[Laplace transform] trades a function of time for a function of a new variable #math.equation(block: false, alt: "s")[$s$], #math.equation(block: true, alt: "F open parenthesis s close parenthesis equals ℒ { f } open parenthesis s close parenthesis equals ∫ 0 infinity e to the power minus s t f open parenthesis t close parenthesis d t ,")[$F ( s ) = ℒ \{ f \} ( s ) = ∫_(0)^(∞) e^(− s t) f ( t ) d t ,$] and its worth rests on three dictionary entries. Differentiation becomes multiplication: #math.equation(block: false, alt: "ℒ { x prime } equals s X open parenthesis s close parenthesis minus x open parenthesis 0 close parenthesis")[$ℒ \{ x^(′) \} = s X ( s ) − x ( 0 )$] and #math.equation(block: false, alt: "ℒ { x double prime } equals s squared X open parenthesis s close parenthesis minus s x open parenthesis 0 close parenthesis minus x prime open parenthesis 0 close parenthesis")[$ℒ \{ x^(″) \} = s^(2) X ( s ) − s x ( 0 ) − x^(′) ( 0 )$]. The constant #math.equation(block: false, alt: "1")[$1$] becomes #math.equation(block: false, alt: "1 / s")[$1 / s$]. And a delayed copy of a signal becomes an exponential tag — the #emph[shifting rule] #math.equation(block: true, alt: "ℒ { u sub a open parenthesis t close parenthesis f open parenthesis t minus a close parenthesis } equals e to the power minus a s F open parenthesis s close parenthesis ,")[$ℒ \{ u_(a) ( t ) f ( t − a ) \} = e^(− a s) F ( s ) ,$] whose right side is the transform of #math.equation(block: false, alt: "f")[$f$] multiplied by a factor that says "start this at #math.equation(block: false, alt: "t equals a")[$t = a$] instead of #math.equation(block: false, alt: "t equals 0")[$t = 0$]." In particular #math.equation(block: false, alt: "ℒ { u sub a open parenthesis t close parenthesis } equals e to the power minus a s / s")[$ℒ \{ u_(a) ( t ) \} = e^(− a s) / s$]. Now the model problem. Take a damped spring from the family of Chapter 2 — damping #math.equation(block: false, alt: "a equals 1")[$a = 1$], frequency #math.equation(block: false, alt: "b equals 3")[$b = 3$], characteristic roots #math.equation(block: false, alt: "minus 1 ± 3 i")[$− 1 ± 3 i$] — sitting at rest until a constant force switches on: #math.equation(block: true, alt: "x double prime plus 2 x prime plus 10 x equals 10 u sub a open parenthesis t close parenthesis , x open parenthesis 0 close parenthesis equals x prime open parenthesis 0 close parenthesis equals 0 .")[$x^(″) + 2 x^(′) + 10 x = 10 u_(a) ( t ) , #h(2em) x ( 0 ) = x^(′) ( 0 ) = 0 .$] Transforming every term (the initial conditions contribute nothing, being zero) gives #math.equation(block: false, alt: "open parenthesis s squared plus 2 s plus 10 close parenthesis X open parenthesis s close parenthesis equals 10 e to the power minus a s / s")[$( s^(2) + 2 s + 10 ) X ( s ) = 10 e^(− a s) / s$], so #math.equation(block: true, alt: "X open parenthesis s close parenthesis equals e to the power minus a s times the fraction 10 over s open parenthesis s squared plus 2 s plus 10 close parenthesis equals e to the power minus a s open parenthesis the fraction 1 over s minus the fraction s plus 1 over open parenthesis s plus 1 close parenthesis squared plus 9 minus the fraction 1 over 3 times the fraction 3 over open parenthesis s plus 1 close parenthesis squared plus 9 close parenthesis .")[$X ( s ) = e^(− a s) · frac(10, s ( s^(2) + 2 s + 10 )) = e^(− a s) ( frac(1, s) − frac(s + 1, ( s + 1 )^(2) + 9) − frac(1, 3) · frac(3, ( s + 1 )^(2) + 9) ) .$] The three pieces inside the parentheses are standard: #math.equation(block: false, alt: "1 / s")[$1 / s$] is the constant #math.equation(block: false, alt: "1")[$1$], and the two shifted fractions are the transforms of #math.equation(block: false, alt: "e to the power minus t cos 3 t")[$e^(− t) cos 3 t$] and #math.equation(block: false, alt: "the fraction 1 over 3 e to the power minus t sin 3 t")[$frac(1, 3) e^(− t) sin 3 t$]. So without its tag the response would be #math.equation(block: false, alt: "f open parenthesis t close parenthesis equals 1 minus e to the power minus t open parenthesis cos 3 t plus the fraction 1 over 3 sin 3 t close parenthesis")[$f ( t ) = 1 − e^(− t) ( cos 3 t + frac(1, 3) sin 3 t )$], and the tag #math.equation(block: false, alt: "e to the power minus a s")[$e^(− a s)$] delays it wholesale: #math.equation(block: true, alt: "x open parenthesis t close parenthesis equals u sub a open parenthesis t close parenthesis [ 1 minus e to the power minus open parenthesis t minus a close parenthesis open parenthesis cos 3 open parenthesis t minus a close parenthesis plus the fraction 1 over 3 sin 3 open parenthesis t minus a close parenthesis close parenthesis ] .")[$x ( t ) = u_(a) ( t ) [ 1 − e^(− ( t − a )) ( cos 3 ( t − a ) + frac(1, 3) sin 3 ( t − a ) ) ] .$] Nothing happens until #math.equation(block: false, alt: "t equals a")[$t = a$]; then the mass climbs toward the new equilibrium #math.equation(block: false, alt: "x equals 1")[$x = 1$], overshoots it, and rings its way down onto it at the free-vibration frequency #math.equation(block: false, alt: "3")[$3$]. {"camera":{"fov":50,"position":\[6,0.7,9\],"projection":"perspective","target":\[6,0.7,0\]},"grid":{"axisColors":{"x":"\#ef4444","y":"\#22c55e","z":"\#3b82f6"},"divisions":12,"gridColor":"\#e5e7eb","showAxes":true,"showLabels":true,"size":12,"visible":true},"id":"61164788-cd5c-4583-b0bc-34a0a648fac5","metadata":{"alt\_text":"A red curve that lies flat at zero, then at the switch-on time springs upward, overshoots a dashed horizontal line at height 1, rings through a few shrinking oscillations, and settles onto the dashed line. The slider a slides the switch-on moment anywhere from t = 1 to t = 8, carrying the entire ringing pattern rigidly with it.","created\_at":"2026-08-01T00:00:00.000Z","description":"Rest-to-rest step response x(t) = u\_a(t)\[1 - e^(-(t-a))(cos 3(t-a) + (1/3) sin 3(t-a))\] of x'' + 2x' + 10x = 10 u\_a(t) on t in \[0, 12\], built with the step trick (sign(t-a)+1)/2; the slider a moves the switch-on time.","tags":\["diffeq","laplace","step-function","forcing","slider"\],"updated\_at":"2026-08-01T00:00:00.000Z"},"objects":\[{"id":"14c00a4b-b58a-4a4c-9587-ec466097dff1","kind":"parameter","label":{"text":"a = switch-on time","visible":true},"max":8,"min":1,"name":"a","step":0.1,"value":3,"visible":true},{"id":"062f06b8-d2c2-45da-a087-fe2d40204b6a","kind":"parametric-curve","label":{"text":"step response, switched on at t = a","visible":true},"samples":2400,"style":{"color":"\#ef4444","dash":\[\],"lineWidth":4},"tDomain":\[0,12\],"visible":true,"xExpr":"t","yExpr":"((sign(t-a)+1)/2)\*(1 - exp(-(t-a))\*(cos(3\*(t-a)) + sin(3\*(t-a))/3))","zExpr":"0"},{"id":"c9c16655-7836-4388-b5ae-e6e858c18108","kind":"parametric-curve","label":{"text":"new equilibrium x = 1","visible":true},"samples":100,"style":{"color":"\#9ca3af","dash":\[5,5\],"lineWidth":2},"tDomain":\[0,12\],"visible":true,"xExpr":"t","yExpr":"1","zExpr":"0"}\],"title":"Switching on: response to a step input at t = a","version":1} The rest-to-rest step response #math.equation(block: false, alt: "x open parenthesis t close parenthesis equals u sub a open parenthesis t close parenthesis [ 1 minus e to the power minus open parenthesis t minus a close parenthesis open parenthesis cos 3 open parenthesis t minus a close parenthesis plus the fraction 1 over 3 sin 3 open parenthesis t minus a close parenthesis close parenthesis ]")[$x ( t ) = u_(a) ( t ) [ 1 − e^(− ( t − a )) ( cos 3 ( t − a ) + frac(1, 3) sin 3 ( t − a ) ) ]$] of #math.equation(block: false, alt: "x double prime plus 2 x prime plus 10 x equals 10 u sub a open parenthesis t close parenthesis")[$x^(″) + 2 x^(′) + 10 x = 10 u_(a) ( t )$]. The dashed line is the new equilibrium #math.equation(block: false, alt: "x equals 1")[$x = 1$]; the slider #math.equation(block: false, alt: "a")[$a$] sets the switch-on time and carries the entire ringing pattern rigidly with it. === Explore + #strong[Observe.] With #math.equation(block: false, alt: "a equals 3")[$a = 3$], the curve before the switch is not merely small — it is exactly zero. Explain from the equation why rest plus zero forcing means zero, identically. Then count how many times the curve visibly crosses the dashed line before settling onto it. + #strong[Predict.] You are about to drag #math.equation(block: false, alt: "a")[$a$] from #math.equation(block: false, alt: "3")[$3$] to #math.equation(block: false, alt: "6")[$6$]. Commit first: will the response change its shape, its height, or only its starting point? + #strong[Verify.] Drag. The whole pattern translates rigidly — the climb, the first peak, and each ring sit at the same distances after the switch, wherever the switch is. That rigidity is the factor #math.equation(block: false, alt: "e to the power minus a s")[$e^(− a s)$] made visible: a delay in time and nothing else. + #strong[Observe.] Read the first peak at any #math.equation(block: false, alt: "a")[$a$]: height about #math.equation(block: false, alt: "1.35")[$1.35$], reached about #math.equation(block: false, alt: "1.05")[$1.05$] after switch-on. The second peak is barely above the dashed line, near #math.equation(block: false, alt: "1.04")[$1.04$]. The overshoot has collapsed to roughly an eighth of its first value in a single ring. + #strong[Predict, then verify.] Push #math.equation(block: false, alt: "a")[$a$] to #math.equation(block: false, alt: "8")[$8$]. Which features of the response still fit in the window #math.equation(block: false, alt: "t less than or equal to 12")[$t ≤ 12$], and which have fallen off the right edge? What would a switch at #math.equation(block: false, alt: "t equals 12")[$t = 12$] show? === Connect The response has two personalities, and the partial fractions found them mechanically. The term #math.equation(block: false, alt: "1 / s")[$1 / s$] inverts to the #emph[steady state] #math.equation(block: false, alt: "x equals 1")[$x = 1$], where the new constant force #math.equation(block: false, alt: "10")[$10$] exactly balances the spring force #math.equation(block: false, alt: "10 x")[$10 x$]. The remaining terms invert to the #emph[transient] — a free damped vibration straight out of Chapter 2, born at the switching instant and dying like #math.equation(block: false, alt: "e to the power minus open parenthesis t minus a close parenthesis")[$e^(− ( t − a ))$]. No new behavior was invented at the switch: the denominator #math.equation(block: false, alt: "open parenthesis s plus 1 close parenthesis squared plus 9")[$( s + 1 )^(2) + 9$] is the characteristic polynomial #math.equation(block: false, alt: "s squared plus 2 s plus 10")[$s^(2) + 2 s + 10$] wearing its roots #math.equation(block: false, alt: "minus 1 ± 3 i")[$− 1 ± 3 i$] on its sleeve, so the ringing frequency and decay rate after the jump are the ones the free system always had. The shifting rule also handles switching #emph[off]. A force applied only for #math.equation(block: false, alt: "a less than or equal to t less than or equal to b")[$a ≤ t ≤ b$] is #math.equation(block: false, alt: "u sub a open parenthesis t close parenthesis minus u sub b open parenthesis t close parenthesis")[$u_(a) ( t ) − u_(b) ( t )$], and by linearity the response is #math.equation(block: false, alt: "f open parenthesis t minus a close parenthesis u sub a open parenthesis t close parenthesis minus f open parenthesis t minus b close parenthesis u sub b open parenthesis t close parenthesis")[$f ( t − a ) u_(a) ( t ) − f ( t − b ) u_(b) ( t )$]: turn on the response, then turn on its negative. A whole chain of switches — on, off, on, off — costs one tagged term per switch, bookkeeping that the next section compresses into a geometric series. #examplebox("Example 1")[How big is the overshoot?][ Show that the first peak of the step response exceeds the equilibrium #math.equation(block: false, alt: "x equals 1")[$x = 1$] by #math.equation(block: false, alt: "e to the power minus π / 3 approximately equals 0.35")[$e^(− π / 3) ≈ 0.35$], no matter where the switch-on time #math.equation(block: false, alt: "a")[$a$] sits. Write #math.equation(block: false, alt: "τ equals t minus a")[$τ = t − a$] and #math.equation(block: false, alt: "f open parenthesis τ close parenthesis equals 1 minus e to the power minus τ open parenthesis cos 3 τ plus the fraction 1 over 3 sin 3 τ close parenthesis")[$f ( τ ) = 1 − e^(− τ) ( cos 3 τ + frac(1, 3) sin 3 τ )$]. Differentiating, the cosine terms cancel and #math.equation(block: false, alt: "f prime open parenthesis τ close parenthesis equals the fraction 10 over 3 e to the power minus τ sin 3 τ")[$f^(′) ( τ ) = frac(10, 3) e^(− τ) sin 3 τ$], which is positive until #math.equation(block: false, alt: "3 τ equals π")[$3 τ = π$] and changes sign there: the first peak comes #math.equation(block: false, alt: "τ equals π / 3 approximately equals 1.05")[$τ = π / 3 ≈ 1.05$] after the switch. Its height is #math.equation(block: false, alt: "f open parenthesis π / 3 close parenthesis equals 1 minus e to the power minus π / 3 cos π equals 1 plus e to the power minus π / 3 approximately equals 1.35")[$f ( π / 3 ) = 1 − e^(− π / 3) cos π = 1 + e^(− π / 3) ≈ 1.35$] — a #math.equation(block: false, alt: "35")[$35$] overshoot. The second peak, at #math.equation(block: false, alt: "τ equals π")[$τ = π$], has height #math.equation(block: false, alt: "1 plus e to the power minus π approximately equals 1.04")[$1 + e^(− π) ≈ 1.04$], so each successive overshoot is #math.equation(block: false, alt: "e to the power minus 2 π / 3 approximately equals 0.12")[$e^(− 2 π / 3) ≈ 0.12$] times the one before — one dramatic swing, one faint echo, then a flat line, exactly what the figure shows. Since #math.equation(block: false, alt: "f")[$f$] depends only on #math.equation(block: false, alt: "τ")[$τ$], none of these numbers move when the slider does. ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ The Laplace transform turns calculus into algebra and switching into multiplication: derivatives become powers of #math.equation(block: false, alt: "s")[$s$], a jump at #math.equation(block: false, alt: "t equals a")[$t = a$] becomes the tag #math.equation(block: false, alt: "e to the power minus a s")[$e^(− a s)$], and the tagged response is the untagged one, delayed. One partial-fraction computation hands back the whole story — steady state, transient, overshoot and all. ]