Linear Response Theory
Perturbation Methods
What you need to know first 7 concepts, 4 layers
The requisite-knowledge inventory for this page, bottom-up: the primitives at the base, combined upward until you reach what this page assumes. Skim the layers you already own; start wherever the ground gets unfamiliar.
- base
- Linear algebraconcept
- Quantum mechanics (states & operators)
- L1
- Matrix eigenvalue problems
- Perturbation theory
- The eigenvalue problem (Ax = λx)concept
- L2
- L3
- ↳you are here
2 of these are concepts without a dedicated page yet — the grey chips. Following the linked ones first makes the rest land.
Kick a system gently and watch what comes back. The response is not mush — it rings, and it rings only at the system's own transition frequencies. Linear response theory is the bookkeeping for that fact: one function whose poles are the excitation energies and whose residues are how brightly each one couples to your probe. Every spectroscopy is a rediscovery of this sentence, and Casida's equation is what it turns into for molecules. Five ways in; read the one that lands.
Strike a bell once and it does not hum at the frequency of your mallet — it rings at its own frequencies, the ones fixed by its geometry before you ever walked up to it. Record the ring, Fourier transform it, and you have measured the bell's spectrum without ever solving for a single vibrational mode.
Quantum systems play the same game. Give the ground state a sudden weak kick (in the code below, literally multiply by and let it evolve) and the observable oscillates as a superposition of pure tones — one per excited state the kick can reach, each at exactly . The spectrum was sitting in the dynamics the whole time. Linear response theory is the guarantee that the ring you record and the eigenvalues you would have computed are the same information.
You already know time-independent perturbation theory: add to the Hamiltonian, expand the energy in powers of , keep the first term. Linear response is the same discipline applied to a time-dependent perturbation — a field coupling to an observable — and instead of asking "how does the energy shift?" you ask "how does the expectation value move?"
To first order in the field, the answer is a convolution:
That second equation is the Kubo formula. Two things to notice. The response kernel is a pure ground-state expectation value — the field's job is only to expose it, which is why a weak kick and a strong theory suffice. And the step function enforces causality: the system responds after you poke it, not before. Fourier transforming a causal function is exactly what plants the poles of just below the real axis, at .
Take the Kubo commutator, insert a complete set of eigenstates between the two operators, and Fourier transform. Every trace of the dynamics collapses into eigenvalue differences and matrix elements:
This is the Lehmann representation, and it is the theorem the whole page orbits: blows up precisely at , and the strength of each blow-up is . Poles are positions of spectral lines; residues are their intensities. A state with is invisible — a dark state — no matter how legitimately it sits in the spectrum of .
The two terms are time-reversal partners: absorption at and stimulated emission at . They travel together, always. When this structure gets rebuilt in a finite orbital basis, that pairing becomes the doubling and the matrix of Casida's equation.
Group the denominators differently and the sum over states is secretly one object. Define the shifted resolvent and the whole sum collapses to
Read it right to left: hit the ground state with the probe ( is the "kicked" vector), feed it to the resolvent — which amplifies whatever eigencomponents lie near — and project back. The response function is a single matrix element of .
This framing is the computational escape hatch. You never need every eigenstate of — you need one matrix element of an inverse, and that is a Krylov problem: run Lanczos on the kicked vector and read the response off the tridiagonal matrix. That is precisely the trick Liouville-Lanczos TDDFT plays when the Casida matrix is too big to build.
An absorption spectrometer sweeps a weak monochromatic field across frequencies and records how much power the sample eats at each one. In linear response language, absorbed power is proportional to — the imaginary part is the dissipative part. Plot and you are looking at the spectrum as the instrument sees it: a Lorentzian line per pole, centered at , with integrated area .
This is the contract between theory and experiment. The experimentalist reports line positions and intensities; the theorist computes eigenvalue differences and transition matrix elements; linear response theory is the statement that these are the same two lists. For a molecule the probe is the dipole operator, the reference is a Kohn-Sham ground state, and the machine that produces the pole list without ever constructing an excited-state wavefunction is Casida's equation. Everything on that page is this page, rebuilt in an orbital basis.
One formula, three altitudes
The sum-over-states formula, with real orbitals and the two time-reversal terms combined over a common denominator:
Now bring it down to earth. For a two-level system — one ground state, one bright excited state at gap — the sum has a single term:
Set and you get the static polarizability — push gently and constantly, and the system leans by that much per unit force. Sweep up toward and the denominator heads for zero: resonance. Past it, the sign flips and the response lags the drive. One pole, and already the whole phenomenology of a driven oscillator.
Finally, real numbers from a real Hamiltonian. Take the quartic anharmonic oscillator — same conventions as the resummation pages — and diagonalize it in a 120-function basis (the script below; levels converged to ). The bright poles of come out
and the single-pole approximation of the formula above becomes , giving a static polarizability of — within of the full answer , because the higher poles are 1,700 and 2,000,000 times dimmer. At the same machinery returns exactly one pole at with , so — the classical Lorentz oscillator, and is just Hooke's law with . The quantum formula knows classical mechanics when the potential is quadratic.
Watch the poles, on real numbers
Every curve below is assembled from the exact poles and residues printed by the validation script — nothing is synthesized at runtime except the Lorentzian broadening, which is the same that damps the time signal in the code. Switch the anharmonicity, then drag down and watch the peaks sharpen toward delta functions parked at the excitation energies.
Exact poles for λ = 0.1: ω = 1.2104 (strength 0.4123) · ω = 4.0697 (strength 2.4e-4). Each peak height is strength/η — shrink η and the peaks march toward delta functions parked at the poles.
Three things to read off. First, the harmonic oscillator shows one line — out of infinitely many excited states, only is bright, because only reaches one rung up the ladder. Second, turning on anharmonicity does two separate things: it shifts the main line (from to at , to at ) and it switches on a new line at — a transition that was exactly dark by the harmonic selection rule, now allowed at three orders of magnitude down. Third, the linewidth is not a property of the system at all: it is , your resolution. The poles underneath are infinitely sharp; a finite observation window (or a finite excited-state lifetime, in a real molecule) is what smears them.
Two ways to compute it — and why they must agree
The claim "poles of the response ARE the excitation energies" deserves a numerical cross-examination, so the script computes twice with no shared machinery. Way one is the Lehmann formula: diagonalize, read off and , sum the fractions.
import numpy as np
# H = p^2/2 + x^2/2 + lam x^4 in a harmonic-oscillator basis (hbar = m = 1)
def aho_eigen(lam, nbasis=120):
n = np.arange(nbasis)
x = np.zeros((nbasis, nbasis))
off = np.sqrt((n[:-1] + 1) / 2.0) # <n|x|n+1> = sqrt((n+1)/2)
x[n[:-1], n[:-1] + 1] = off
x[n[:-1] + 1, n[:-1]] = off
H = np.diag(n + 0.5) + lam * np.linalg.matrix_power(x, 4)
E, U = np.linalg.eigh(H)
return E, U.T @ x @ U # energies, x in the eigenbasis
E, x_eig = aho_eigen(lam=0.1)
w = E[1:] - E[0] # poles: excitation energies
s = x_eig[0, 1:] ** 2 # residues: |<n|x|0>|^2
def chi_sos(omega, eta=0.05): # the sum-over-states formula
return np.sum(s * 2 * w / (w**2 - (omega + 1j * eta)**2)) Way two never sees an eigensolver. Cool a Gaussian to the ground state in imaginary time, kick it with , propagate on a grid with the split-operator method, record , and Fourier transform the transient. First-order perturbation theory in says the kicked signal is the response kernel: — so its transform must land on the same poles.
# Independent check: no eigensolver anywhere. Ground state by imaginary
# time, then a delta-kick exp(i kappa x), then split-operator propagation.
xs = np.linspace(-L, L, N, endpoint=False); dx = xs[1] - xs[0]
k = 2 * np.pi * np.fft.fftfreq(N, d=dx)
V = 0.5 * xs**2 + lam * xs**4
psi = np.exp(-xs**2 / 2).astype(complex) # imaginary time: cool to |0>
eV, eT = np.exp(-V * dt / 2), np.exp(-0.5 * k**2 * dt)
for _ in range(20000):
psi = eV * np.fft.ifft(eT * np.fft.fft(eV * psi))
psi /= np.sqrt(np.sum(np.abs(psi)**2) * dx)
psi = np.exp(1j * kappa * xs) * psi # the kick, kappa = 1e-3
expV = np.exp(-1j * V * dt / 2) # real time: listen
expT = np.exp(-1j * 0.5 * k**2 * dt)
sig = []
for j in range(int(T / dt)): # T = 400, dt = 0.002
psi = expV * np.fft.ifft(expT * np.fft.fft(expV * psi))
sig.append(np.sum(xs * np.abs(psi)**2).real * dx)
# d<x(t)>/kappa is chi(t); a damped Fourier transform gives chi(omega)
resp = (np.array(sig) - 0.0) / kappa
chi_grid = fourier(resp * np.exp(-eta * t)) # e^{-eta t} <-> Lorentzian width They agree to six digits across the whole frequency window — the residual is the Trotter error of the propagator, not physics. The Thomas-Reiche-Kuhn sum rule holds to ten digits for both values of , and the harmonic limit recovers its single exact pole. (The grid run's weight for the weak line reads high — against the exact — because at the peak sits on the Lorentzian tail of a line 1,700 times brighter. Shrink in the demo and watch that contamination die.)
basis convergence (lam=0.1): max |E_80 - E_120| over first 8 levels = 4.37e-13
lam = 0.0: E0 = 0.500000
poles (sum over states):
w = 1.000000 |<n|x|0>|^2 = 5.000000e-01
TRK sum rule sum w_n s_n = 0.5000000000 (exact: 0.5)
grid vs sum-over-states: max relative deviation of chi(w) = 4.12e-06
peaks found in the grid spectrum:
w = 1.0000 weight = 4.996346e-01
lam = 0.1: E0 = 0.559146
poles (sum over states):
w = 1.210356 |<n|x|0>|^2 = 4.122817e-01
w = 4.069736 |<n|x|0>|^2 = 2.434491e-04
w = 7.340621 |<n|x|0>|^2 = 1.956422e-07
TRK sum rule sum w_n s_n = 0.5000000000 (exact: 0.5)
grid vs sum-over-states: max relative deviation of chi(w) = 6.20e-06
peaks found in the grid spectrum:
w = 1.2104 weight = 4.121054e-01
w = 4.0694 weight = 3.324795e-04
Full script: scripts/gen_linear_response.py. Everything above
— poles, strengths, both spectra, the sum rule — is its verbatim output.
Try First
Each prompt asks a checkable question about the working code or math above — predict an output, derive a sign, state an invariant, find a bug. Commit to an answer before clicking "reveal." That commitment is the whole point: if your answer matched, you understand the piece you were looking at; if it didn't, that's the part worth re-reading.
Where this goes
Everything downstream of this page is a change of arena, not of idea. Swap for the dipole operator and for a Kohn-Sham ground state, and demanding that the density response be consistent with the response of the exchange-correlation potential turns the pole condition into a matrix eigenproblem in the space of occupied→virtual orbital pairs — that is Casida's equation, and its two-block structure is the absorption/emission pairing from the Lehmann representation. When that matrix is too large to build, the resolvent framing takes over: kick, Lanczos, read the spectrum off a tridiagonal — Liouville-Lanczos. And the residues, dressed with a factor and summed against the TRK rule, become the oscillator strengths an experimental spectrum is plotted in.