45 min read

> Learning paths. Math majors — read everything, especially the conjugate-pair theorem and its proof, the real canonical form derivation, and the Math-Major Sidebar on diagonalizing over $\mathbb{C}$. CS / Data Science — focus on the Geometric...

Prerequisites

  • chapter-25-diagonalization

Learning Objectives

  • Explain geometrically why a pure rotation has no real eigenvectors, and why this forces its characteristic polynomial to have complex roots.
  • State and use the fact that a real matrix has eigenvalues in complex-conjugate pairs, and that its complex eigenvectors come in conjugate pairs too.
  • Interpret a complex eigenvalue $re^{i\theta}$ as rotation by $\theta$ and scaling by $r$ inside an invariant 2D plane.
  • Build the real canonical (block) form $\begin{bmatrix} a & -b \\ b & a\end{bmatrix}$ from a complex eigenpair and verify $A = PCP^{-1}$.
  • Use $|\lambda| = r$ to predict spiral-in ($r<1$), spiral-out ($r>1$), or pure orbit ($r=1$) dynamics, teeing up stability.
  • Connect complex eigenvalues to unitary matrices and complex inner products, and verify all results against $\texttt{np.linalg.eig}$.

Complex Eigenvalues: Rotations in Disguise

Learning paths. Math majors — read everything, especially the conjugate-pair theorem and its proof, the real canonical form derivation, and the Math-Major Sidebar on diagonalizing over $\mathbb{C}$. CS / Data Science — focus on the Geometric Intuition, the spiral-dynamics picture, the numpy, and the np.linalg.eig outputs; the proofs build the intuition you will reuse. Physics / Engineering — focus on the rotation-plus-scaling interpretation, the modulus $|\lambda|$ as a growth rate, and the oscillation/AC-circuit application that previews stability in Chapter 37.

Take the rotation matrix from Chapter 21 — turn the plane by $30°$ — and ask the question this entire part of the book is built around: which vectors does it leave on their own line? In Chapter 23 we learned that those are the eigenvectors, the invariant directions a transformation only stretches and never turns. In Chapter 25 we learned that when a matrix has enough of them, it diagonalizes, and taking powers becomes trivial. So point the visualizer at a rotation and look for the arrows that hold their line.

You will look for a long time. A rotation turns every arrow. Spin the whole plane by $30°$ and there is not a single nonzero direction that stays put — that is the entire point of a rotation. So a rotation has no real eigenvectors at all, and yet every $2\times 2$ matrix has a characteristic polynomial with two roots. Where did the eigenvalues go? They went somewhere we have been carefully avoiding since Chapter 24: into the complex numbers. This chapter is about what those complex eigenvalues mean — and the answer, the secret this whole chapter exists to reveal, is beautiful. A real matrix with complex eigenvalues is rotating, and the complex eigenvalue $re^{i\theta}$ is a compact report of two facts at once: it rotates by the angle $\theta$, and it scales by the factor $r$. Complex eigenvalues are rotations in disguise.

That phrase — complex eigenvalues meaning rotation — is the threshold idea of the chapter. Once you see it, complex eigenvalues stop being an algebraic accident you tolerate and become a geometric signal you read. A spiral galaxy, an oscillating circuit, a boom-and-bust population cycle, a damped vibration ringing down to silence: every one of them has a matrix behind it, and every one of those matrices has complex eigenvalues whose two pieces, the angle and the modulus, tell you exactly how fast the system spins and whether it grows, decays, or orbits forever. We will earn that reading carefully, prove the structural facts that make it reliable, and verify every number against np.linalg.eig.

26.1 Why does a rotation have no real eigenvectors?

Before any algebra, let us settle the geometry, because the geometry is the whole motivation. We will use the recurring visualizer from Chapter 1 — unchanged, as always — and point it at a rotation.

# toolkit/visualizer.py — the recurring 2D transformation visualizer.
# Shows what a 2x2 matrix A does to the unit square and the basis vectors.
import numpy as np
import matplotlib.pyplot as plt

def visualize_2d(A, title="", ax=None):
    """Plot the action of 2x2 matrix A on the unit square and i-hat, j-hat."""
    A = np.asarray(A, dtype=float)
    square = np.array([[0, 1, 1, 0, 0],
                       [0, 0, 1, 1, 0]])          # unit-square corners (closed)
    out = A @ square                               # transformed square
    e1, e2 = A @ np.array([1, 0]), A @ np.array([0, 1])   # images of basis vectors
    if ax is None:
        _, ax = plt.subplots(figsize=(5, 5))
    ax.plot(square[0], square[1], "b--", lw=1, label="input (unit square)")
    ax.fill(out[0], out[1], alpha=0.25, color="C1")
    ax.plot(out[0], out[1], "C1-", lw=2, label="A . (unit square)")
    ax.arrow(0, 0, *e1, color="C3", width=0.02, length_includes_head=True)  # A e1
    ax.arrow(0, 0, *e2, color="C2", width=0.02, length_includes_head=True)  # A e2
    ax.axhline(0, color="gray", lw=0.5)
    ax.axvline(0, color="gray", lw=0.5)
    ax.set_aspect("equal")
    ax.grid(True, alpha=0.3)
    ax.set_title(title or f"det = {np.linalg.det(A):.2f}")
    ax.legend(loc="best", fontsize=8)
    return ax

# Watch a rotation by 30 degrees: every arrow turns, none stays on its line.
theta = np.deg2rad(30)
R = [[np.cos(theta), -np.sin(theta)],
     [np.sin(theta),  np.cos(theta)]]
visualize_2d(R, title="Rotation by 30°")
plt.show()

Figure 26.1The action of the rotation matrix $R$ for $\theta = 30°$ on the unit square. The dashed blue square is the input; the solid orange square is its image, rotated a sixth of a right angle counterclockwise. The two arrows are the images of $\mathbf{e}_1$ and $\mathbf{e}_2$. Alt-text: the unit square and both basis arrows have swung to a new angle, and crucially no arrow lies along the same line it started on — the input square and output square share only the origin.

Stare at the figure and try to find an eigenvector. An eigenvector is an arrow whose image lies on the same line through the origin — pointing the same way (positive eigenvalue) or exactly opposite (negative eigenvalue). The image arrow $A\mathbf{e}_1$ has swung $30°$ off $\mathbf{e}_1$; the image $A\mathbf{e}_2$ has swung $30°$ off $\mathbf{e}_2$; and the same is true of every arrow you could draw, because that is what "rotate the plane by $30°$" means — it adds $30°$ to the angle of everything. No nonzero real vector survives on its line. There is no real eigenvector, and therefore no real eigenvalue.

Geometric Intuition — An eigenvector is a direction the transformation does not turn. A rotation, by its very definition, turns every direction by the same angle. So a genuine rotation (any angle that is not a multiple of $180°$) has no invariant lines at all in the real plane — and that geometric fact is exactly why its eigenvalues cannot be real. The missing real eigenvectors are not a defect of the matrix; they are the fingerprint of spinning.

This is the cleanest possible illustration of a principle we have been building toward since Chapter 23: the eigen-structure of a matrix reflects what the matrix does to space. A scaling has two real eigenvectors (the axes it stretches along). A shear has one real eigenvector (the direction it leaves fixed) and a repeated eigenvalue. A reflection has two — the mirror line and its perpendicular. And a rotation has none, because spinning leaves no direction behind. The real eigenvectors run out precisely when the transformation has a rotational character, and that is the gap the complex numbers were invented to fill.

26.1.1 The algebra confirms the geometry

Let us watch the characteristic polynomial deliver the same verdict. From Chapter 24, the eigenvalues of $A$ are the roots of $\det(A - \lambda I) = 0$. For the rotation $$R = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix},$$ we compute $$\det(R - \lambda I) = \det\begin{bmatrix} \cos\theta - \lambda & -\sin\theta \\ \sin\theta & \cos\theta - \lambda \end{bmatrix} = (\cos\theta - \lambda)^2 + \sin^2\theta.$$ Expanding, and using $\cos^2\theta + \sin^2\theta = 1$ (the Pythagorean identity that has done so much work in this book), the characteristic polynomial is $$\lambda^2 - 2\cos\theta\,\lambda + 1 = 0.$$ The discriminant is $(2\cos\theta)^2 - 4 = 4(\cos^2\theta - 1) = -4\sin^2\theta$. For any $\theta$ that is not a multiple of $180°$, $\sin\theta \ne 0$, so the discriminant is negative and the roots are complex. Solving the quadratic, $$\lambda = \cos\theta \pm \sqrt{\cos^2\theta - 1} = \cos\theta \pm i\sin\theta = e^{\pm i\theta},$$ using Euler's formula $e^{i\theta} = \cos\theta + i\sin\theta$ in the last step. The eigenvalues of a rotation by $\theta$ are exactly $e^{i\theta}$ and $e^{-i\theta}$ — unit-modulus complex numbers whose argument is the rotation angle itself. The geometry said "no real direction is preserved"; the algebra answered "because the eigenvalues are $e^{\pm i\theta}$, which are real only when $\theta$ is a multiple of $180°$." Two views, one object — the book's recurring refrain.

