Quant Memo
Advanced

The Sherman-Morrison-Woodbury Formula

A shortcut for updating a matrix inverse after a small, low-rank change — such as adding one new asset to a covariance matrix — without recomputing the whole inverse from scratch.

Prerequisites: Matrix Inverses and Linear Systems, The Schur Complement

Recomputing the inverse of a large covariance matrix every time a single new asset is added, or a single risk factor exposure is updated, is wasteful — a full inverse of an n×nn \times n matrix costs on the order of n3n^3 operations, and most of that work is thrown away and redone from scratch for a change that only touched a handful of entries. The Sherman-Morrison-Woodbury formula says you don't need to: if the change is low-rank (a small number of new rows/columns, or a rank-one update), the new inverse can be built directly from the old inverse plus a small correction.

An analogy: patching a map instead of redrawing it

If a single road closes on a large city map, you don't redraw the entire map from scratch — you take the existing map and patch in a local correction around the closure. The Sherman-Morrison-Woodbury formula is the same idea applied to matrix inverses: instead of recomputing the whole inverse (redrawing the whole map) after a small, localized change, it patches the old inverse with a correction term sized to the rank of the change, which is cheap when the change itself is small.

The math, one symbol at a time

For an invertible matrix AA and a low-rank update UCVUCV (where UU, VV are tall/wide with few columns and CC is small), the formula gives

(A+UCV)1=A1A1U(C1+VA1U)1VA1.(A + UCV)^{-1} = A^{-1} - A^{-1}U\left(C^{-1} + VA^{-1}U\right)^{-1}VA^{-1}.

In words: the inverse of the updated matrix equals the old inverse, minus a correction term built entirely from the old inverse and the small pieces UU, CC, VV describing the update — no inversion of the full updated matrix A+UCVA + UCV is needed, only inversion of the much smaller matrix C1+VA1UC^{-1} + VA^{-1}U, whose size matches the rank of the update, not the size of AA. The simplest case, a rank-one update A+uvA + uv^\top, simplifies further to A1A1uvA11+vA1uA^{-1} - \frac{A^{-1}uv^\top A^{-1}}{1 + v^\top A^{-1}u} — a correction built from just two matrix-vector products.

Worked example 1: a rank-one update by hand

Let A=(2002)A = \begin{pmatrix}2&0\\0&2\end{pmatrix}, so A1=(0.5000.5)A^{-1} = \begin{pmatrix}0.5&0\\0&0.5\end{pmatrix}. Update with u=v=(1,1)u = v = (1,1), i.e. A+uv=(3113)A + uv^\top = \begin{pmatrix}3&1\\1&3\end{pmatrix}. Compute vA1u=(1,1)(0.5000.5)(11)=1v^\top A^{-1}u = (1,1)\begin{pmatrix}0.5&0\\0&0.5\end{pmatrix}\begin{pmatrix}1\\1\end{pmatrix} = 1. Then A1uvA1=(0.50.5)(1,1)(0.5000.5)A^{-1}uv^\top A^{-1} = \begin{pmatrix}0.5\\0.5\end{pmatrix}(1,1)\begin{pmatrix}0.5&0\\0&0.5\end{pmatrix}, which works out to (0.250.250.250.25)\begin{pmatrix}0.25&0.25\\0.25&0.25\end{pmatrix}. The formula gives (A+uv)1=(0.5000.5)12(0.250.250.250.25)=(0.3750.1250.1250.375)(A+uv^\top)^{-1} = \begin{pmatrix}0.5&0\\0&0.5\end{pmatrix} - \frac{1}{2}\begin{pmatrix}0.25&0.25\\0.25&0.25\end{pmatrix} = \begin{pmatrix}0.375&-0.125\\-0.125&0.375\end{pmatrix} — matching a direct inversion of (3113)\begin{pmatrix}3&1\\1&3\end{pmatrix}, but computed with only vector operations.

Worked example 2: adding one asset to a portfolio covariance inverse

A quant already has the inverse of a 500-asset covariance matrix cached (needed repeatedly for mean-variance optimization). A new asset arrives whose covariances with the existing 500 form a vector vv, and its own variance requires a rank-one adjustment. Instead of re-inverting a 501×501501\times501 matrix (roughly 5013126501^3 \approx 126 million operations), the formula updates the cached 500×500500\times500 inverse using a handful of matrix-vector products, each costing about 5002=250,000500^2 = 250{,}000 operations — several hundred times cheaper, and exactly why production risk systems use incremental updates rather than full recomputation whenever the investable universe changes by one name.

full re-inversion ~n³ rank-1 update ~n²
A full re-inversion scales with the cube of the matrix size; a Sherman-Morrison-Woodbury update after a small change scales only with its square — a large saving as the matrix grows.
old A⁻¹ small correction = new inverse
The updated inverse is built by patching the cached old inverse with a correction sized to the rank of the change, not by recomputing from zero.

What this means in practice

This formula is what makes incremental portfolio risk updates, online regression (adding one data point without refitting), and Kalman filter covariance updates computationally feasible at scale. It's the same block-elimination logic as the The Schur Complement, specialized to the case of a low-rank update, and it's why production systems maintain a cached inverse and patch it rather than re-solving a full linear system on every new data point.

For a low-rank update A+UCVA + UCV, the new inverse can be built from the old inverse A1A^{-1} plus a correction sized to the rank of the update — turning an expensive full re-inversion into a cheap, incremental patch.

The formula assumes the small matrix C1+VA1UC^{-1} + VA^{-1}U being inverted is itself well-conditioned. If the update nearly cancels part of AA's structure — pushing that small matrix close to singular — the formula becomes numerically unstable even though it's algebraically exact. In practice, always sanity-check an incrementally updated inverse periodically against a fresh full inversion; small numerical errors from repeated incremental updates can accumulate silently over many updates.

Related concepts

Practice in interviews

Further reading

  • Golub & Van Loan, Matrix Computations, ch. 2
ShareTwitterLinkedIn