#set document(title: "5.3 Complex Eigenvalues and the Spiral", 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")) == 5.3#h(0.6em)Complex Eigenvalues and the Spiral #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Objectives] - Recognize rotation–scaling matrices as the matrices with no real eigenvector. - Compute their complex eigenvalues and read modulus and argument as growth factor and rotation rate. - Predict the fate of an iterated point — spiral in, circle, or spiral out — from the modulus alone. ] Some matrices turn #emph[every] direction. The cleanest examples are the rotation–scaling matrices: rotate the plane by an angle #math.equation(block: false, alt: "b")[$b$], then scale it by a factor #math.equation(block: false, alt: "a greater than 0")[$a > 0$]. Written out, this map sends #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] to #math.equation(block: false, alt: "open parenthesis a cos b x minus a sin b y , a sin b x plus a cos b y close parenthesis")[$( a cos b #h(0.278em) x − a sin b #h(0.278em) y , #h(0.278em) #h(0.278em) a sin b #h(0.278em) x + a cos b #h(0.278em) y )$]. If #math.equation(block: false, alt: "sin b not equal to 0")[$sin b ≠ 0$], every nonzero vector is rotated by the full angle #math.equation(block: false, alt: "b")[$b$] — no line is invariant, no real eigenvector exists, and the hunts of the last two sections come home empty. The misalignment function never touches zero. Yet the matrix still has structure, and the way to see it is to #emph[iterate]. Start at the point #math.equation(block: false, alt: "open parenthesis 2 , 0 close parenthesis")[$( 2 , 0 )$] and apply the matrix over and over. Each application multiplies the distance from the origin by #math.equation(block: false, alt: "a")[$a$] and advances the angle by #math.equation(block: false, alt: "b")[$b$], so after #math.equation(block: false, alt: "k")[$k$] steps the point sits at #math.equation(block: false, alt: "2 a to the power k open parenthesis cos k b , sin k b close parenthesis")[$2 a^(k) ( cos k b , #h(0.278em) sin k b )$]. Letting the step count run continuously traces the curve #math.equation(block: false, alt: "2 a to the power t open parenthesis cos b t , sin b t close parenthesis")[$2 a^(t) ( cos b t , #h(0.278em) sin b t )$] — the violet spiral in the figure, with the iteration's start marked at #math.equation(block: false, alt: "open parenthesis 2 , 0 , 0 close parenthesis")[$( 2 , 0 , 0 )$]. {"camera":{"fov":50,"position":\[2.5,-3.5,5\],"projection":"perspective","target":\[0,0,0\]},"grid":{"axisColors":{"x":"\#ef4444","y":"\#22c55e","z":"\#3b82f6"},"divisions":10,"gridColor":"\#e5e7eb","showAxes":true,"showLabels":true,"size":10,"visible":true},"id":"511e4cdf-bdbd-419a-8c72-49da67b9033f","metadata":{"alt\_text":"A smooth violet spiral in the horizontal plane, starting at a marked point and winding around the origin. A slider named a sets whether the spiral tightens inward (a below 1), stays a circle (a equal to 1), or unwinds outward (a above 1), while a slider named b sets how fast it wraps around.","created\_at":"2026-08-01T00:00:00.000Z","description":"Book scene: the trajectory 2 a^t (cos bt, sin bt, 0) for t in \[0, 40\] \\u2014 the continuous path traced by a 2-by-2 matrix with complex eigenvalues of modulus a and argument b. Sliders a in \[0.9, 1.04\] and b in \[0.2, 1.2\]; defaults spiral gently inward.","tags":\["book","linear-algebra","complex-eigenvalues","spiral"\],"updated\_at":"2026-08-01T00:00:00.000Z"},"objects":\[{"id":"28cd3efd-ce11-4814-8b2b-8412b2ea90cf","kind":"parameter","label":{"text":"a (growth factor per unit time)","visible":true},"max":1.04,"min":0.9,"name":"a","step":0.005,"value":0.96,"visible":true},{"id":"2d57a162-0fdb-40b7-8365-9e18c0e7a4b0","kind":"parameter","label":{"text":"b (rotation rate, radians per unit time)","visible":true},"max":1.2,"min":0.2,"name":"b","step":0.05,"value":0.6,"visible":true},{"id":"b6f6c981-526e-433c-b62a-728bbd81f96a","kind":"parametric-curve","label":{"text":"trajectory: 2 a^t (cos bt, sin bt)","visible":true},"samples":1200,"style":{"color":"\#8b5cf6","dash":\[\],"lineWidth":3},"tDomain":\[0,40\],"visible":true,"xExpr":"2\*pow(a, t)\*cos(b\*t)","yExpr":"2\*pow(a, t)\*sin(b\*t)","zExpr":"0"},{"color":"\#111827","id":"79cc4f22-87eb-45ba-a564-cae5a6aa543f","kind":"point","label":{"text":"start: (2, 0, 0)","visible":true},"radius":0.09,"visible":true,"x":2,"y":0,"z":0}\],"title":"Complex eigenvalues spiral","version":1} The trajectory #math.equation(block: false, alt: "2 a to the power t open parenthesis cos b t , sin b t close parenthesis")[$2 a^(t) ( cos b t , #h(0.278em) sin b t )$] for #math.equation(block: false, alt: "t")[$t$] from #math.equation(block: false, alt: "0")[$0$] to #math.equation(block: false, alt: "40")[$40$], starting at the marked point #math.equation(block: false, alt: "open parenthesis 2 , 0 , 0 close parenthesis")[$( 2 , 0 , 0 )$]. The slider #math.equation(block: false, alt: "a")[$a$] is the growth factor per unit time and #math.equation(block: false, alt: "b")[$b$] is the rotation rate in radians per unit time; the defaults #math.equation(block: false, alt: "a equals 0.96")[$a = 0.96$], #math.equation(block: false, alt: "b equals 0.6")[$b = 0.6$] spiral gently inward. === Explore the figure + At the defaults, follow the curve from the marked start point. With #math.equation(block: false, alt: "b equals 0.6")[$b = 0.6$] it wraps around the origin about #math.equation(block: false, alt: "3.8")[$3.8$] times over the run, and with #math.equation(block: false, alt: "a equals 0.96")[$a = 0.96$] each unit of time shaves four percent off the radius, ending near radius #math.equation(block: false, alt: "0.4")[$0.4$]. Rotation and decay, superimposed. + Set #math.equation(block: false, alt: "a equals 1")[$a = 1$]. The spiral closes into a perfect circle of radius #math.equation(block: false, alt: "2")[$2$]: pure rotation, nothing gained or lost. This is the knife-edge between decay and growth. + Push #math.equation(block: false, alt: "a")[$a$] to #math.equation(block: false, alt: "1.04")[$1.04$]. The same curve now unwinds outward, finishing near radius #math.equation(block: false, alt: "9.6")[$9.6$]. A four-percent difference per step, compounded forty times, is the whole difference between collapse and explosion. + Return #math.equation(block: false, alt: "a")[$a$] to #math.equation(block: false, alt: "0.96")[$0.96$] and sweep #math.equation(block: false, alt: "b")[$b$] across its range. At #math.equation(block: false, alt: "b equals 0.2")[$b = 0.2$] the path barely completes one lap; at #math.equation(block: false, alt: "b equals 1.2")[$b = 1.2$] it wraps nearly eight times. Notice what #math.equation(block: false, alt: "b")[$b$] never changes: the radius at each time depends on #math.equation(block: false, alt: "a")[$a$] alone. === Eigenvalues without eigenvectors The eigenvalue machinery does not break here — it reports complex numbers. The characteristic polynomial of the rotation–scaling matrix is #math.equation(block: true, alt: "λ squared minus 2 a cos b λ plus a squared equals 0")[$λ^(2) − 2 a cos b λ + a^(2) = 0$] and its discriminant is #math.equation(block: false, alt: "4 a squared cos squared b minus 4 a squared equals minus 4 a squared sin squared b")[$4 a^(2) cos^(2) b − 4 a^(2) = − 4 a^(2) sin^(2) b$], which is negative whenever #math.equation(block: false, alt: "sin b not equal to 0")[$sin b ≠ 0$]: no real roots, confirming what the pictures showed. The roots are the complex pair #math.equation(block: false, alt: "λ equals a cos b ± i a sin b")[$λ = a cos b ± i a sin b$], better read in polar form as #math.equation(block: false, alt: "λ equals a e to the power ± i b")[$λ = a e^(± i b)$]. The two sliders of the figure are literally the two coordinates of the eigenvalue: #math.equation(block: false, alt: "a")[$a$] is its #strong[modulus] and #math.equation(block: false, alt: "b")[$b$] is its #strong[argument]. A complex eigenvalue does not mark an invariant line; it prescribes a motion — turn by the argument, scale by the modulus, once per application — and the spiral is that prescription traced out in time. The trichotomy you explored is the modulus test: #math.equation(block: false, alt: "| λ | less than 1")[$| λ | < 1$] spirals in, #math.equation(block: false, alt: "| λ | equals 1")[$| λ | = 1$] circles, #math.equation(block: false, alt: "| λ | greater than 1")[$| λ | > 1$] spirals out. #examplebox("Example 1")[Verify the eigenvalue pair and its modulus][ Solve the characteristic equation above and confirm that both roots have modulus exactly #math.equation(block: false, alt: "a")[$a$]. By the quadratic formula, #math.equation(block: false, alt: "λ equals open parenthesis 2 a cos b ± the square root of minus 4 a squared sin squared b close parenthesis / 2 equals a cos b ± i a sin b")[$λ = ( 2 a cos b ± sqrt(− 4 a^(2) sin^(2) b) ) / 2 = a cos b ± i a sin b$]. The modulus is #math.equation(block: false, alt: "the square root of open parenthesis a cos b close parenthesis squared plus open parenthesis a sin b close parenthesis squared equals a the square root of cos squared b plus sin squared b equals a")[$sqrt(( a cos b )^(2) + ( a sin b )^(2)) = a sqrt(cos^(2) b + sin^(2) b) = a$]. At the figure's defaults, #math.equation(block: false, alt: "λ equals 0.96 e to the power ± 0.6 i")[$λ = 0.96 e^(± 0.6 i)$]: modulus #math.equation(block: false, alt: "0.96 less than 1")[$0.96 < 1$], so iterates decay — after #math.equation(block: false, alt: "40")[$40$] steps the radius is #math.equation(block: false, alt: "2 times 0.96 to the power 40 approximately equals 0.39")[$2 · 0.96^(40) ≈ 0.39$], matching the spiral's inner end — while the argument #math.equation(block: false, alt: "0.6")[$0.6$] delivers #math.equation(block: false, alt: "0.6")[$0.6$] radians of turning per step, about #math.equation(block: false, alt: "3.8")[$3.8$] full laps in #math.equation(block: false, alt: "40")[$40$] steps. ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ When the eigenvalues go complex, the matrix trades a private axis for a private #emph[dance]: modulus sets growth or decay, argument sets the turning. This completes the census of what a #math.equation(block: false, alt: "2 times 2")[$2 × 2$] matrix can do in the long run — stretch along real eigenlines, or spiral by a complex pair — and it is the engine behind every oscillation in discrete dynamics, from population cycles to vibrating structures. ]