The Key Insight — The eigenvalues of the rotation-by-$\theta$ matrix are $e^{\pm i\theta} = \cos\theta \pm i\sin\theta$. The argument of the eigenvalue is the angle of rotation, and its modulus is $1$ because a pure rotation neither grows nor shrinks anything. A complex eigenvalue is not abstract bookkeeping — its two parts are the spin angle and the scale factor of the transformation.

Notice the two roots are complex conjugates of each other: $\overline{e^{i\theta}} = e^{-i\theta}$. That was no coincidence, and the next section explains why it could not have been otherwise.

26.1.2 A field guide: which transformations have real eigenvectors, and which don't?

It is worth pausing to organize what we now know about when real eigenvectors exist, because the rotation is the dramatic exception in a family of more familiar cases. Run the visualizer on each of the following $2\times 2$ matrices and watch for arrows that stay on their line — the real eigenvectors. The pattern is a small theory of its own.

  • Diagonal scaling $\begin{psmallmatrix}3 & 0\\ 0 & 2\end{psmallmatrix}$: two real eigenvectors, the coordinate axes, with eigenvalues $3$ and $2$. The transformation stretches along two perpendicular lines and leaves both as invariant directions. Plenty of real eigenvectors; no rotation.
  • Reflection $\begin{psmallmatrix}1 & 0\\ 0 & -1\end{psmallmatrix}$: two real eigenvectors — the mirror line (eigenvalue $+1$, fixed) and its perpendicular (eigenvalue $-1$, flipped). A reflection wears its invariant directions on its sleeve, as Chapter 21 noted.
  • Shear $\begin{psmallmatrix}1 & 1\\ 0 & 1\end{psmallmatrix}$: only one real eigenvector direction (the horizontal axis it leaves fixed), with a repeated eigenvalue $1$. This is the "defective" borderline case of Chapter 25 — a single eigen-direction where the algebra wanted two.
  • Rotation $\begin{psmallmatrix}\cos\theta & -\sin\theta\\ \sin\theta & \cos\theta\end{psmallmatrix}$ (with $\theta$ not a multiple of $180°$): no real eigenvectors. Every arrow turns. The eigenvalues flee into the complex plane as $e^{\pm i\theta}$.

The discriminant of the characteristic polynomial is the dividing line. When it is positive, you get two distinct real eigenvalues and two real eigen-directions (the scaling and reflection). When it is zero, the two real eigenvalues coincide and you may lose a direction (the shear). When it is negative, the real eigenvectors vanish entirely and the matrix is rotating (complex eigenvalues). So the appearance of complex eigenvalues is precisely the signal "this transformation has a rotational component that no real direction can escape." That is the geometric meaning we will spend the rest of the chapter quantifying.

Real-World ApplicationProcedural animation and physics engines. A game or animation studio that wants an object to spin applies a rotation matrix every frame; the engine never needs the eigenvectors, but a tools programmer debugging a transform can diagnose its character instantly from its eigenvalues — real eigenvalues mean stretching or shearing (often a bug if a pure rotation was intended), while a complex conjugate pair on the unit circle confirms a clean rotation. The same diagnostic — read the eigenvalues to classify the motion — recurs whenever a matrix is supposed to represent a rigid spin, from camera rigs to skeletal animation.

26.2 What does it mean for a real matrix to have complex eigenvalues?

We have been computing eigenvalues since Chapter 24, always over the real numbers, and quietly stepping around the cases where the discriminant went negative. Now we confront them. The first thing to internalize is that complex eigenvalues are completely normal, not a pathology. A real matrix is a perfectly real object — every entry is a real number — and yet its eigenvalues may be complex, just as the real polynomial $x^2 + 1$ has the complex roots $\pm i$ despite having only real coefficients. The eigenvalues live in $\mathbb{C}$ even when the matrix lives in $\mathbb{R}^{n\times n}$, and that is fine.

When a matrix $A$ has a complex eigenvalue $\lambda = a + bi$ (with $b \ne 0$), there cannot be a real eigenvector for it, because the eigen-equation $A\mathbf{v} = \lambda\mathbf{v}$ would then have a real left side and a genuinely complex right side — impossible unless $\mathbf{v} = \mathbf{0}$, which is not allowed. So the eigenvector must itself be complex: $\mathbf{v} \in \mathbb{C}^n$, a vector whose entries are complex numbers. We say $A$ has no eigenvectors in $\mathbb{R}^n$, but it does have eigenvectors in $\mathbb{C}^n$. The fix for the missing real directions is to enlarge the space from $\mathbb{R}^n$ to $\mathbb{C}^n$ — which is exactly the move that quantum mechanics makes from the start, and which we will formalize when we build complex inner-product spaces in Chapter 34.

Geometric Intuition — You cannot draw a complex eigenvector as a single arrow in the plane, and that is the point: the transformation has no single invariant direction. What it has instead is an invariant plane in which it spins. The complex eigenvector packages the two real directions that span that plane (its real part and its imaginary part) into one object, and the complex eigenvalue packages the spin angle and the scale factor of the motion inside that plane. The complex numbers are how we carry a rotation around in the same algebraic luggage we used for a stretch.

26.2.1 The complex-conjugate-pair theorem

The two eigenvalues of our rotation came out as a conjugate pair, $e^{i\theta}$ and $e^{-i\theta}$. This is a completely general law for real matrices, and it is worth stating and proving carefully, because it governs everything that follows.

Theorem (complex eigenvalues come in conjugate pairs). Let $A$ be a real matrix (every entry real). If $\lambda = a + bi$ is an eigenvalue of $A$ with eigenvector $\mathbf{v}$, then its complex conjugate $\bar\lambda = a - bi$ is also an eigenvalue of $A$, with eigenvector $\bar{\mathbf{v}}$ (the entry-wise conjugate of $\mathbf{v}$).

1. Why we care. This is what makes complex eigenvalues manageable. They never appear alone — they arrive in matched pairs $a \pm bi$ — so a real $2\times 2$ matrix with complex eigenvalues has eigenvalues that are mirror images across the real axis, a real $4\times 4$ matrix can have at most two such pairs, and the imaginary parts always cancel in any real quantity you build, like the trace or the determinant. The conjugate structure is the bookkeeping that keeps the real world real.

2. Key idea. Conjugation is a ring homomorphism on the complex numbers — it respects addition and multiplication, $\overline{z + w} = \bar z + \bar w$ and $\overline{zw} = \bar z\,\bar w$ — and it leaves real numbers untouched. So if you conjugate both sides of the eigen-equation and the matrix is real, the matrix passes through the conjugation unchanged and you get a brand-new eigen-equation for the conjugates.

3. Proof. Start from the eigen-equation $A\mathbf{v} = \lambda\mathbf{v}$. Take the complex conjugate of every entry of both sides: $$\overline{A\mathbf{v}} = \overline{\lambda\mathbf{v}}.$$ On the left, conjugating a matrix-vector product conjugates each entry; since each entry of $A\mathbf{v}$ is a sum of products $\sum_j a_{ij}v_j$, and conjugation distributes over sums and products, $\overline{A\mathbf{v}} = \bar A\,\bar{\mathbf{v}}$. But $A$ is real, so $\bar A = A$, giving $\overline{A\mathbf{v}} = A\bar{\mathbf{v}}$. On the right, $\overline{\lambda\mathbf{v}} = \bar\lambda\,\bar{\mathbf{v}}$. Putting the two sides together: $$A\bar{\mathbf{v}} = \bar\lambda\,\bar{\mathbf{v}}.$$ This says precisely that $\bar\lambda$ is an eigenvalue of $A$ with eigenvector $\bar{\mathbf{v}}$. And because $b \ne 0$, $\bar\lambda = a - bi \ne a + bi = \lambda$, so it is a genuinely different eigenvalue. $\blacksquare$

