Lanczos ↔ continued fractions (cycling reader)
Cycling
A document in the cycling-rephrasings format: each paragraph below has multiple framings of the same claim. The default view shows one framing per paragraph; click any paragraph to cycle to another framing of its claim. The outline view (top button) hides all bodies and shows the argument's skeleton — the overview sequence — for fast skimming. Each card has a copy button (top-right) that grabs the framing you're currently looking at.
Worked out: from a matrix you can check to the Padé connection
The framings above state the identity in general. General is where the one fact that makes this useful goes to hide, so here it is on real numbers — first an invented matrix small enough to check by hand, then a bigger one where the truncated chain becomes a Padé approximant, which is the entire reason anyone runs Lanczos in the first place. Every number below is from actually running the algorithm.
1. An invented 3×3, full chain — the mechanics, and the trap
Take a dense symmetric matrix (dense, so it is genuinely not tridiagonal — Lanczos has to do real work) and the starting vector :
import numpy as np
def lanczos(A, v0, m): # symmetric A, start vector v0, m steps
n = len(v0); V = np.zeros((n, m)); a = np.zeros(m); b = np.zeros(m)
V[:, 0] = v0 / np.linalg.norm(v0); bprev = 0.0; vprev = np.zeros(n)
for j in range(m):
w = A @ V[:, j]; a[j] = V[:, j] @ w # alpha_j = <v_j|A|v_j>
w = w - a[j]*V[:, j] - bprev*vprev # three-term recurrence
for k in range(j): w -= (V[:, k] @ w) * V[:, k] # reorthogonalize
b[j] = np.linalg.norm(w) # beta_j = <v_{j+1}|A|v_j>
if b[j] < 1e-12 or j == m-1: break
vprev = V[:, j]; bprev = b[j]; V[:, j+1] = w / b[j]
return a, b
def cf(a, b, z, n): # n-level continued fraction, bottom-up
f = z - a[n-1]
for j in range(n-2, -1, -1):
f = (z - a[j]) - b[j]**2 / f
return 1.0 / f A = np.array([[2., 1, 1], [1, 3, 1], [1, 1, 4]]) # dense, NOT tridiagonal
v0 = np.array([1., 0, 0])
a, b = lanczos(A, v0, 3)
print("alpha =", a) # [2. 4.5 2.5 ] <- real Lanczos output
print("beta =", b[:2]) # [1.4142 0.5 ] = (sqrt 2, 1/2)
print("CF_3(6) =", cf(a, b, 6, 3)) # 0.3846153846
print("exact =", v0 @ np.linalg.solve(6*np.eye(3)-A, v0)) # 0.3846153846 Lanczos hands back and — these are computed, not chosen. Feed them into the three-level continued fraction (, ):
Evaluate at , bottom up: ; then ; then ; so . The direct resolvent is also . They agree exactly.
And that exactness is the trap. The chain ran to , so of course the continued fraction equals the resolvent — at full length it's just Cramer's rule written sideways. A full-dimension Lanczos run reproduces the resolvent identically and approximates nothing. Nothing here is worth the trouble. The trouble only pays off when .
2. A bigger matrix, truncated chain — the [n−1/n] Padé approximant
Let's apply this to something concrete, an 8×8 random symmetric matrix with a random unit starting vector . The resolvent at gives us the exact answer to check against — — and Lanczos now lets us evaluate the truncated continued fraction at each chain length:
rng = np.random.default_rng(3); N = 8
M = rng.standard_normal((N, N)); A = (M + M.T) / 2 # random symmetric 8x8
v0 = rng.standard_normal(N); v0 /= np.linalg.norm(v0)
a, b = lanczos(A, v0, N)
exact = v0 @ np.linalg.solve(6*np.eye(N) - A, v0) # 0.173892043148
for n in range(1, N+1):
print(n, cf(a, b, 6, n), abs(cf(a, b, 6, n) - exact)) n CF_n(6) |CF_n - exact|
1 0.148050615223 2.58e-02
2 0.167297739854 6.59e-03
3 0.170822791951 3.07e-03 <- [2/3] Pade from 3 Lanczos steps
4 0.173469327962 4.23e-04
5 0.173885545845 6.50e-06
6 0.173891769274 2.74e-07
7 0.173892043101 4.65e-11
8 0.173892043148 2.78e-17 <- n = dim: exact, machine precision
This is the content. Each truncated continued fraction is a rational function of degree over degree — the Padé approximant of the resolvent. Three Lanczos steps give a approximant already good to three digits; at it collapses onto the exact value at machine precision. Short chain, cheap approximation; full chain, exact. That is why you run a handful of Lanczos steps on a million-dimensional operator and read off a rational function instead of inverting anything — the 3×3-run-to-completion never shows you this, because it has no "short chain" to truncate.
3. Why Lanczos steps are the Padé approximant
The connection is the part that's genuinely hard to find stated plainly, so here it is in one chain of equalities. The resolvent is the moment-generating function of 's spectral measure (the measure that puts weight at each eigenvalue of ):
The are the moments of . Now three facts line up:
- The Padé approximant of a power series is, by definition, the unique rational function (degree over degree ) whose own series matches the first coefficients.
- The -level Lanczos continued fraction is the Stieltjes transform of the -point Gauss quadrature rule for — its nodes are the eigenvalues of the tridiagonal (the Ritz values), its weights the squared first components of 's eigenvectors.
- -point Gauss quadrature is exact for polynomials up to degree , so it reproduces the first moments of exactly.
Put them together: the -level Lanczos continued fraction is a degree- rational function matching the first moments of — which is exactly the Padé approximant. Lanczos coefficients = Gauss-quadrature rule = Padé approximant. Three names for one object, and the reason a 1950s numerical algorithm reproduces a 1890s moment-problem theorem.
Checked on the 8×8: at the continued fraction reproduces the first moments and first diverges from the truth at — the difference between and the six-moment sum shrinks like as grows ( at , at ), precisely the "first unmatched moment is the 7th" signature of a six-moment match. The Padé is matching six moments, on the nose.
It's not a coincidence: the classical orthogonal polynomials are Lanczos
Everything above secretly lives in one classical theory — orthogonal polynomials on the real line. Recall the spectral measure of (weight at each eigenvalue). That measure has its own family of orthogonal polynomials , the ones obeying . Every such family satisfies a three-term recurrence,
and the coefficients of that recurrence are exactly the entries of the Jacobi (tridiagonal) matrix — which is to say, exactly what Lanczos hands back. So Lanczos is the algorithm that generates the orthogonal polynomials of 's spectral measure. The continued fraction is their Stieltjes transform, the Gauss quadrature is their roots-and-weights rule, the Padé approximant is their moment match. One structure, four names.
Which means the famous orthogonal polynomial families aren't separate objects to memorize — each is just Lanczos run on a classical weight. Take the multiplication-by- operator with weight , start from , and the 's and 's that come out are the textbook recurrence coefficients:
# Run Lanczos on "multiply by x" with a classical weight w(x); out come the
# recurrence coefficients of THAT weight's orthogonal polynomials. The starting
# vector v0 = sqrt(weights) makes v0's spectral measure equal the weighted measure.
def recover(nodes, weights, m=6):
return lanczos(nodes, np.sqrt(weights), m)
# Legendre: weight 1 on [-1,1]
x = np.linspace(-1, 1, 20000); a, b = recover(x, np.full(20000, 2/20000))
print("Legendre beta:", b[:5], " vs n/sqrt(4n^2-1)")
# Chebyshev (1st): weight 1/sqrt(1-x^2)
xc = np.cos((np.arange(4000)+0.5)*np.pi/4000); a, b = recover(xc, np.full(4000, np.pi/4000))
print("Chebyshev beta:", b[:5], " vs 1/sqrt2 then 1/2, 1/2, ...")
# Hermite: weight e^{-x^2}
xh, wh = np.polynomial.hermite.hermgauss(60); a, b = recover(xh, wh)
print("Hermite beta:", b[:5], " vs sqrt(n/2)")
# Laguerre: weight e^{-x} on [0, inf)
xl, wl = np.polynomial.laguerre.laggauss(60); a, b = recover(xl, wl)
print("Laguerre alpha:", a[:5], " beta:", b[:5], " vs 2n+1 and n") Legendre beta: [0.5774 0.5164 0.5071 0.5040 0.5025] vs n/sqrt(4n^2-1)
Chebyshev beta: [0.7071 0.5 0.5 0.5 0.5 ] vs 1/sqrt2 then 1/2, 1/2, ...
Hermite beta: [0.7071 1. 1.2247 1.4142 1.5811] vs sqrt(n/2)
Laguerre alpha: [1. 3. 5. 7. 9.] beta: [1. 2. 3. 4. 5.] vs 2n+1 and n Every one matches its textbook formula — Legendre's , Chebyshev's , Hermite's , Laguerre's diagonal and off-diagonal — recovered by running the same Lanczos routine from the top of this page on the right measure. The classical families are the special cases where the measure happens to be a classical weight; the named Gauss quadratures are the same Jacobi-matrix eigenproblem (Golub-Welsch):
| family | weight | interval | Jacobi off-diagonals | quadrature |
|---|---|---|---|---|
| Legendre | Gauss-Legendre | |||
| Chebyshev (1st) | Gauss-Chebyshev | |||
| Hermite | Gauss-Hermite | |||
| Laguerre | (diag ) | Gauss-Laguerre | ||
| Jacobi | (closed form in ) | Gauss-Jacobi |
Watch the matrix collapse to tridiagonal
The recovery above runs Lanczos and reads off the 's. But you can see why the matrix is tridiagonal in the first place without running Lanczos at all. Build the orthonormal polynomials of a weight by plain Gram-Schmidt, then fill in the multiplication-by- matrix by quadrature — using none of the recurrence coefficients, so the structure is an output. Every entry more than one step off the diagonal comes back as machine zero. Pick a column to see what multiplication by does to a single basis polynomial: it can only reach one degree up, and self-adjointness kills everything more than one degree down.
Build the orthonormal polynomials of the Legendre weight by Gram–Schmidt, then fill the matrix M[i][j] = ⟨P̃ᵢ, x·P̃ⱼ⟩ by quadrature — no recurrence coefficients used. Click a column to see what multiplying by x does to that basis polynomial.
Only P̃1, P̃2 and P̃3 survive. Multiplying by x raises the degree to 3 (so nothing above P̃3), and orthogonality kills everything below P̃1: ⟨x·P̃2, P̃m⟩ = ⟨P̃2, x·P̃m⟩, and x·P̃m has degree m+1 < 2 whenever m < 1. Three terms, forced.
Everything more than one step off the diagonal came out ≈0 (≤ 10⁻¹³, the quadrature floor) — computed, not assumed. The off-diagonal band you do see is the Lanczos β sequence: for Legendre that's the textbook recurrence coefficient. Symmetric, because multiplication by the real variable x is self-adjoint; tridiagonal, because x raises degree by exactly one. Run Lanczos on this measure and these same numbers fall out.
Two facts are doing all the work. Multiplication by is self-adjoint — , because is real and slides across the integral with no conjugate — so is symmetric. And has degree , so it is orthogonal to every with ; symmetry then forces the mirror zeros below . A symmetric matrix that vanishes outside the first off-diagonal is exactly a tridiagonal one — a three-term recurrence. The Jacobi matrix isn't a lucky shape; it's the only shape these two facts allow.
The converse closes the loop. Favard's theorem (1935): any sequence obeying that three-term recurrence with real is the orthogonal-polynomial family of some positive measure. So the correspondence is a clean bijection,
and Lanczos is the constructive direction: hand it an operator and a vector, it builds the Jacobi matrix, which is a measure's orthogonal polynomials. Run it on a textbook weight and you get Legendre or Hermite; run it on a quantum Hamiltonian and a state, you get the bespoke orthogonal polynomials of that system's spectral density — and their continued fraction is the resolvent, their Gauss rule is the spectral-density approximation, their Padé is the moment match. Stieltjes (1894), Favard (1935), Gauss quadrature, Lanczos (1950), and the continued fraction at the top of this page are all the same theorem about the same object. Not a coincidence — just the moment problem, seen from five directions.
Related on this site
- Lanczos iteration — the algorithm that produces the α's and β's.
- Padé via Lanczos — the same correspondence put to work in model-order reduction.
- Padé approximants — what [m/n] means and where it comes from.
- Legendre polynomials — one of the classical families that falls out of Lanczos on a flat weight.
- Chebyshev nodes — Gauss-Chebyshev quadrature, the same Jacobi-matrix eigenproblem.
- Obara-Saika — the same three-term recurrence in quantum chemistry: the Gaussian-integral angular-momentum ladder is the Hermite recurrence.