Quant Memo
Advanced

The Matrix Condition Number

One number tells you whether solving a system of equations is safe or a numerical minefield: the condition number measures how much a matrix amplifies small errors, and a big one means your answer cannot be trusted.

Prerequisites: Eigenvalues & Eigenvectors, The Spectral Theorem for Symmetric Matrices, Singular Value Decomposition

You solve Ax=bAx=b on a computer and get an answer. Change bb by a tiny amount — a rounding error, a data revision, the sixth decimal place of a price — and the "same" system sometimes gives back almost the same xx, and sometimes gives back a wildly different xx. Same equations, same solving method, wildly different sensitivity to noise. There is a single number, computable directly from AA alone before you even touch bb, that tells you in advance which situation you're in: the condition number.

The analogy: a see-saw versus a hair trigger

Imagine two machines that both convert an input into an output. The first is a see-saw: push it a little, it moves a little. Push it more, it moves proportionally more. Predictable, forgiving of small mistakes in how hard you pushed. The second is a hair-trigger switch balanced on a knife-edge: the tiniest push in the wrong spot sends the output flying in a completely different direction. Both machines are "linear" in the loose sense that doubling the push roughly doubles some response, but one amplifies your imprecision gently and the other amplifies it catastrophically. A matrix AA, used to solve Ax=bAx=b, is exactly one of these two machines — and the condition number tells you, numerically, which one.

Writing it down