4. What this means. The eigenvalues of a real matrix are symmetric across the real axis in the complex plane. Real eigenvalues sit on the axis (they are their own conjugates); complex ones come in mirror-image pairs above and below it. This is why a real $3\times 3$ matrix — odd size, three eigenvalues — must have at least one real eigenvalue: complex ones pair up, and three cannot be split into pairs without a leftover. (Geometrically, an odd-dimensional rotation always has a fixed axis; this is the algebra behind that.) And it is why we can extract a real description of the rotation, the canonical block form of §26.4, despite starting with complex data: the imaginary parts always come matched and ready to cancel.

Here is the cancellation made concrete. Chapter 24 taught us that the trace of a matrix is the sum of its eigenvalues and the determinant is their product. For a conjugate pair $\lambda = a + bi$ and $\bar\lambda = a - bi$, those two real quantities come out manifestly real: $$\lambda + \bar\lambda = (a + bi) + (a - bi) = 2a \quad(\text{the imaginary parts cancel}),$$ $$\lambda\bar\lambda = (a + bi)(a - bi) = a^2 + b^2 = |\lambda|^2 = r^2 \quad(\text{a sum of squares, always real and non-negative}).$$ So for a real $2\times 2$ matrix with complex eigenvalues, the trace is $2a$ (twice the common real part) and the determinant is $r^2$ (the squared modulus) — both real, exactly as they must be for a real matrix, even though the eigenvalues that built them are complex. The imaginary parts are guaranteed to annihilate because they arrive equal-and-opposite. This is the conjugate-pair theorem paying rent: it is the structural reason a real matrix can have complex eigenvalues without any complex number ever leaking into a quantity (trace, determinant, characteristic-polynomial coefficient) that the real matrix is obligated to produce as a real number.

Warning

— The conjugate-pair theorem requires the matrix to be real. State this condition and never drop it. A genuinely complex matrix — one with complex entries — has no such symmetry; its eigenvalues can be scattered anywhere in $\mathbb{C}$ with no conjugate partners. The theorem also says nothing about symmetric real matrices specifically: those are even better behaved (their eigenvalues are always real, with no complex ones at all), but that is the Spectral Theorem of Chapter 27, a separate and stronger result. Here we are talking about a general real matrix, where complex eigenvalues are allowed but must come in conjugate pairs.

Check Your Understanding — A real $5\times 5$ matrix has eigenvalues $2 + 3i$, $2 - 3i$, and $-1 + i$. What can you say about its remaining two eigenvalues? Could a real $5\times 5$ matrix have eigenvalues that are all non-real?

Answer Complex eigenvalues of a real matrix come in conjugate pairs, so $-1 + i$ forces $-1 - i$ to also be an eigenvalue. That accounts for four of the five. The fifth eigenvalue must therefore be real — it has no partner to pair with, and a lone complex value would violate the conjugate-pair theorem. So no: a real matrix of odd size can never have all-complex eigenvalues; at least one must be real. (For even sizes it is possible — a $4\times 4$ block-diagonal of two rotations has four complex eigenvalues and no real ones.)

26.2.2 What does a complex eigenvector actually look like? (the rotation, by hand)

The phrase "complex eigenvector" sounds forbidding, so let us compute one explicitly and see that it is concrete and finite — just a vector whose entries happen to be complex numbers. Return to the rotation by $\theta$, with eigenvalue $\lambda = e^{i\theta} = \cos\theta + i\sin\theta$, and solve the eigen-equation $(R - \lambda I)\mathbf{v} = \mathbf{0}$ by hand. The matrix $R - \lambda I$ is $$R - \lambda I = \begin{bmatrix} \cos\theta - (\cos\theta + i\sin\theta) & -\sin\theta \\ \sin\theta & \cos\theta - (\cos\theta + i\sin\theta) \end{bmatrix} = \begin{bmatrix} -i\sin\theta & -\sin\theta \\ \sin\theta & -i\sin\theta \end{bmatrix}.$$ Factor out $\sin\theta$ (nonzero, since the rotation is genuine) and read the top row: $-i\,v_1 - v_2 = 0$, so $v_2 = -i\,v_1$. Choosing $v_1 = 1$ gives the eigenvector $$\mathbf{v} = \begin{bmatrix} 1 \\ -i \end{bmatrix}.$$ That is it — a two-entry vector, the second entry being the imaginary number $-i$. Let us confirm it satisfies the eigen-equation directly for $\theta = 30°$ ($\cos\theta = \tfrac{\sqrt3}{2} \approx 0.866$, $\sin\theta = \tfrac12$): $$R\mathbf{v} = \begin{bmatrix} 0.866 & -0.5 \\ 0.5 & 0.866 \end{bmatrix}\begin{bmatrix} 1 \\ -i \end{bmatrix} = \begin{bmatrix} 0.866 + 0.5i \\ 0.5 - 0.866i \end{bmatrix}, \qquad \lambda\mathbf{v} = (0.866 + 0.5i)\begin{bmatrix} 1 \\ -i \end{bmatrix} = \begin{bmatrix} 0.866 + 0.5i \\ 0.5 - 0.866i \end{bmatrix}.$$ (The second component of $\lambda\mathbf{v}$ is $(0.866 + 0.5i)(-i) = -0.866i - 0.5i^2 = 0.5 - 0.866i$.) The two columns agree exactly — $\mathbf{v} = (1, -i)$ really is an eigenvector. Its conjugate $\bar{\mathbf{v}} = (1, i)$ is the eigenvector for $\bar\lambda = e^{-i\theta}$, just as the conjugate-pair theorem promised.

Now extract the two real vectors hiding inside it. The real and imaginary parts of $\mathbf{v} = (1, -i)$ are $$\operatorname{Re}(\mathbf{v}) = \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \mathbf{e}_1, \qquad \operatorname{Im}(\mathbf{v}) = \begin{bmatrix} 0 \\ -1 \end{bmatrix} = -\mathbf{e}_2.$$ These two real vectors span the invariant plane — and for a $2\times 2$ rotation they span all of $\mathbb{R}^2$, which is right, because the rotation's invariant plane is the whole plane. The complex eigenvector did not give us a single invariant arrow (there is none); it handed us the two real directions whose plane the rotation churns. That is the lesson to carry into §26.4: a complex eigenvector is a compact, finite, perfectly computable object whose real and imaginary parts are the coordinate frame of the spinning plane.

Common Pitfall — When you normalize a complex eigenvector, the length is the complex norm $\lVert\mathbf{v}\rVert = \sqrt{\sum_i |v_i|^2} = \sqrt{|v_i|^2 + \dots}$, where $|v_i|^2 = v_i\overline{v_i}$ — not $\sqrt{\sum v_i^2}$. For $\mathbf{v} = (1, -i)$, the correct length is $\sqrt{|1|^2 + |-i|^2} = \sqrt{1 + 1} = \sqrt2$, so the unit eigenvector is $\tfrac{1}{\sqrt2}(1, -i)$ — which is exactly what numpy returns. The naive $\sqrt{1^2 + (-i)^2} = \sqrt{1 - 1} = 0$ is wrong and dangerous: it would call a nonzero vector "length zero." This is your first encounter with the rule that complex length uses the conjugate, the seed of the complex inner product we formalize in Chapter 34.

26.3 How is a complex eigenvalue a rotation and a scaling at once?

This is the heart of the chapter. We have established that complex eigenvalues encode rotation. Now we make the interpretation precise and quantitative, and we generalize from pure rotations (modulus $1$) to rotation-and-scaling (any modulus).

Write a complex eigenvalue in polar form: $$\lambda = a + bi = r\,e^{i\theta}, \qquad r = |\lambda| = \sqrt{a^2 + b^2}, \qquad \theta = \arg(\lambda) = \operatorname{atan2}(b, a).$$ Here $r$ is the modulus (the distance from the origin in the complex plane) and $\theta$ is the argument (the angle from the positive real axis). The claim is that these two numbers are the two ingredients of the transformation's action in its invariant plane:

