#set document(title: "3.5 Two dimensional systems and their vector fields", author: "Jiří Lebl") #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.5#h(0.6em)Two dimensional systems and their vector fields Let us take a moment to talk about constant coefficient linear homogeneous systems in the plane. Much intuition can be obtained by studying this simple case. Suppose we use coordinates #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] for the plane as usual, and suppose #math.equation(block: false, alt: "a b; c d")[$a b \ c d$] is a #math.equation(block: false, alt: "2 times 2")[$2 × 2$] matrix . Consider the system #math.equation(block: true, alt: "[ to the power x; y equals P [ x; y ] or [ to the power x; y equals [ a, b; c, d ] [ x; y ] .")[$\[^(x \ y) = P \[ x \ y \] #h(2em) "or" #h(2em) \[^(x \ y) = \[ a & b \ c & d \] \[ x \ y \] .$] The system is #emph[autonomous] (compare this section to #link("https://math.libretexts.org/Bookshelves/Differential_Equations/Differential_Equations_for_Engineers_(Lebl)/1%3A_First_order_ODEs/1.6%3A_Autonomous_equations")[Section 1.6]) and so we can draw a #strong[vector field] (see end of #link("https://math.libretexts.org/Bookshelves/Differential_Equations/Differential_Equations_for_Engineers_(Lebl)/3%3A_Systems_of_ODEs/3.1%3A_Introduction_to_Systems_of_ODEs")[Section 3.1]). We will be able to visually tell what the vector field looks like and how the solutions behave, once we find the eigenvalues and eigenvectors of the matrix #math.equation(block: false, alt: "P")[$P$]. For this section, we assume that #math.equation(block: false, alt: "P")[$P$] has two eigenvalues and two corresponding eigenvectors. Lebl's summary table lists six behaviors; this one family produces all six. For x′ = Ax with A = \[\[a, 1\], \[c, a\]\] the eigenvalues are exactly λ = a ± √c, so the two sliders are the two things that decide the picture: a shifts both eigenvalues (stability), and the sign of c decides complex versus real. It opens on Lebl's own spiral source \[\[1, 1\], \[−4, 1\]\], λ = 1 ± 2i. Drag c up from −4 and the spiral uncoils into an unstable node as the discriminant passes zero — at c = 0 exactly you get the defective \[\[a, 1\], \[0, a\]\], the shape of §3.7's \[\[3, 1\], \[0, 3\]\]. At c = a² one eigenvalue is 0, the singular case this section's last paragraph sets aside; past it the two real eigenvalues have opposite signs and the node becomes a saddle. Then put c back to −4 and drag a down through 0: spiral source → Lebl's own center \[\[0, 1\], \[−4, 0\]\], λ = ±2i → spiral sink, λ = −1 ± 2i. {"functions":\[{"color":"\#1f4e79","domain":null,"expression":"","expression2":"","id":"pp-family","inequality":"lt","lineDash":\[\],"lineWidth":2,"matrix":\["a","1","c","a"\],"mode":"phase-plane","seeds":\[{"x":2,"y":0.6},{"x":0.5,"y":1.95},{"x":-1.5,"y":1.35},{"x":-2,"y":-0.6},{"x":-0.5,"y":-1.95},{"x":1.5,"y":-1.35}\],"tMax":10,"tMin":-10,"variable":"x","visible":true}\],"grid":{"axisColor":"\#333333","gridColor":"\#cccccc","majorSpacing":1,"minorGridColor":"\#eeeeee","showAxes":true,"showLabels":true},"parameters":\[{"id":"lebl-3-5-a","label":"Diagonal entry a \\u2014 shifts both eigenvalues (stability)","max":2,"min":-2,"name":"a","step":0.1,"value":1},{"id":"lebl-3-5-c","label":"Lower-left entry c \\u2014 sign of the discriminant (spiral vs node)","max":4,"min":-4,"name":"c","step":0.1,"value":-4}\],"title":"Two-dimensional systems: all six pictures, one matrix","version":1,"viewport":{"centerX":0,"centerY":0,"scale":60}} === 1 Suppose that the eigenvalues of #math.equation(block: false, alt: "P")[$P$] are real and positive. We find two corresponding eigenvectors and plot them in the plane. For example, take the matrix #math.equation(block: false, alt: "[ 1, 1; 0, 2 ]")[$[ 1 & 1 \ 0 & 2 ]$]. The eigenvalues are 1 and 2 and corresponding eigenvectors are #math.equation(block: false, alt: "[ 1; 0 ]")[$[ 1 \ 0 ]$] and #math.equation(block: false, alt: "[ 1; 1 ]")[$[ 1 \ 1 ]$]. See Figure #math.equation(block: false, alt: "1")[$1$]. #figure(figph[Plot on a grid from -3 to 3 showing only two red eigenvector segments from the origin: one along the 45-degree diagonal to (1, 1), one along the horizontal axis to (1, 0).], alt: "Plot on a grid from -3 to 3 showing only two red eigenvector segments from the origin: one along the 45-degree diagonal to (1, 1), one along the horizontal axis to (1, 0).", caption: [Figure #math.equation(block: false, alt: "1")[$1$]: Eigenvectors of #math.equation(block: false, alt: "P")[$P$].]) Now suppose that #math.equation(block: false, alt: "x")[$x$] and #math.equation(block: false, alt: "y")[$y$] are on the line determined by an eigenvector #math.equation(block: false, alt: "v →")[$arrow(v)$] for an eigenvalue #math.equation(block: false, alt: "λ")[$λ$]. That is, #math.equation(block: false, alt: "[ x; y ] equals a v →")[$[ x \ y ] = a arrow(v)$] for some scalar #math.equation(block: false, alt: "a")[$a$]. Then #math.equation(block: true, alt: "[ to the power x; y equals P [ x; y ] equals P open parenthesis a v → close parenthesis equals a open parenthesis P v → close parenthesis equals a λ v →")[$\[^(x \ y) = P \[ x \ y \] = P \( a arrow(v) \) = a \( P arrow(v) \) = a λ arrow(v)$] The derivative is a multiple of #math.equation(block: false, alt: "v →")[$arrow(v)$] and hence points along the line determined by #math.equation(block: false, alt: "v →")[$arrow(v)$]. As #math.equation(block: false, alt: "λ greater than 0")[$λ > 0$], the derivative points in the direction of #math.equation(block: false, alt: "v e c v")[$v e c v$] when #math.equation(block: false, alt: "α")[$α$] is positive and in the opposite direction when #math.equation(block: false, alt: "α")[$α$] is negative. Let us draw the lines determined by the eigenvectors, and let us draw arrows on the lines to indicate the directions. See Figure #math.equation(block: false, alt: "2")[$2$]. We fill in the rest of the arrows for the vector field and we also draw a few solutions. See Figure #math.equation(block: false, alt: "3")[$3$]. Notice that the picture looks like a source with arrows coming out from the origin. Hence we call this type of picture a source or sometimes an #emph[unstable node]. #figure(figph[Plot on a grid from -3 to 3 with the eigenvector lines through the origin drawn in black, the diagonal y equals x and the horizontal axis, and red arrows to (1, 1) and (1, 0) marking direction.], alt: "Plot on a grid from -3 to 3 with the eigenvector lines through the origin drawn in black, the diagonal y equals x and the horizontal axis, and red arrows to (1, 1) and (1, 0) marking direction.", caption: [Figure #math.equation(block: false, alt: "2")[$2$]: Eigenvectors of #math.equation(block: false, alt: "P")[$P$] with directions.]) #figure(figph[Vector field of blue arrows on a square from -3 to 3, all pointing away from the origin, with red trajectories running outward along the horizontal axis and the diagonal y equals x: a source.], alt: "Vector field of blue arrows on a square from -3 to 3, all pointing away from the origin, with red trajectories running outward along the horizontal axis and the diagonal y equals x: a source.", caption: [Figure #math.equation(block: false, alt: "3")[$3$]: Example source vector field with eigenvectors and solutions.]) === 2 Suppose both eigenvalues were negative. For example, take the negation of the matrix in case 1, #math.equation(block: false, alt: "[ minus 1, minus 1; 0, minus 2 ]")[$[ − 1 & − 1 \ 0 & − 2 ]$]. The eigenvalues are -1 and -2 and corresponding eigenvectors are the same, #math.equation(block: false, alt: "[ 1; 0 ]")[$[ 1 \ 0 ]$] and #math.equation(block: false, alt: "[ 1; 1 ]")[$[ 1 \ 1 ]$]. The calculation and the picture are almost the same. The only difference is that the eigenvalues are negative and hence all arrows are reversed. We get the picture in Figure #math.equation(block: false, alt: "4")[$4$]. We call this kind of picture a #emph[sink]or sometimes a#emph[stable node]. #figure(figph[Vector field of blue arrows on a square from -3 to 3, all pointing toward the origin, with red trajectories flattening onto the horizontal axis and sliding in without circling: a sink.], alt: "Vector field of blue arrows on a square from -3 to 3, all pointing toward the origin, with red trajectories flattening onto the horizontal axis and sliding in without circling: a sink.", caption: [Figure #math.equation(block: false, alt: "4")[$4$]: Example sink vector field with eigenvectors and solutions.]) === 3 Suppose one eigenvalue is positive and one is negative. For example the matrix #math.equation(block: false, alt: "1 1; 0 minus 2")[$1 1 \ 0 − 2$]. The eigenvalues are #math.equation(block: false, alt: "1")[$1$] and #math.equation(block: false, alt: "− 2")[$− 2$] and corresponding eigenvectors are #math.equation(block: false, alt: "1; 0")[$1 \ 0$] and #math.equation(block: false, alt: "1; minus 3")[$1 \ − 3$]. We reverse the arrows on one line (corresponding to the negative eigenvalue) and we obtain the picture in Figure #math.equation(block: false, alt: "5")[$5$]. We call this picture a saddle point. #figure(figph[Phase portrait of a saddle on axes from -3 to 3: red trajectories in a blue vector field sweep in along a steep eigenvector line of slope about -3, then out along the horizontal axis.], alt: "Phase portrait of a saddle on axes from -3 to 3: red trajectories in a blue vector field sweep in along a steep eigenvector line of slope about -3, then out along the horizontal axis.", caption: [Figure #math.equation(block: false, alt: "5")[$5$]: Example saddle vector field with eigenvectors and solutions.]) For the next three cases we will assume the eigenvalues are complex. In this case the eigenvectors are also complex and we cannot just plot them in the plane. === 4 Suppose the eigenvalues are purely imaginary. That is, suppose the eigenvalues are #math.equation(block: false, alt: "± i b")[$± i b$]. For example, let #math.equation(block: false, alt: "P equals [ 0, 1; minus 4, 0 ]")[$P = [ 0 & 1 \ − 4 & 0 ]$]. The eigenvalues turn out to be #math.equation(block: false, alt: "± 2 i")[$± 2 i$] and eigenvectors are #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$] and #math.equation(block: false, alt: "[ 1; minus 2 i ]")[$[ 1 \ − 2 i ]$]. Consider the eigenvalue #math.equation(block: false, alt: "2 i")[$2 i$] and its eigenvector #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$]. The real and imaginary parts of #math.equation(block: false, alt: "v → e to the power i 2 t")[$arrow(v) e^(i 2 t)$] are #math.equation(block: true, alt: "R e [ 1; 2 i ] e to the power i 2 t equals [ c o s open parenthesis 2 t close parenthesis; minus 2 s i n open parenthesis 2 t close parenthesis ] , I m [ 1; 2 i ] e to the power i 2 t equals [ s i n open parenthesis 2 t close parenthesis; 2 c o s open parenthesis 2 t close parenthesis ]")[$R e [ 1 \ 2 i ] e^(i 2 t) = [ c o s ( 2 t ) \ − 2 s i n ( 2 t ) ] , #h(1em) I m [ 1 \ 2 i ] e^(i 2 t) = [ s i n ( 2 t ) \ 2 c o s ( 2 t ) ]$] We can take any linear combination of them to get other solutions, which one we take depends on the initial conditions. Now note that the real part is a parametric equation for an ellipse. Same with the imaginary part and in fact any linear combination of the two. This is what happens in general when the eigenvalues are purely imaginary. So when the eigenvalues are purely imaginary, we get #emph[ellipses]for the solutions. This type of picture is sometimes called a #emph[center]. See Figure #math.equation(block: false, alt: "6")[$6$]. #figure(figph[Center vector field on axes from -3 to 3: blue arrows circulate clockwise and five nested red loops, taller than wide, close on themselves around the origin.], alt: "Center vector field on axes from -3 to 3: blue arrows circulate clockwise and five nested red loops, taller than wide, close on themselves around the origin.", caption: [Figure #math.equation(block: false, alt: "6")[$6$]: Example center vector field.]) === 5 Now suppose the complex eigenvalues have a positive real part. That is, suppose the eigenvalues are #math.equation(block: false, alt: "a ± i b")[$a ± i b$] for some #math.equation(block: false, alt: "a greater than 0")[$a > 0$]. For example, let #math.equation(block: false, alt: "P equals [ 1, 1; minus 4, 1 ]")[$P = [ 1 & 1 \ − 4 & 1 ]$]. The eigenvalues turn out to be #math.equation(block: false, alt: "1 ± 2 i")[$1 ± 2 i$] and eigenvectors are #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$] and #math.equation(block: false, alt: "[ 1; minus 2 i ]")[$[ 1 \ − 2 i ]$]. We take #math.equation(block: false, alt: "1 ± 2 i")[$1 ± 2 i$] and its eigenvector #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$] and find the real and imaginary of #math.equation(block: false, alt: "v → e to the power open parenthesis 1 plus 2 i close parenthesis t")[$arrow(v) e^(( 1 + 2 i ) t)$] are #math.equation(block: true, alt: "R e [ 1; 2 i ] e to the power open parenthesis 1 plus 2 i close parenthesis t equals e to the power t [ c o s open parenthesis 2 t close parenthesis; minus 2 s i n open parenthesis 2 t close parenthesis ] I m [ 1; 2 i ] e to the power open parenthesis 1 plus 2 i close parenthesis t equals e to the power t [ s i n open parenthesis 2 t close parenthesis; 2 c o s open parenthesis 2 t close parenthesis ]")[$R e [ 1 \ 2 i ] e^(( 1 + 2 i ) t) = e^(t) [ c o s ( 2 t ) \ − 2 s i n ( 2 t ) ] #h(1em) I m [ 1 \ 2 i ] e^(( 1 + 2 i ) t) = e^(t) [ s i n ( 2 t ) \ 2 c o s ( 2 t ) ]$] Note the #math.equation(block: false, alt: "e to the power t")[$e^(t)$] in front of the solutions. This means that the solutions grow in magnitude while spinning around the origin. Hence we get a #emph[spiral source]. See Figure #math.equation(block: false, alt: "7")[$7$]. #figure(figph[Spiral source vector field on axes from -3 to 3: red curves spiral clockwise outward from the origin, growing steadily, with blue arrows leaning outward everywhere.], alt: "Spiral source vector field on axes from -3 to 3: red curves spiral clockwise outward from the origin, growing steadily, with blue arrows leaning outward everywhere.", caption: [Figure #math.equation(block: false, alt: "7")[$7$]: Example spiral source vector field.]) === 6 Finally suppose the complex eigenvalues have a negative real part. That is, suppose the eigenvalues are #math.equation(block: false, alt: "minus a ± i b")[$− a ± i b$] for some #math.equation(block: false, alt: "a greater than 0")[$a > 0$]. For example, let #math.equation(block: false, alt: "P equals [ minus 1, minus 1; 4, minus 1 ]")[$P = [ − 1 & − 1 \ 4 & − 1 ]$]. The eigenvalues turn out to be #math.equation(block: false, alt: "minus 1 ± 2 i")[$− 1 ± 2 i$] and eigenvectors are #math.equation(block: false, alt: "[ 1; minus 2 i ]")[$[ 1 \ − 2 i ]$] and #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$]. We take #math.equation(block: false, alt: "minus 1 minus 2 i")[$− 1 − 2 i$] and its eigenvector #math.equation(block: false, alt: "[ 1; 2 i ]")[$[ 1 \ 2 i ]$] and find the real and imaginary of #math.equation(block: false, alt: "v → e to the power open parenthesis minus 1 minus 2 i close parenthesis t")[$arrow(v) e^(( − 1 − 2 i ) t)$] are #math.equation(block: true, alt: "R e [ 1; 2 i ] e to the power open parenthesis minus 1 minus 2 i close parenthesis t equals e to the power minus t [ c o s open parenthesis 2 t close parenthesis; 2 s i n open parenthesis 2 t close parenthesis ] I m [ 1; 2 i ] e to the power open parenthesis minus 1 minus 2 i close parenthesis t equals e to the power minus t [ minus s i n open parenthesis 2 t close parenthesis; 2 c o s open parenthesis 2 t close parenthesis ]")[$R e [ 1 \ 2 i ] e^(( − 1 − 2 i ) t) = e^(− t) [ c o s ( 2 t ) \ 2 s i n ( 2 t ) ] #h(1em) I m [ 1 \ 2 i ] e^(( − 1 − 2 i ) t) = e^(− t) [ − s i n ( 2 t ) \ 2 c o s ( 2 t ) ]$] Note the #math.equation(block: false, alt: "e to the power minus t")[$e^(− t)$] in front of the solutions. This means that the solutions shrink in magnitude while spinning around the origin. Hence we get a spiral sink. See Figure #math.equation(block: false, alt: "8")[$8$]. #figure(figph[Spiral sink vector field on axes from -3 to 3: red trajectories wind counterclockwise inward from the edges, tightening onto the origin as the blue arrows tilt inward.], alt: "Spiral sink vector field on axes from -3 to 3: red trajectories wind counterclockwise inward from the edges, tightening onto the origin as the blue arrows tilt inward.", caption: [Figure #math.equation(block: false, alt: "8")[$8$]: Example spiral sink vector field.]) We summarize the behavior of linear homogeneous two dimensional systems given by a nonsingular matrix in Table #math.equation(block: false, alt: "1")[$1$]. Systems where one of the eigenvalues is zero (the matrix is singular) come up in practice from time to time, see Example 3.1.2, and the pictures are somewhat different (simpler in a way). See the exercises. #figure(table( columns: 2, align: left, inset: 6pt, table.header([#strong[Eigenvalues]], [#strong[Behavior]]), [real and both positive], [source / unstable node], [real and both negative], [sink / stable node], [real and opposite signs], [saddle], [purely imaginary], [center point / ellipses], [complex with positive real part], [spiral source], [complex with negative real part], [spiral sink], ))