For a matrix AA, the condition number is the ratio of its largest to its smallest singular value (for a symmetric positive-definite matrix, singular values coincide with eigenvalues, so you can read "eigenvalue" throughout if that's more familiar):

κ(A)=σmax(A)σmin(A).\kappa(A) = \frac{\sigma_{\max}(A)}{\sigma_{\min}(A)} .

In words: the largest singular value measures the most a unit vector can be stretched by AA; the smallest measures the least it can be stretched (possibly nearly to zero). The ratio compares the biggest stretch to the smallest — a large ratio means the matrix treats different directions extremely unequally.

This connects directly to error amplification through a standard bound:

Δxxκ(A)Δbb.\frac{\|\Delta x\|}{\|x\|} \le \kappa(A)\,\frac{\|\Delta b\|}{\|b\|} .

In words: the relative error in your solution xx can be as large as the condition number times the relative error in your input bb. If κ(A)=10\kappa(A)=10, a 0.1% wobble in your data can become at most a 1% wobble in your answer — annoying but survivable. If κ(A)=10,000,000\kappa(A) = 10{,}000{,}000, that same 0.1% data wobble can blow up into a 100,000% error — your computed answer is numerical noise, not a real solution.

A useful mental shortcut: κ(A)\kappa(A) close to 1 (its theoretical minimum) means AA treats every direction almost equally — like a uniform stretch, or an outright rotation. κ(A)\kappa(A) in the millions means AA is nearly singular — nearly non-invertible — because σmin\sigma_{\min} is nearly zero, meaning some direction gets squashed almost to nothing, and inverting that squash means dividing by almost nothing.

Matrix explorer
dashed = before · solid = after
det 1.25trace 2.50λ 1.81, 0.69area scales by 1.25×

Push the transform toward a very flat, elongated ellipse. That elongation is a high condition number made visible — one axis long, one axis short, and the ratio of the two lengths is exactly κ(A)\kappa(A). A near-circle is well conditioned; a near-line-segment is the geometric picture of ill-conditioning.

kappa near 1 — safe kappa in the thousands — unstable
Same idea as before: a near-circular stretch treats every direction alike, so errors pass through undistorted. A nearly flat ellipse means one direction is stretched far more than another — the geometric signature of a large condition number and an unstable solve.

Worked example 1: two systems that look similar but aren't, by hand

Compare A1=(2001)A_1 = \begin{pmatrix}2&0\\0&1\end{pmatrix} and A2=(1.0001111)A_2 = \begin{pmatrix}1.0001 & 1\\1 & 1\end{pmatrix}.

For A1A_1, it's diagonal, so singular values are just the diagonal entries: σmax=2\sigma_{\max}=2, σmin=1\sigma_{\min}=1, giving κ(A1)=2\kappa(A_1)=2. Perfectly tame.

For A2A_2, find eigenvalues (symmetric, so eigenvalues = singular values here): det(A2λI)=(1.0001λ)(1λ)1=0\det(A_2-\lambda I) = (1.0001-\lambda)(1-\lambda)-1 = 0. Expand: λ22.0001λ+(1.00011)=λ22.0001λ+0.0001=0\lambda^2 - 2.0001\lambda + (1.0001-1) = \lambda^2-2.0001\lambda+0.0001=0. By the quadratic formula, λ=2.0001±2.000120.00042=2.0001±4.00040.00042=2.0001±2.00002\lambda = \frac{2.0001 \pm \sqrt{2.0001^2 - 0.0004}}{2} = \frac{2.0001\pm\sqrt{4.0004-0.0004}}{2}=\frac{2.0001\pm 2.0000}{2}. That gives λ12.00005\lambda_1 \approx 2.00005 and λ20.00005\lambda_2\approx 0.00005. So κ(A2)2.00005/0.0000540,000\kappa(A_2) \approx 2.00005/0.00005 \approx 40{,}000.

Both matrices have entries all between 0 and 2 — nothing about their size looks alarming. But A2A_2 amplifies input errors roughly 20,000 times more than A1A_1, purely because its two rows are nearly parallel (one is (1.0001,1)(1.0001,1), the other (1,1)(1,1) — nearly identical directions). Near-parallel rows are the fingerprint of ill-conditioning: the system is close to being redundant, telling you almost the same thing twice instead of two independent facts.

Worked example 2: watching an error amplify in a regression

Recall a regression solves β^=(XX)1Xy\hat\beta = (X^\top X)^{-1}X^\top y. Suppose two predictor columns in XX are highly correlated — nearly collinear, say correlation 0.9990.999. This makes XXX^\top X ill-conditioned in exactly the A2A_2 way above. Concretely, take XX=(10099.999.9100)X^\top X = \begin{pmatrix}100 & 99.9\\99.9&100\end{pmatrix} (variance 100 each, covariance 99.999.9, correlation 0.9990.999). Eigenvalues: trace =200=200, determinant =100(100)99.92=10,0009,980.01=19.99=100(100)-99.9^2=10{,}000-9{,}980.01=19.99. Solving λ2200λ+19.99=0\lambda^2-200\lambda+19.99=0 gives λ200±4000079.962=200±199.82\lambda \approx \frac{200\pm\sqrt{40000-79.96}}{2}=\frac{200\pm 199.8}{2}, so λ1199.9\lambda_1\approx199.9, λ20.1\lambda_2\approx0.1, giving κ1999\kappa \approx 1999. A data revision that nudges yy by half a percent can swing the individual coefficients on those two correlated predictors by roughly 1999×0.5%10×1999 \times 0.5\% \approx 10\times their own size — even though the combined prediction Xβ^X\hat\beta barely moves. This is exactly the "unstable coefficients, stable predictions" symptom quants recognise as multicollinearity.

What this means in practice

  • It's the real reason "just invert the matrix" is bad advice. Explicit matrix inversion tends to be numerically worse-conditioned than solving the system directly via factorisation (QR, Cholesky, LU) — production linear algebra libraries avoid inverse() for exactly this reason.
  • It flags collinear or redundant risk factors before they wreck a regression or optimiser. A covariance matrix with a huge condition number means some combination of assets is nearly riskless-looking in-sample, which mean-variance optimisers will happily bet the farm on — a well-known source of blown-up portfolio weights.
  • It tells you how many digits of precision you can trust. A rough rule: you lose about log10κ(A)\log_{10}\kappa(A) decimal digits of accuracy relative to the precision of your inputs. With standard double-precision arithmetic (about 16 digits), a condition number of 101010^{10} leaves only about 6 trustworthy digits.

The condition number κ(A)=σmax/σmin\kappa(A) = \sigma_{\max}/\sigma_{\min} measures how unevenly a matrix stretches different directions, and that unevenness is exactly how much it amplifies small input errors into large output errors when you solve Ax=bAx=b. A condition number near 1 is safe; one in the millions means your computed answer may be mostly numerical noise.

The classic confusion is judging numerical stability from the size of a matrix's entries. A matrix can have small, ordinary-looking numbers and still be catastrophically ill-conditioned — as A2A_2 above shows, entries between 0 and 2 but a condition number near 40,000. Conditioning is about the relationship between rows or columns (how close to parallel, i.e. redundant, they are), not about magnitude. The practical trap this causes: a quant sees "reasonable" numbers in a correlation or design matrix, assumes the regression or optimisation built on it is trustworthy, and never checks κ\kappa — right up until a tiny data revision produces wildly different coefficients or portfolio weights from one day to the next.

Related concepts

Practice in interviews

Further reading

  • Trefethen & Bau, Numerical Linear Algebra (lecture 12)
  • Golub & Van Loan, Matrix Computations (ch. 2)
ShareTwitterLinkedIn