The Key Insight — A complex eigenvalue $\lambda = re^{i\theta}$ of a real matrix means: inside an invariant 2D plane, the transformation rotates by the angle $\theta$ and scales by the factor $r$. The argument is the rotation; the modulus is the stretch. This single sentence is the entire meaning of a complex eigenvalue.

Why is this true? The cleanest way to see it is to recall how multiplication by a complex number behaves. If you think of the complex plane as $\mathbb{R}^2$ (the number $a + bi$ at the point $(a, b)$), then multiplying every point by the fixed complex number $re^{i\theta}$ does exactly one thing: it rotates the whole plane by $\theta$ and scales it by $r$. (Multiply two numbers in polar form: $r_1 e^{i\theta_1}\cdot r_2 e^{i\theta_2} = r_1 r_2\, e^{i(\theta_1 + \theta_2)}$ — moduli multiply, arguments add. Multiplying by $re^{i\theta}$ therefore adds $\theta$ to every angle and multiplies every modulus by $r$, which is precisely "rotate by $\theta$, scale by $r$.") The eigen-equation $A\mathbf{v} = \lambda\mathbf{v}$ says that on the invariant complex line spanned by $\mathbf{v}$, the matrix $A$ acts exactly like multiplication by the scalar $\lambda = re^{i\theta}$. So on the real 2D plane that this complex line corresponds to, $A$ rotates by $\theta$ and scales by $r$. The complex eigenvalue is the rotation-scaling factor, read off directly.

26.3.1 The three regimes of the modulus

Because $r = |\lambda|$ is a scale factor applied every time the transformation acts, it controls the long-run fate of the system under repeated application — exactly the powers $A^n$ we learned to compute via diagonalization in Chapter 25. Three cases, and they are the whole story of spiral dynamics:

  • $r > 1$ — spiral outward. Each application rotates and enlarges. A point released near the origin spirals away to infinity, turning by $\theta$ and growing by a factor $r$ on every step. The system is unstable.
  • $r < 1$ — spiral inward. Each application rotates and shrinks. A point spirals in toward the origin, turning by $\theta$ and decaying by a factor $r$ each step. The system is stable — it rings down to rest, like a damped oscillation.
  • $r = 1$ — pure orbit. Each application rotates without changing size. A point circles the origin forever on a closed orbit, neither growing nor decaying. This is the marginally stable boundary, and it is exactly the pure-rotation case, $\lambda = e^{i\theta}$.

Geometric Intuition — The argument $\theta$ tells you how fast the system spins (the angle turned per step), and the modulus $r$ tells you whether the spiral opens out, winds in, or holds a steady circle. A complex eigenvalue is therefore a complete weather report for rotational dynamics: direction of spin and rate of growth, in one number. We will lean on exactly this picture when we study the matrix exponential and the stability of $\mathbf{x}' = A\mathbf{x}$ in Chapter 37 — there the relevant quantity is the real part of the eigenvalue rather than the modulus, but the spiral-in / orbit / spiral-out trichotomy is the same physical idea.

26.3.2 Worked example by hand: a spiral-outward matrix

Let us make all of this concrete with a matrix that is not obviously a rotation, so the rotation has to be discovered. Take $$A = \begin{bmatrix} 1 & -2 \\ 1 & \phantom{-}3 \end{bmatrix}.$$ Its trace is $\operatorname{tr}(A) = 1 + 3 = 4$ and its determinant is $\det(A) = (1)(3) - (-2)(1) = 3 + 2 = 5$. The characteristic polynomial (Chapter 24's shortcut for $2\times 2$ matrices, $\lambda^2 - \operatorname{tr}(A)\,\lambda + \det(A)$) is $$\lambda^2 - 4\lambda + 5 = 0.$$ The discriminant is $16 - 20 = -4 < 0$: complex eigenvalues, so this matrix is rotating. Solving with the quadratic formula, $$\lambda = \frac{4 \pm \sqrt{-4}}{2} = \frac{4 \pm 2i}{2} = 2 \pm i.$$ Now read off the geometry by converting $\lambda = 2 + i$ to polar form. The modulus and argument are $$r = |\lambda| = \sqrt{2^2 + 1^2} = \sqrt{5} \approx 2.2361, \qquad \theta = \arg(\lambda) = \operatorname{atan2}(1, 2) \approx 0.4636\ \text{rad} \approx 26.565°.$$ So $A$ rotates by about $26.57°$ and scales by about $2.236$ in its invariant plane, on every application. Because $r = \sqrt5 > 1$, points spiral outward: iterate $A$ and any starting vector winds away from the origin, growing by $\sqrt5$ and turning by $26.57°$ each step.

A satisfying cross-check: for a $2\times 2$ matrix, the product of the eigenvalues equals the determinant (Chapter 24). Here $\lambda\bar\lambda = |\lambda|^2 = r^2 = 5$, and indeed $\det(A) = 5$. The determinant is the squared modulus, $r^2$ — which makes geometric sense, because each application scales 2D area by $\det(A)$, and scaling lengths by $r$ scales area by $r^2$. The algebra and the area picture agree to the digit.

26.3.3 numpy verification

Now confirm every one of those hand numbers against np.linalg.eig. Recall the convention noted in earlier chapters: the math writes the eigenvalue $\lambda = a + bi$, while numpy returns it as a Python complex a+bj, with j (not i) for the imaginary unit, and indexes the returned arrays from $0$.

# Complex eigenvalues of a real matrix: modulus = scaling, argument = rotation angle.
import numpy as np
A = np.array([[1.0, -2.0],
              [1.0,  3.0]])
eigvals, eigvecs = np.linalg.eig(A)

print("eigenvalues:", eigvals)
print("|lambda| (modulus, the scale factor) :", np.abs(eigvals))
print("arg(lambda) in degrees (rotation)    :", np.degrees(np.angle(eigvals)))
print("det(A) and r^2 :", round(np.linalg.det(A), 4), "vs", round(abs(eigvals[0])**2, 4))
eigenvalues: [2.+1.j 2.-1.j]
|lambda| (modulus, the scale factor) : [2.23606798 2.23606798]
arg(lambda) in degrees (rotation)    : [ 26.56505118 -26.56505118]
det(A) and r^2 : 5.0 vs 5.0

Every number matches the hand computation: the eigenvalues are the conjugate pair $2 \pm i$, the modulus is $\sqrt5 \approx 2.236$, the rotation angle is $\pm 26.565°$ (the two conjugate eigenvalues rotate by opposite angles — one says "$+26.57°$," its partner says "$-26.57°$," and the real motion is the single sense of rotation they jointly encode), and $\det(A) = r^2 = 5$. The conjugate eigenvalues have equal moduli (a real matrix spirals at a single rate) and opposite arguments, exactly as the conjugate-pair theorem demands.

Computational Notenp.linalg.eig returns complex arrays (dtype complex128) the moment a matrix has any complex eigenvalue, and the eigenvalues are not sorted — do not assume eigvals[0] is the one with positive imaginary part. The eigenvectors it returns are also complex and are normalized to unit length in the complex norm $\lVert\mathbf{v}\rVert = \sqrt{\sum |v_i|^2}$ (the complex inner product of Chapter 34, where $|v_i|^2 = v_i\overline{v_i}$), and they are determined only up to an arbitrary complex phase $e^{i\phi}$ — so your eigenvector may differ from a friend's (or from a textbook's) by a unit-modulus complex factor and still be correct. When you need a deterministic real description, extract the modulus, the argument, and the real canonical form (next section) rather than comparing raw complex eigenvectors.

26.3.4 A second example: when the matrix is already a rotation-scaling

The matrix $\begin{psmallmatrix}1 & -2\\ 1 & 3\end{psmallmatrix}$ hid its rotational nature in a tilted coordinate system. Some matrices wear it openly. Consider $$A = \begin{bmatrix} 2 & -3 \\ 3 & \phantom{-}2 \end{bmatrix},$$ which already has the tell-tale antisymmetric pattern — equal diagonal entries $a = 2$, and off-diagonals $-3$ above, $+3$ below. This is the block $\begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$ with $a = 2$, $b = 3$, so we can predict the eigenvalues without any computation: $\lambda = a \pm bi = 2 \pm 3i$. Its modulus is $r = \sqrt{2^2 + 3^2} = \sqrt{13} \approx 3.606$ and its argument is $\theta = \operatorname{atan2}(3, 2) \approx 56.31°$. So $A$ rotates by about $56.3°$ and scales by about $3.6$ — and because $b > 0$, the rotation is counterclockwise. Let us confirm.

