MATH-300 · Lesson 4 of 12 · 27 min
Computing eigenvalues
Eigenvalue problems are everywhere in engineering. The natural frequencies and mode shapes of a building, bridge or aircraft wing are eigenvalues and eigenvectors of its stiffness and mass matrices; the buckling loads of a frame are eigenvalues; the stability of a control system or a power grid depends on the eigenvalues of its system matrix; principal stresses and principal axes are eigenvalues of a symmetric tensor; and the long-run behavior of a Markov chain, including the ranking of web pages, is an eigenvector. MATH-125 found eigenvalues by solving the characteristic polynomial, which works for 2 × 2 and 3 × 3 matrices but is hopeless for the thousands or millions of unknowns in a finite element model. This lesson develops the methods computers actually use: power iteration, inverse iteration with shifts, the Rayleigh quotient, the QR algorithm behind every library eigenvalue routine, and the Krylov methods that find a few eigenvalues of huge sparse matrices. It also explains when computed eigenvalues can be trusted.
Why not the characteristic polynomial?
For an n × n matrix, \(\det(A - \lambda I) = 0\) is a polynomial of degree n. Expanding the determinant costs far more than solving the eigenvalue problem directly, and there is a deeper problem: the roots of a polynomial can be extremely sensitive to its coefficients. Wilkinson's famous example has roots 1, 2, …, 20; changing one coefficient by about one part in 10¹⁰ moves several roots by large amounts and makes some of them complex. Round-off in forming the coefficients (Lesson 1) is enough to ruin the answer. So numerical methods never form the characteristic polynomial; instead they work with the matrix itself, using operations that keep errors small. In fact, the reverse is true: library routines find the roots of a polynomial by computing the eigenvalues of a matrix built from its coefficients.
Power iteration
The simplest method repeatedly multiplies a starting vector by A and normalizes:
To see why this works, write the starting vector as a combination of eigenvectors, \(\mathbf{x}_0 = c_1\mathbf{v}_1 + c_2\mathbf{v}_2 + \cdots\). After k multiplications the components have been scaled by \(\lambda_1^k, \lambda_2^k, \ldots\). If \(|\lambda_1|\) is strictly the largest, its component dominates, and \(\mathbf{x}_k\) turns toward \(\mathbf{v}_1\). The error shrinks by a factor of about \(|\lambda_2/\lambda_1|\) at each step, so convergence is fast when the dominant eigenvalue is well separated and slow when it is not.
The best estimate of the eigenvalue from an approximate eigenvector is the Rayleigh quotient:
For a symmetric matrix, its error is proportional to the square of the error in the vector, so it converges twice as fast as the vector does.
Worked problem
Power iteration by hand
Apply three steps of power iteration to \(A = \begin{pmatrix} 2 & 1 \\ 1 & 3 \end{pmatrix}\), starting from (1, 1), estimating the eigenvalue with the Rayleigh quotient each time.
Show solution
- Exact eigenvalues: \((5 \pm \sqrt{5})/2 = 3.618\) and \(1.382\).
- \(\mathbf{x}_0 = (1, 1)\): \(A\mathbf{x}_0 = (3, 4)\), \(r = 7/2 = 3.5\).
- \(\mathbf{x}_1 \propto (3, 4)\): \(A\mathbf{x}_1 = (10, 15)\), \(r = (30 + 60)/25 = 3.6\).
- \(\mathbf{x}_2 \propto (10, 15)\): \(A\mathbf{x}_2 = (35, 55)\), \(r = (350 + 825)/325 = 3.6154\).
Answer: The estimates 3.5, 3.6, 3.6154 approach 3.618, with the error falling by a factor of about (1.382/3.618)² ≈ 0.15 each step. Normalization (not needed by hand here) keeps the numbers from overflowing.
Power iteration needs only matrix-vector products, so it works for enormous sparse matrices. Google's original PageRank computed the dominant eigenvector of a matrix describing links among billions of web pages in exactly this way. Its weakness is that it finds only the largest eigenvalue, while engineers usually want the smallest: the fundamental frequency or the lowest buckling load.
Inverse iteration and shifts
The eigenvalues of \(A^{-1}\) are \(1/\lambda_i\), with the same eigenvectors, so power iteration applied to \(A^{-1}\) finds the eigenvalue of A closest to zero. More generally, the eigenvalues of \((A - \sigma I)^{-1}\) are \(1/(\lambda_i - \sigma)\), so power iteration with this matrix finds the eigenvalue closest to the shift σ, and converges at the rate \(|\lambda_{near} - \sigma|/|\lambda_{next} - \sigma|\), which can be made very small with a good shift. The inverse is never formed: each step solves \((A - \sigma I)\mathbf{y} = \mathbf{x}_k\), using an LU factorization (Lesson 3) computed once and reused, so each step costs only a forward and back substitution.
Updating the shift at every step to the latest Rayleigh quotient gives Rayleigh quotient iteration, which for symmetric matrices converges cubically: the number of correct digits roughly triples each step, at the cost of refactoring the matrix each time.
import numpy as np
from scipy.linalg import eigh, lu_factor, lu_solve
# Ten-storey shear building: floor mass 50 t, storey stiffness 40 MN/m
n, m, k = 10, 50e3, 40e6
K = np.zeros((n, n))
for i in range(n):
K[i, i] = 2 * k if i < n - 1 else k
if i > 0:
K[i, i - 1] = K[i - 1, i] = -k
A = K / m # equal masses, so K phi = w^2 M phi becomes A phi = w^2 phi
def power(A, iters):
x = np.ones(len(A))
for _ in range(iters):
x = A @ x
x = x / np.linalg.norm(x)
return x @ A @ x, x
def inverse(A, shift, iters):
lu = lu_factor(A - shift * np.eye(len(A))) # factor once, reuse every step
x = np.ones(len(A))
for _ in range(iters):
x = lu_solve(lu, x)
x = x / np.linalg.norm(x)
return x @ A @ x, x
hz = lambda lam: np.sqrt(lam) / (2 * np.pi)
lam_all = eigh(A, eigvals_only=True)
print("Exact (eigh): f1 = %.4f Hz, f2 = %.4f Hz, f10 = %.3f Hz" % (hz(lam_all[0]), hz(lam_all[1]), hz(lam_all[-1])))
for it in [5, 20, 100]:
lam, _ = power(A, it)
print(f"Power, {it:3d} steps: highest f = {hz(lam):.3f} Hz")
for it in [3, 10]:
lam, x = inverse(A, 0.0, it)
print(f"Inverse, {it:2d} steps: lowest f = {hz(lam):.4f} Hz")
lam, x = inverse(A, (2 * np.pi * 1.9)**2, 5)
print(f"Shifted inverse near 1.9 Hz, 5 steps: f = {hz(lam):.4f} Hz")Exact (eigh): f1 = 0.6728 Hz, f2 = 2.0034 Hz, f10 = 8.903 Hz Power, 5 steps: highest f = 8.367 Hz Power, 20 steps: highest f = 8.836 Hz Power, 100 steps: highest f = 8.903 Hz Inverse, 3 steps: lowest f = 0.6728 Hz Inverse, 10 steps: lowest f = 0.6728 Hz Shifted inverse near 1.9 Hz, 5 steps: f = 2.0034 Hz
Power iteration needs about 100 steps for the highest frequency, because the top two eigenvalues are close; inverse iteration finds the fundamental frequency, 0.673 Hz, in three steps, and a shift near 1.9 Hz picks out the second mode just as quickly. Structural engineers care most about the lowest few modes, which dominate earthquake and wind response, so shifted inverse methods are the workhorses of structural dynamics.
The QR algorithm
To find all the eigenvalues of a dense matrix, libraries such as LAPACK (used by NumPy, MATLAB and others) use the QR algorithm. Factor \(A_0 = A\) as \(A_0 = Q_0R_0\), with Q orthogonal and R upper triangular (MATH-125), then multiply in the reverse order: \(A_1 = R_0Q_0\). Since \(A_1 = Q_0^TA_0Q_0\), it has the same eigenvalues. Repeating, the matrices \(A_k\) converge (under mild conditions) to an upper triangular matrix, with the eigenvalues appearing on the diagonal. The practical algorithm adds three refinements that make it fast and reliable:
- First reduce A to Hessenberg form (zeros below the first subdiagonal), or tridiagonal form if A is symmetric, using orthogonal transformations. Each QR step then costs \(O(n^2)\) instead of \(O(n^3)\).
- Use shifts, \(A_k - \sigma_kI = Q_kR_k\), \(A_{k+1} = R_kQ_k + \sigma_kI\), chosen from the bottom corner of the matrix, so that each eigenvalue converges in two or three steps.
- Deflate: once a subdiagonal entry is negligible, split the problem and continue on the smaller pieces.
The whole process costs about \(10n^3\) operations for all eigenvalues and eigenvectors of a general matrix, fewer for a symmetric one. A 1000 × 1000 problem takes well under a second on a laptop; a 100 000 × 100 000 dense problem would take days and 80 GB of memory, which is why large problems use the methods below.
Symmetric and generalized problems
Most engineering eigenvalue problems are symmetric, because stiffness and mass matrices, covariance matrices and stress tensors are symmetric. Symmetric problems are easier and better behaved: the eigenvalues are real, the eigenvectors can be chosen orthogonal, and the eigenvalues are well conditioned, meaning that a perturbation of size ε in the matrix moves each eigenvalue by at most ε. Use the routines for symmetric matrices (numpy.linalg.eigh or scipy.linalg.eigh) rather than the general ones; they are faster and guarantee real results.
Vibration problems usually come in generalized form, \(K\boldsymbol{\phi} = \omega^2M\boldsymbol{\phi}\). It is tempting to form \(M^{-1}K\), but that matrix is not symmetric. Instead, solvers either pass both matrices to a generalized routine (scipy.linalg.eigh(K, M)) or use a Cholesky factorization \(M = LL^T\) to convert the problem to a standard symmetric one.
Worked problem
A sensitive non-symmetric matrix
Compare the eigenvalues of \(A = \begin{pmatrix} 1 & 1 \\ 0 & 1 \end{pmatrix}\) and \(A_\varepsilon = \begin{pmatrix} 1 & 1 \\ \varepsilon & 1 \end{pmatrix}\) for ε = 10⁻¹⁰.
Show solution
- A has the double eigenvalue 1.
- For \(A_\varepsilon\): \((1 - \lambda)^2 = \varepsilon\), so \(\lambda = 1 \pm \sqrt{\varepsilon} = 1 \pm 10^{-5}\).
Answer: A perturbation of 10⁻¹⁰ moved the eigenvalues by 10⁻⁵, a hundred thousand times more. Non-symmetric matrices with nearly repeated eigenvalues can be very sensitive, so computed eigenvalues of such matrices (from control and stability analysis) should be checked, for example by perturbing the data. Symmetric matrices never behave like this.
Large sparse problems
A finite element model of a car body or an aircraft may have millions of unknowns, but its matrices are sparse, and only the lowest few dozen modes are needed. Krylov subspace methods (Lanczos for symmetric matrices, Arnoldi for general ones) build a small basis from the vectors \(\mathbf{x}, A\mathbf{x}, A^2\mathbf{x}, \ldots\), whose span captures the extreme eigenvalues remarkably well, and solve a small eigenvalue problem within it. Combined with the shift-and-invert idea, so that the eigenvalues near a chosen σ become the extreme ones, they find the lowest modes of enormous models efficiently. In Python this is scipy.sparse.linalg.eigsh, which wraps the ARPACK library used by many commercial programs.
Checking computed eigenvalues
A computed pair \((\lambda, \mathbf{x})\) can always be checked through its residual, \(\|A\mathbf{x} - \lambda\mathbf{x}\|/\|\mathbf{x}\|\). For a symmetric matrix, a small residual guarantees that some true eigenvalue lies within that distance of λ. Further checks come from physics: the sum of the eigenvalues equals the trace of A; mode shapes should be orthogonal with respect to the mass matrix; the lowest frequency should be consistent with a simple hand estimate; and refining a finite element mesh should change the lowest frequencies only slightly.
Common mistakes
MistakeFinding eigenvalues by solving the characteristic polynomial numerically.
InsteadUse a library eigenvalue routine; polynomial roots are badly conditioned.
MistakeUsing power iteration to find the fundamental frequency.
InsteadPower iteration finds the largest eigenvalue; use inverse iteration or shift-and-invert.
MistakeForming the inverse matrix for inverse iteration.
InsteadFactor A − σI once and solve with it at each step.
MistakeForming M⁻¹K for a vibration problem.
InsteadUse a generalized symmetric solver, eigh(K, M).
MistakeTrusting eigenvalues of non-symmetric matrices without checks.
InsteadCheck residuals and sensitivity; nearly repeated eigenvalues can be very sensitive.
Summary and key terms
- Never compute eigenvalues from the characteristic polynomial; its roots are badly conditioned.
- Power iteration finds the dominant eigenvalue, converging at rate |λ₂/λ₁|.
- The Rayleigh quotient xᵀAx/xᵀx gives an accurate eigenvalue estimate from an approximate eigenvector.
- Inverse iteration with shift σ finds the eigenvalue nearest σ, reusing one LU factorization.
- The QR algorithm, with Hessenberg reduction, shifts and deflation, computes all eigenvalues in O(n³).
- Symmetric problems are well conditioned; use symmetric and generalized solvers such as eigh(K, M).
- Large sparse problems use Lanczos or Arnoldi methods with shift-and-invert to find a few modes.
- Power iteration
- Repeated multiplication by A and normalization, converging to the dominant eigenvector.
- Dominant eigenvalue
- The eigenvalue of largest magnitude.
- Rayleigh quotient
- xᵀAx/xᵀx, an eigenvalue estimate for a vector x.
- Inverse iteration
- Power iteration with (A − σI)⁻¹, finding the eigenvalue nearest σ.
- Shift
- A value σ subtracted from the diagonal to target eigenvalues near it.
- QR algorithm
- Iterating A = QR, A ← RQ to converge to a triangular matrix with the eigenvalues on its diagonal.
- Hessenberg form
- A matrix with zeros below the first subdiagonal.
- Deflation
- Splitting off converged eigenvalues to reduce the problem size.
- Generalized eigenvalue problem
- Kφ = λMφ with two matrices.
- Krylov subspace
- The span of x, Ax, A²x, …, used by Lanczos and Arnoldi methods.
Practice problems
Work each problem on paper first, then reveal the answer to check.
Find the Rayleigh quotient of x = (1, 0) for A = [[4, 1], [1, 2]].
Show answer
4.
A matrix has eigenvalues 10, 9 and 1. How fast does power iteration converge?
Show answer
Error shrinks by 0.9 per step, slowly.
For the same matrix, inverse iteration with σ = 0 converges at what rate?
Show answer
|1 − 0|/|9 − 0| = 0.11 per step, toward λ = 1.
What shift would make inverse iteration converge fastest to λ = 9?
Show answer
A shift close to 9, such as 8.9 (rate 0.1/1.1 ≈ 0.09, better closer).
Why is the inverse never formed in inverse iteration?
Show answer
Solving with an LU factorization is cheaper and more accurate.
One step of power iteration on A = [[0, 1], [1, 0]] from (1, 0) gives what? Will it converge?
Show answer
(0, 1); no, eigenvalues ±1 have equal magnitude so it alternates.
What do A₀ and A₁ = R₀Q₀ in the QR algorithm have in common?
Show answer
The same eigenvalues (they are similar).
Check: A = [[2, 1], [1, 3]] has eigenvalues summing to what?
Show answer
The trace, 5.
A symmetric matrix is perturbed by 10⁻⁸. At most how far can an eigenvalue move?
Show answer
By 10⁻⁸ (in the matrix 2-norm).
Which SciPy routine finds the 10 lowest modes of a large sparse K and M?
Show answer
scipy.sparse.linalg.eigsh with shift-and-invert (sigma near 0).
Lesson quiz · 5 questions
Score 60% or more to complete this lesson.
Create a free account to save your progress, take quizzes and earn a certificate.