# A matrix already in rotation-scaling form: eigenvalues are a +- bi by inspection.
import numpy as np
A = np.array([[2.0, -3.0],
              [3.0,  2.0]])
eigvals = np.linalg.eigvals(A)
print("eigenvalues :", eigvals)
print("modulus r   :", round(abs(eigvals[0]), 4), "  (sqrt 13 =", round(np.sqrt(13), 4), ")")
print("argument deg:", round(np.degrees(np.angle(eigvals[eigvals.imag > 0][0])), 4))
eigenvalues : [2.+3.j 2.-3.j]
modulus r   : 3.6056   (sqrt 13 = 3.6056 )
argument deg: 56.3099

Exactly as predicted: $\lambda = 2 \pm 3i$, $r = \sqrt{13} \approx 3.606$, $\theta \approx 56.31°$. When a real $2\times 2$ matrix has equal diagonal entries and equal-but-opposite off-diagonals, it is a rotation-scaling already, no change of basis required — the block form is its native form. Learning to recognize that pattern by eye is a useful skill: it tells you a matrix is a spiral generator at a glance, before you compute a single eigenvalue.

Check Your Understanding — Without using the quadratic formula, write down the eigenvalues, the modulus, and the rotation angle of $A = \begin{psmallmatrix}0 & -2\\ 2 & \phantom{-}0\end{psmallmatrix}$. What does this matrix do to the plane?

Answer It is the block $\begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$ with $a = 0$, $b = 2$, so the eigenvalues are $0 \pm 2i = \pm 2i$ (purely imaginary). The modulus is $r = \sqrt{0^2 + 2^2} = 2$ and the argument is $\theta = \operatorname{atan2}(2, 0) = 90°$. So $A$ rotates the plane by $90°$ counterclockwise and scales it by $2$. (Equivalently $A = 2\begin{psmallmatrix}0 & -1\\ 1 & 0\end{psmallmatrix}$, twice the standard $90°$ rotation.) Purely imaginary eigenvalues — zero real part — are the signature of a quarter-turn rotation combined with scaling; you will see in Chapter 37 that purely imaginary eigenvalues mark the boundary between stable and unstable in continuous-time systems, the undamped oscillator that orbits forever.

26.4 What is the real canonical (block) form of a rotation-scaling matrix?

Complex eigenvalues and complex eigenvectors are correct, but they are awkward: a real engineer modeling a real circuit would rather not carry $i$ around. Happily, the conjugate-pair structure lets us repackage the complex eigen-data into a purely real normal form — the rotation-scaling block. This is the real-arithmetic analogue of diagonalization for matrices with complex eigenvalues, and it is the form in which complex eigenvalues do their everyday work.

The Key Insight — A real $2\times 2$ matrix with eigenvalues $\lambda = a \pm bi$ is similar, over the real numbers, to the block $$C = \begin{bmatrix} a & -b \\ b & \phantom{-}a \end{bmatrix}.$$ That is, $A = PCP^{-1}$ for a real invertible $P$. The block $C$ is exactly a rotation-scaling: it equals $r$ times a rotation matrix, $C = r\begin{psmallmatrix}\cos\theta & -\sin\theta\\ \sin\theta & \cos\theta\end{psmallmatrix}$, with $r = \sqrt{a^2 + b^2}$ and $\theta = \operatorname{atan2}(b, a)$.

Let us first verify that the block $C$ really is a scaled rotation, because that is what justifies calling it "rotation-scaling." Factor out $r = \sqrt{a^2 + b^2}$: $$C = \begin{bmatrix} a & -b \\ b & \phantom{-}a \end{bmatrix} = r\begin{bmatrix} a/r & -b/r \\ b/r & \phantom{-}a/r \end{bmatrix} = r\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \phantom{-}\cos\theta \end{bmatrix},$$ where the last step uses $\cos\theta = a/r$ and $\sin\theta = b/r$ — which is just the definition of the polar angle of $a + bi$. So $C$ scales by $r$ and rotates by $\theta$: rotation-scaling, made of real numbers, with the spin and the stretch visible right in the entries. The off-diagonal entries are equal in magnitude and opposite in sign, $-b$ above and $+b$ below; that antisymmetric pattern is the signature of rotation, and you will learn to spot a hidden rotation by it. Its eigenvalues, by the way, are $a \pm bi$ — exactly the eigenvalues of $A$ — which is the whole reason $C$ is the right canonical form.

26.4.1 How to build $P$ from a complex eigenvector

The columns of $P$ come straight from the complex eigenvector, split into its real and imaginary parts. Take the eigenvalue $\lambda = a + bi$ with positive imaginary part and its complex eigenvector $\mathbf{v}$, and write $$\mathbf{v} = \mathbf{p} + i\mathbf{q}, \qquad \mathbf{p} = \operatorname{Re}(\mathbf{v}) \in \mathbb{R}^n, \quad \mathbf{q} = \operatorname{Im}(\mathbf{v}) \in \mathbb{R}^n.$$ The two real vectors $\mathbf{p}$ and $\mathbf{q}$ span the invariant real plane. The matrix $P$ that conjugates $A$ into the block $C$ is built from them as $$P = \big[\, \mathbf{p} \ \big|\ -\mathbf{q} \,\big] = \big[\, \operatorname{Re}(\mathbf{v}) \ \big|\ -\operatorname{Im}(\mathbf{v}) \,\big].$$ (Different books choose different sign and ordering conventions — $[\mathbf{p}\mid -\mathbf{q}]$, $[\mathbf{q}\mid\mathbf{p}]$, and others all work, each producing the block $C$ with a particular sign of $b$; the geometry of "rotate by $\pm\theta$, scale by $r$" is identical, and the only thing that flips is the sense of the rotation. We adopt $[\operatorname{Re}(\mathbf{v})\mid -\operatorname{Im}(\mathbf{v})]$ throughout this book so that $C$ comes out as $\begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$ with $b > 0$.) The reason this works comes from expanding the eigen-equation into real and imaginary parts.

26.4.2 Why it works: separating $A\mathbf{v} = \lambda\mathbf{v}$ into real and imaginary parts

The derivation is short and worth seeing once. Substitute $\mathbf{v} = \mathbf{p} + i\mathbf{q}$ and $\lambda = a + bi$ into $A\mathbf{v} = \lambda\mathbf{v}$: $$A(\mathbf{p} + i\mathbf{q}) = (a + bi)(\mathbf{p} + i\mathbf{q}).$$ The left side is $A\mathbf{p} + iA\mathbf{q}$ (the matrix $A$ is real, so it passes through the $i$ untouched). Expand the right side and collect real and imaginary parts, using $i^2 = -1$: $$(a + bi)(\mathbf{p} + i\mathbf{q}) = (a\mathbf{p} - b\mathbf{q}) + i(b\mathbf{p} + a\mathbf{q}).$$ A complex equation holds exactly when its real and imaginary parts match separately, so we get two real equations: $$A\mathbf{p} = a\mathbf{p} - b\mathbf{q}, \qquad A\mathbf{q} = b\mathbf{p} + a\mathbf{q}.$$ Read these as statements about what $A$ does to the basis $\{\mathbf{p}, -\mathbf{q}\}$ of the invariant plane. With $P = [\mathbf{p}\mid -\mathbf{q}]$, the images $A\mathbf{p}$ and $A(-\mathbf{q})$ expressed in that basis are exactly the columns of $C = \begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$ — which is precisely the statement $AP = PC$, i.e. $A = PCP^{-1}$. The complex eigen-equation, split into its two real halves, is the rotation-scaling block. The imaginary unit was scaffolding; once the plane is found, the real description stands on its own.

Math-Major Sidebar — Over $\mathbb{C}$, this matrix simply diagonalizes: $A = V D V^{-1}$ with $D = \operatorname{diag}(\lambda, \bar\lambda)$ and $V = [\mathbf{v}\mid\bar{\mathbf{v}}]$, exactly as in Chapter 25 — complex eigenvalues are no obstacle to diagonalization once you allow complex matrices. The real canonical form $A = PCP^{-1}$ is what you get by applying the real change of basis $\mathbf{v}, \bar{\mathbf{v}} \mapsto \operatorname{Re}\mathbf{v}, \operatorname{Im}\mathbf{v}$ to that complex diagonalization; concretely, $C = S D S^{-1}$ where $S = \tfrac12\begin{psmallmatrix}1 & 1\\ -i & i\end{psmallmatrix}$ is the fixed matrix that turns $\operatorname{diag}(a+bi, a-bi)$ into $\begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$. The block form is the price (and the prize) of insisting on real arithmetic: you trade a diagonal matrix with complex entries for a block-diagonal matrix with real entries. For an $n\times n$ real matrix this generalizes to the real Jordan / block-diagonal form — real eigenvalues give $1\times 1$ blocks, conjugate pairs give $2\times 2$ rotation-scaling blocks — which we meet again alongside the Jordan normal form in Chapter 36.

26.4.3 Worked example: reconstructing the block, with numpy

Return to $A = \begin{psmallmatrix}1 & -2\\ 1 & 3\end{psmallmatrix}$, whose eigenvalues we found to be $2 \pm i$, so we expect the block $C = \begin{psmallmatrix}2 & -1\\ 1 & 2\end{psmallmatrix}$. Let us build $P$ from the eigenvector and confirm $A = PCP^{-1}$ numerically.

# Reconstruct the real canonical (rotation-scaling) form A = P C P^{-1}.
import numpy as np
A = np.array([[1.0, -2.0],
              [1.0,  3.0]])
eigvals, eigvecs = np.linalg.eig(A)

k = int(np.argmax(eigvals.imag))      # pick the eigenvalue with positive imaginary part
lam, v = eigvals[k], eigvecs[:, k]
a, b = lam.real, lam.imag
P = np.column_stack([v.real, -v.imag])      # P = [Re v | -Im v]
C = np.array([[a, -b],
              [b,  a]])                       # the rotation-scaling block
print("a, b =", round(a, 4), round(b, 4))
print("C =\n", np.round(C, 4))
print("P C P^-1 reproduces A:", np.allclose(P @ C @ np.linalg.inv(P), A))
a, b = 2.0 1.0
C =
 [[ 2. -1.]
 [ 1.  2.]]
P C P^-1 reproduces A: True

The block is $C = \begin{psmallmatrix}2 & -1\\ 1 & 2\end{psmallmatrix}$, exactly as predicted from $\lambda = 2 + i$, and $PCP^{-1}$ reproduces $A$ to floating-point tolerance. So the seemingly arbitrary matrix $\begin{psmallmatrix}1 & -2\\ 1 & 3\end{psmallmatrix}$ is, after a real change of basis, nothing but a rotation by $26.57°$ combined with a stretch by $\sqrt5$. Its complicated-looking entries were an artifact of the coordinate system; in the right (skewed) coordinates given by $P$, its true nature — spin and stretch — is laid bare. This is the recurring theme of Part V in its complex-eigenvalue costume: eigen-analysis reveals what a matrix really does, stripped of coordinate-system disguise.

Common Pitfall — Three traps cluster around complex eigen-data. First, do not try to interpret a single complex eigenvector as a real direction in space — it is not an arrow you can draw; its real and imaginary parts together span an invariant plane, and the spin happens in that plane. Second, do not forget that the eigenvalues and eigenvectors come in conjugate pairs: the second eigenvalue $\bar\lambda = a - bi$ and its eigenvector $\bar{\mathbf{v}}$ carry no new information — they are the mirror image of the first, and using both as if they were independent real directions double-counts the single 2D motion. Third, do not read the rotation angle off the matrix entries directly the way you would for an obvious rotation matrix; for a general $A$ you must compute the eigenvalues first, then take $\theta = \arg(\lambda)$ — the entries of $A$ are written in the wrong coordinate system to show the angle.

26.4.4 A quick test: when does a $2\times 2$ matrix have complex eigenvalues?

Because so much of this chapter lives in the $2\times 2$ world, it is worth having a one-glance test for whether a given $2\times 2$ matrix rotates. From Chapter 24, the characteristic polynomial of $A = \begin{psmallmatrix}a & b\\ c & d\end{psmallmatrix}$ is $\lambda^2 - \operatorname{tr}(A)\,\lambda + \det(A)$, with $\operatorname{tr}(A) = a + d$ and $\det(A) = ad - bc$. The eigenvalues are complex exactly when the discriminant is negative: $$\boxed{\ \operatorname{tr}(A)^2 - 4\det(A) < 0 \quad\Longleftrightarrow\quad A \text{ has complex eigenvalues (it rotates).}\ }$$ When this holds, the eigenvalues are $\lambda = \tfrac{\operatorname{tr}(A)}{2} \pm \tfrac{\sqrt{4\det(A) - \operatorname{tr}(A)^2}}{2}\,i$, so the real part is half the trace and the modulus is $r = \sqrt{\det(A)}$ — two facts worth memorizing. The first says the conjugate pair straddles $a = \operatorname{tr}(A)/2$ symmetrically; the second re-derives the area identity $\det(A) = r^2$ from §26.3.2. A high determinant relative to the trace forces a rotation: intuitively, if the matrix scales area a lot ($\det$ large and positive) without stretching along any single real axis ($\operatorname{tr}$ small), the only way it can grow area is by rotating while it scales. The condition $\operatorname{tr}(A)^2 < 4\det(A)$ is the precise tipping point where real stretching becomes impossible and rotation takes over.

For an everyday check, you rarely need the whole quadratic — just the sign of $\operatorname{tr}(A)^2 - 4\det(A)$. Positive: two real eigenvalues, no rotation. Zero: a repeated real eigenvalue, the borderline (possibly defective) case of Chapter 25. Negative: a complex conjugate pair, and the matrix is a rotation-scaling in disguise. This is the $2\times 2$ companion to the visualizer's "do any arrows stay on their line?" — the discriminant answers the same question with arithmetic instead of a picture.

26.5 How do complex eigenvalues produce spirals?

We have the static picture; now let us watch the dynamics, because "spiral" is a statement about iteration — about applying the matrix again and again, the very thing diagonalization (Chapter 25) was built to handle. Repeatedly applying $A = \begin{psmallmatrix}1 & -2\\ 1 & 3\end{psmallmatrix}$ to a starting vector should rotate by $26.57°$ and grow by $\sqrt5$ each step, tracing a spiral that opens outward.

# Iterating a matrix with complex eigenvalues traces a spiral (r > 1: outward).
import numpy as np
A = np.array([[1.0, -2.0],
              [1.0,  3.0]])
x = np.array([1.0, 0.0])
print(f"{'step':>4} {'x':>20} {'||x||':>10}")
for n in range(5):
    print(f"{n:>4} {str(np.round(x, 3)):>20} {np.linalg.norm(x):>10.4f}")
    x = A @ x                      # one more application of the transformation
print("growth per step should be r = sqrt(5) =", round(np.sqrt(5), 4))
step                    x      ||x||
   0           [1. 0.]     1.0000
   1           [1. 1.]     1.4142
   2          [-1.  4.]     4.1231
   3         [-9. 11.]    14.2127
   4        [-31.  24.]    39.2046

The length grows from $1$ toward larger and larger values; the ratio of successive lengths approaches $\sqrt5 \approx 2.236$ (e.g. $14.21 / 4.12 \approx 3.45$ early on—the per-step ratio oscillates (the orbit spirals on a tilted ellipse), but its long-run geometric average, and the growth rate $\lVert A^n\mathbf{x}\rVert^{1/n}$, equal $\sqrt5$), and the sign pattern flips as the vector swings around the origin. Plotting the points $\mathbf{x}, A\mathbf{x}, A^2\mathbf{x}, \dots$ traces a spiral winding outward and counterclockwise — the geometric signature of a complex eigenvalue with modulus greater than $1$.

To see the spiral rather than read it off a table, plot the successive iterates and connect them. (We use a smaller starting vector and many steps so the early turns are visible before the growth runs off the page.)

# Plot the spiral traced by repeatedly applying A (complex eigenvalues, r > 1).
import numpy as np, matplotlib.pyplot as plt
A = np.array([[1.0, -2.0], [1.0, 3.0]])
pts = [np.array([0.3, 0.0])]
for _ in range(7):
    pts.append(A @ pts[-1])
pts = np.array(pts)
plt.plot(pts[:, 0], pts[:, 1], "o-", color="C1")     # the spiral of iterates
plt.plot(0, 0, "k+", markersize=10)                    # the origin
plt.gca().set_aspect("equal"); plt.grid(True, alpha=0.3)
plt.title(r"Iterates $x, Ax, A^2x, \dots$ spiral out ($r=\sqrt5$)")
plt.show()

Figure 26.2The orbit of a point under repeated application of $A = \begin{psmallmatrix}1 & -2\\ 1 & 3\end{psmallmatrix}$. Starting near the origin, each step turns the point about $26.6°$ counterclockwise and pushes it $\sqrt5\approx 2.24$ times farther out, so the connected iterates trace an outward spiral. Alt-text: a sequence of dots emanating from the origin, each farther out and rotated from the last, sweeping counterclockwise into an ever-widening spiral arm.

Geometric Intuition — Picture the orbit as the trajectory of a particle that is kicked by the matrix once per step. The argument $\theta$ sets how far around the particle swings each kick; the modulus $r$ sets whether the particle drifts outward ($r>1$, energy injected), inward ($r<1$, energy dissipated), or holds a perfect circle ($r=1$, energy conserved). A pendulum losing amplitude to friction is $r<1$; an idealized frictionless oscillator is $r=1$; a microphone howling into a speaker — feedback gone unstable — is $r>1$. The two numbers inside one complex eigenvalue, $\theta$ and $r$, are the shape and the fate of the spiral.

26.5.1 The decaying spiral: stability through the modulus

To see the stable case, build a matrix deliberately as "scale by $0.9$, then rotate by $40°$" — a rotation matrix multiplied by $0.9$: $$A = 0.9\begin{bmatrix} \cos 40° & -\sin 40° \\ \sin 40° & \phantom{-}\cos 40° \end{bmatrix}.$$ Because scaling commutes with everything (it is $0.9I$), this matrix's eigenvalues are $0.9$ times the rotation's eigenvalues $e^{\pm i\,40°}$, namely $0.9\,e^{\pm i\,40°}$ — modulus $0.9$, argument $\pm 40°$.

# A deliberately built spiral-in matrix: scale by 0.9, rotate by 40 degrees.
import numpy as np
th = np.deg2rad(40)
A = 0.9 * np.array([[np.cos(th), -np.sin(th)],
                    [np.sin(th),  np.cos(th)]])
eigvals = np.linalg.eigvals(A)
print("eigenvalues  :", np.round(eigvals, 4))
print("moduli |lam| :", np.round(np.abs(eigvals), 4))   # both 0.9 -> spiral IN
print("args (deg)   :", np.round(np.degrees(np.angle(eigvals)), 4))
eigenvalues  : [0.6894+0.5785j 0.6894-0.5785j]
moduli |lam| : [0.9 0.9]
args (deg)   : [ 40. -40.]

Both eigenvalues have modulus $0.9 < 1$, so every starting vector spirals inward, shrinking by a factor $0.9$ and turning $40°$ per step, decaying to the origin — a damped oscillation ringing down to rest. This is exactly the discrete-time stability criterion: a linear system $\mathbf{x}_{n+1} = A\mathbf{x}_n$ is stable precisely when every eigenvalue has modulus $\le 1$ (strictly $< 1$ for decay to zero). Complex eigenvalues add the rotational flavor — stability with oscillation, the system spiraling rather than sliding into rest. We develop the continuous-time version, where the test is on the eigenvalue's real part and the engine is the matrix exponential $e^{At}$, in Chapter 37; the discrete spiral you see here is its mirror image.

Real-World ApplicationCyclic dynamics in ecology and economics. Predator–prey populations, business cycles, and inventory–restocking loops all oscillate, and the linearized model near an equilibrium is a matrix $A$ whose eigenvalues are typically a complex conjugate pair. The argument sets the period of the cycle (how many years between booms), and the modulus says whether the oscillations grow into instability ($r>1$), damp toward a steady state ($r<1$), or persist as a stable cycle ($r=1$). A central-bank economist tuning policy and a fisheries manager setting quotas are both, in effect, trying to push the dominant eigenvalue's modulus to the stable side of $1$. We work a population-cycle model in detail in this chapter's second case study, and you will meet the same eigenvalue-driven dynamics in Markov chains, where the largest eigenvalue governs long-run behavior.

26.5.2 Matrix powers, the complex-eigenvalue way

Chapter 25 sold diagonalization on a single irresistible benefit: once $A = PDP^{-1}$, the powers are trivial, $A^n = PD^nP^{-1}$, because $D^n$ just raises each diagonal eigenvalue to the $n$-th power. The same trick works here, with the rotation-scaling block playing the role of $D$. From $A = PCP^{-1}$ we get $$A^n = PC^nP^{-1},$$ and the power of the block is wonderfully clean, because raising a scaled rotation to the $n$-th power scales by $r^n$ and rotates by $n\theta$: $$C^n = \left(r\begin{bmatrix}\cos\theta & -\sin\theta\\ \sin\theta & \cos\theta\end{bmatrix}\right)^{\! n} = r^n\begin{bmatrix}\cos(n\theta) & -\sin(n\theta)\\ \sin(n\theta) & \cos(n\theta)\end{bmatrix}.$$ This is De Moivre's theorem $(re^{i\theta})^n = r^n e^{in\theta}$ wearing a matrix costume: $n$ applications of "rotate by $\theta$, scale by $r$" is "rotate by $n\theta$, scale by $r^n$," exactly as iterating a complex multiplication would predict. The eigenvalue $\lambda^n = r^n e^{in\theta}$ literally is the entry that drives $C^n$. Let us confirm $A^4$ for our running matrix, whose block has $r = \sqrt5$, $\theta \approx 26.57°$.

# A^n via the rotation-scaling block: C^n scales by r^n and rotates by n*theta.
import numpy as np
A = np.array([[1.0, -2.0],
              [1.0,  3.0]])
eigvals, eigvecs = np.linalg.eig(A)
k = int(np.argmax(eigvals.imag)); v = eigvecs[:, k]
P = np.column_stack([v.real, -v.imag])
r, theta = np.sqrt(5), np.arctan2(1, 2)
n = 4
Cn = r**n * np.array([[np.cos(n*theta), -np.sin(n*theta)],
                      [np.sin(n*theta),  np.cos(n*theta)]])
print("A^4 via block:\n", np.round(P @ Cn @ np.linalg.inv(P), 4))
print("A^4 direct   :\n", np.linalg.matrix_power(A, 4))
print("r^4 = scale after 4 steps =", round(r**4, 4))
A^4 via block:
 [[-31. -48.]
 [ 24.  17.]]
A^4 direct   :
 [[-31 -48]
 [ 24  17]]
r^4 = scale after 4 steps = 25.0

The two routes to $A^4$ agree exactly, and the overall scale after four steps is $r^4 = (\sqrt5)^4 = 25$ — the spiral has grown lengths twenty-five-fold while turning a total of $4\theta \approx 106°$. This is the complex-eigenvalue counterpart of Chapter 25's headline: the eigenstructure turns the hard problem of matrix powers into the easy problem of raising one number, $\lambda = re^{i\theta}$, to a power — and for a complex eigenvalue that power is a spiral, growth $r^n$ braided with rotation $n\theta$.

Math-Major Sidebar — The closed form for $A^n$ also gives the closed form for solutions of the discrete dynamical system $\mathbf{x}_n = A^n\mathbf{x}_0$: each coordinate is a combination of $r^n\cos(n\theta)$ and $r^n\sin(n\theta)$, the discrete analogue of the damped sinusoids $e^{\sigma t}\cos(\omega t)$ that solve $\mathbf{x}' = A\mathbf{x}$ in Chapter 37. The modulus $r$ plays the role of the growth rate $e^{\sigma}$ and the argument $\theta$ plays the role of the angular frequency $\omega$. So the algebra you built here — split a complex eigenvalue into modulus and argument — is the same algebra that, in continuous time, separates a vibration's decay rate from its pitch. A single eigenvalue carries both.

26.6 What do complex eigenvalues have to do with unitary matrices?

We close the exposition by connecting this chapter to the two that bracket it. Chapter 21 introduced orthogonal matrices — real matrices with $Q^{\mathsf{T}}Q = I$ that preserve length — and showed that rotations are exactly the orthogonal matrices with $\det = +1$. We can now say what their eigenvalues must look like: since a rotation preserves length, it cannot grow or shrink anything, so its eigenvalues must have modulus exactly $1$. Indeed our very first computation found the rotation's eigenvalues to be $e^{\pm i\theta}$, which lie on the unit circle in the complex plane. That is no accident.

Geometric Intuition — All eigenvalues of an orthogonal matrix lie on the unit circle: $|\lambda| = 1$ for every one. The real eigenvalues are therefore only $+1$ (a fixed direction) or $-1$ (a flipped direction); everything else is a genuinely complex $e^{i\theta}$ on the circle, a pure rotation in some invariant plane. A length-preserving map can turn directions (modulus $1$, argument $\theta$) and flip them ($\lambda = -1$), but it can never stretch them (that would require $|\lambda| \ne 1$), which is the eigenvalue-side statement of "rigid motion."

The complex generalization of an orthogonal matrix is a unitary matrix $U$, satisfying $U^{*}U = I$ where $U^{*}$ is the conjugate (Hermitian) transpose from our notation table. Unitary matrices are the length-preserving maps of complex space $\mathbb{C}^n$, and they too have all their eigenvalues on the unit circle. This is the mathematics of quantum logic gates, where a gate must be unitary so that total probability — the squared complex length of the state vector — stays equal to $1$; the gate may rotate the qubit's state around the complex sphere, but never grow or shrink it. We will build the proper machinery of complex inner products, the conjugate transpose, and unitary matrices in Chapters 27 and 34. For now, simply register the through-line: the complex eigenvalues you met here as "rotations in disguise" are the same objects that, on the unit circle, describe the perfectly reversible, length-preserving evolution of complex amplitudes in quantum mechanics. The qubit we teased in Chapter 1 lives in exactly this circle of ideas.

Historical Note — The recognition that an honest real polynomial could require complex roots — and that those roots were not "fictitious" but carried real geometric meaning — matured over the seventeenth and eighteenth centuries. The Fundamental Theorem of Algebra, that every degree-$n$ polynomial has exactly $n$ complex roots (so every $n\times n$ matrix has exactly $n$ complex eigenvalues, counted with multiplicity), was given its first widely accepted proof by Carl Friedrich Gauss in 1799, in his doctoral dissertation [verify]. The interpretation of multiplication by $e^{i\theta}$ as a rotation of the plane is usually credited to the geometric representation of complex numbers developed by Caspar Wessel (1799) and Jean-Robert Argand (1806) [verify] — which is why the picture of the complex plane is often called the Argand diagram.

Worth noting alongside the quantum connection: this same unit-circle picture is the foundation of digital signal processing. A digital filter is a linear system whose behavior is governed by the eigenvalues (the poles) of its state matrix, and an engineer designing one places those poles relative to the unit circle in the complex plane — inside the circle ($|\lambda| < 1$) for a stable filter that settles, on the circle for a pure oscillator, outside for an unstable one that blows up. The "$z$-plane" that every signal-processing course draws is precisely the complex plane of this chapter, and "stay inside the unit circle" is precisely "$|\lambda| < 1$, the spiral winds in." Complex eigenvalues are not a niche curiosity; they are the daily language of anyone who designs systems that oscillate.

Real-World ApplicationControl systems and signal processing. The autopilot holding an aircraft level, the cruise control maintaining your speed, and the noise-cancelling filter in your headphones are all linear feedback systems whose stability is decided by the complex eigenvalues (poles) of a matrix. A control engineer's central task is pole placement: choosing feedback gains so that every eigenvalue lands where its modulus (in discrete time) or real part (in continuous time, Chapter 37) guarantees the system damps out disturbances instead of amplifying them into oscillation. The complex part of the eigenvalue tells the engineer how much the response will ring (oscillate) on its way to rest; the modulus tells them whether it rings down to silence or up to catastrophe. Reading $re^{i\theta}$ as "ringing frequency $\theta$, decay-or-growth $r$" is the working intuition of an entire engineering discipline.

26.6.1 Build the rotation-scaling extractor

You now have everything needed to automate this chapter's central computation: take a real $2\times 2$ matrix with complex eigenvalues, recover the spin angle and stretch factor, and reconstruct the rotation-scaling block — the work we did by hand in §26.4 and verified against numpy in §26.4.3.

Build Your Toolkit — Implement rotation_scaling(A) in toolkit/eigen.py. Given a real $2\times 2$ array A with complex eigenvalues, it should (1) form the characteristic polynomial $\lambda^2 - \operatorname{tr}(A)\,\lambda + \det(A)$ from the trace and determinant, (2) check that the discriminant $\operatorname{tr}(A)^2 - 4\det(A)$ is negative (raise a clear error if the eigenvalues are real — there is no rotation to extract), (3) return the modulus $r = \sqrt{\det(A)}$, the argument $\theta = \operatorname{atan2}\!\big(\sqrt{4\det(A) - \operatorname{tr}(A)^2}/2,\ \operatorname{tr}(A)/2\big)$, and the block $C = \begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$ with $a = \operatorname{tr}(A)/2$ and $b = \sqrt{4\det(A) - \operatorname{tr}(A)^2}/2$. Implement it in pure Python (use math, no numpy in the body — r is just $\sqrt{\det A}$ because $\det A = r^2$, and the trace gives $2a = 2r\cos\theta$). Verify against np.linalg.eig: your $r$ must equal np.abs(eigvals) and your $\theta$ must equal np.angle(eigvals[k]) for the eigenvalue with positive imaginary part, and your block $C$ must satisfy np.allclose(P @ C @ inv(P), A) for $P = [\operatorname{Re}\mathbf{v}\mid-\operatorname{Im}\mathbf{v}]$. This joins power_iteration (Chapters 23 and 29) in toolkit/eigen.py.

A short sketch of the result you are reproducing (the full implementation is yours to write):

# Sketch only — verify your from-scratch toolkit version against this.
import numpy as np, math
def rotation_scaling_check(A):
    tr, det = A[0][0] + A[1][1], A[0][0]*A[1][1] - A[0][1]*A[1][0]
    disc = tr*tr - 4*det
    if disc >= 0:
        raise ValueError("eigenvalues are real; no rotation-scaling form")
    a, b = tr/2, math.sqrt(-disc)/2          # lambda = a + i b, b > 0
    r, theta = math.sqrt(det), math.atan2(b, a)
    return r, theta, [[a, -b], [b, a]]

print(rotation_scaling_check([[1.0, -2.0], [1.0, 3.0]]))
# (2.23606..., 0.46364..., [[2.0, -1.0], [1.0, 2.0]])  -> matches np.linalg.eig

26.7 What is the big picture of complex eigenvalues?

Step back and survey what this chapter added to the eigen-toolkit of Part V. In Chapter 23 we learned that eigenvectors are the directions a matrix does not turn; in Chapter 24 that eigenvalues are the roots of the characteristic polynomial; in Chapter 25 that enough independent eigenvectors let a matrix diagonalize. This chapter confronted the matrices that break the real story — the ones with no real invariant direction — and discovered that they are not broken at all. They rotate, and the complex numbers are the exact language for describing rotation algebraically.

The single sentence to carry away is the threshold idea: a complex eigenvalue $re^{i\theta}$ of a real matrix means rotation by $\theta$ and scaling by $r$ in an invariant plane. The argument is the spin; the modulus is the stretch. Real matrices keep their complex eigenvalues in conjugate pairs $a \pm bi$, so the imaginary parts always cancel when you build something real — and that conjugate structure lets you trade the awkward complex diagonalization for the tidy real rotation-scaling block $\begin{psmallmatrix}a & -b\\ b & a\end{psmallmatrix}$. The modulus then forecasts the dynamics: spiral out ($r>1$), spiral in ($r<1$), or orbit forever ($r=1$), which is the eigenvalue test for stability that Chapter 37 will turn into the theory of differential equations and phase portraits. And the whole circle of ideas reaches forward to the Spectral Theorem (Chapter 27), where symmetric matrices are revealed as the special case that has no complex eigenvalues at all — pure stretching, no rotation — and onward to the unitary maps that run quantum mechanics.

That is the deepest lesson of this chapter, and of Part V: a matrix's eigenvalues, real or complex, report its essential action. Complex eigenvalues do not signal failure; they signal motion. Learn to read $re^{i\theta}$ as "turn by $\theta$, scale by $r$," and a whole world of oscillating, spiraling, cycling systems opens to the same eigen-analysis you have been building since the start of this part.