Gaussian elimination, LU, and LDL

9/12/2026

For some projects I am working on, I wanted to understand sparse factorizations better, but first I needed to get the dense case straight. This is the first of three notes collecting the material I found most useful on the topic.

None of the material is new, and all of it is covered more fully in Trefethen and Bau (1997) and Golub and Van Loan (2013). The error analysis I quote without proof is developed carefully in Higham (2002).

Gaussian elimination is a factorization

Suppose A∈Rn×nA\in\mathbb{R}^{n\times n}. One step of Gaussian elimination uses the pivot a11a_{11} to clear the first column below the diagonal. Partition

A=[αrTcB],α≠0. A = \begin{bmatrix} \alpha & r^T \\ c & B \end{bmatrix}, \qquad \alpha \neq 0.

With m=c/αm=c/\alpha, the elimination step is

[10−mI][αrTcB]=[αrT0B−mrT]. \begin{bmatrix}1&0\\-m&I\end{bmatrix} \begin{bmatrix}\alpha&r^T\\c&B\end{bmatrix} = \begin{bmatrix}\alpha&r^T\\0&B-mr^T\end{bmatrix}.

The trailing matrix B−mrTB-mr^T is the Schur complement of the pivot. Write E1E_1 for the unit lower triangular matrix that produced it. Repeating the step on each successive Schur complement produces E2,…,En−1E_2,\dots,E_{n-1} and an upper triangular UU with En−1⋯E1A=UE_{n-1}\cdots E_1A=U, so

A=E1−1⋯En−1−1U=LU. A=E_1^{-1}\cdots E_{n-1}^{-1}U=LU.

Each inverse elimination matrix is unit lower triangular, and so is their product LL. Its subdiagonal entries are exactly the multipliers used along the way. LU is therefore not a construction layered on top of Gaussian elimination. It is a record of the elimination.

Once the factorization is in hand, solving Ax=bAx=b is two triangular solves,

Ly=b,Ux=y. Ly=b, \qquad Ux=y.

The factorization costs 2n3/3+O(n2)2n^3/3+O(n^2) flops for a dense matrix, and each solve costs O(n2)O(n^2). This asymmetry is the reason to keep the factors and reuse them rather than form A−1A^{-1}.

Existence is an algebraic condition. If every leading principal submatrix of order less than nn is nonsingular, then AA has an LU factorization with unit lower triangular LL, and that factorization is unique when AA is nonsingular. Nothing in the condition is numerical. A pivot can be nonzero and still be small enough to produce large multipliers and a poor factorization in floating point.

Pivoting bounds the multipliers, not the growth

Dense LU normally uses partial pivoting. Step kk selects the largest-magnitude entry of column kk at or below the diagonal, exchanges its row with row kk, and only then eliminates. The search costs n−kn-k comparisons, or O(n2)O(n^2) over the whole factorization.

The resulting factorization has the form

PA=LU, PA=LU,

where PP collects the row exchanges. Because the pivot has maximal magnitude in its column, every multiplier satisfies ∣lik∣≤1|l_{ik}|\leq 1. This says nothing about the entries created in UU. Those are measured separately. Write aij(k)a_{ij}^{(k)} for the entries present at the start of step kk, so that aij(1)=aija_{ij}^{(1)}=a_{ij}. The growth factor is

ρ=max⁡i,j,k∣aij(k)∣max⁡i,j∣aij∣. \rho = \frac{\max_{i,j,k}\left|a_{ij}^{(k)}\right|}{\max_{i,j}|a_{ij}|}.

Wilkinson (1961) showed that partial pivoting admits ρ≤2n−1\rho\leq 2^{n-1}, and the bound is attained. Nor is exponential growth only a textbook artifact. Wright (1993) collects problems from applications on which partial pivoting fails. Growth is nonetheless modest in many practical problems, and Trefethen and Schreiber (1990) give a statistical account of why.

A factorization algorithm is backward stable if its computed factors exactly factor a nearby matrix, with relative perturbation of order unit roundoff up to dimension-dependent constants. The standard backward-error statement keeps the two effects separate. The computed factors satisfy

PA+ΔA=L^U^,∣ΔA∣≲u ∣L^∣ ∣U^∣, PA+\Delta A=\hat{L}\hat{U}, \qquad |\Delta A|\lesssim u\,|\hat{L}|\,|\hat{U}|,

where uu is unit roundoff, the absolute values and inequality are entrywise, and ≲\lesssim hides dimension-dependent constants. The product ∣L^∣ ∣U^∣|\hat{L}|\,|\hat{U}| is ordinary matrix multiplication. Partial pivoting controls L^\hat{L}. Element growth controls U^\hat{U}. LU with partial pivoting is therefore backward stable when growth is moderate. It is not unconditionally backward stable in the strong sense that Householder QR is.

To see how the row exchanges collect into PP, return to the individual steps. Each contributes a permutation and an elimination. Let PkP_k be the transposition applied at step kk and EkE_k the elimination matrix that follows it. The reduction to upper triangular form reads

En−1Pn−1⋯E2P2E1P1A=U. E_{n-1}P_{n-1}\cdots E_2P_2E_1P_1A=U.

This is not yet in the form PA=LUPA=LU, because the permutations are interleaved with the eliminations. They can be pulled out to the right. Write Ej=I−mjejTE_j=I-m_je_j^T, where eje_j is the jjth standard basis vector and mjm_j holds the multipliers of step jj, with nonzeros only below entry jj. If k>jk>j, then PkP_k exchanges two rows whose indices both exceed jj. It therefore fixes eje_j and only reorders the entries of mjm_j:

PkEjPk=I−(Pkmj)ejT. P_kE_jP_k = I-\left(P_km_j\right)e_j^T.

The conjugate is another elimination matrix in the same column, holding the same multipliers in a different order. Applying this repeatedly walks each transposition to the right, past every elimination matrix standing between it and AA. Writing E~j\tilde{E}_j for EjE_j conjugated by all the transpositions that follow it,

E~n−1⋯E~1Pn−1⋯P1A=U, \tilde{E}_{n-1}\cdots\tilde{E}_1P_{n-1}\cdots P_1A=U,

so with P=Pn−1⋯P1P=P_{n-1}\cdots P_1 and L=E~1−1⋯E~n−1−1L=\tilde{E}_1^{-1}\cdots\tilde{E}_{n-1}^{-1} we recover the familiar

PA=LU. PA=LU.

Nothing about the elimination changed. The exchanges were chosen one step at a time, during the factorization, and only afterwards collected into a single permutation applied to AA up front. This is also why LL can be built in place. Each E~j\tilde{E}_j carries the multipliers of step jj permuted by the exchanges that came later. That is exactly what an implementation does when it applies each row swap to the multipliers already stored.

Solving Ax=bAx=b now permutes the right-hand side first, so the triangular solves become Ly=PbLy=Pb and Ux=yUx=y.

Complete pivoting trades a more expensive search for stronger growth control. It searches the entire trailing matrix and applies both row and column permutations. Its growth bound is subexponential, but the search costs O(n3)O(n^3) comparisons, the same order as the arithmetic itself.

Rook pivoting alternates row and column searches until a candidate is maximal in magnitude in both its active row and its active column. It buys growth control close to complete pivoting at a search cost usually closer to partial pivoting, as Foster (1997) quantifies.

Which of these strategies is affordable for a sparse matrix is a separate question, because every exchange also changes the structure of the factors. I take that up in the next note.

Symmetry turns LU into LDL

Now suppose A=ATA=A^T and elimination proceeds without exchanges. Each successive Schur complement remains symmetric. In the partition above r=cr=c, so the Schur complement is

B−mrT=B−ccTα, B-mr^T = B-\frac{cc^T}{\alpha},

which is again symmetric. The elimination step can therefore be written with transposed factors on either side:

A=[10c/αI][α00B−ccT/α][1cT/α0I]. A= \begin{bmatrix}1&0\\c/\alpha&I\end{bmatrix} \begin{bmatrix}\alpha&0\\0&B-cc^T/\alpha\end{bmatrix} \begin{bmatrix}1&c^T/\alpha\\0&I\end{bmatrix}.

Repeating this identity on the Schur complement and recording the scalar pivots in DD gives

A=LDLT, A=LDL^T,

with LL unit lower triangular and DD diagonal. This is Gaussian elimination with the symmetry left in. It stores one triangular factor instead of two and costs n3/3+O(n2)n^3/3+O(n^2) flops, roughly half of general LU.

Written column by column, the factorization is a sum of rank-one terms. If lkl_k denotes the kkth column of LL, so that lkk=1l_{kk}=1 and mkm_k sits below it, then

A=∑k=1ndk lklkT. A=\sum_{k=1}^{n} d_k\, l_kl_k^T.

Each elimination step removes one term. The terms that remain are supported on the trailing block, where they sum to the Schur complement. This is the right-looking view of the algorithm, and it is the one to hold onto for sparsity. The pattern of lkl_k decides which entries of the trailing matrix a single pivot can reach, and therefore how many new nonzeros, or fill, it creates.

For a symmetric positive definite matrix, every pivot is positive and no pivoting is required. The Schur complement identity proves it in one line. If

A=[αcTcB]≻0, A=\begin{bmatrix}\alpha&c^T\\c&B\end{bmatrix}\succ 0,

then α>0\alpha>0 and, for every nonzero yy,

yT(B−ccTα)y=[−cTy/αy]TA[−cTy/αy]>0. y^T\left(B-\frac{cc^T}{\alpha}\right)y = \begin{bmatrix}-c^Ty/\alpha\\y\end{bmatrix}^T A \begin{bmatrix}-c^Ty/\alpha\\y\end{bmatrix}>0.

The Schur complement is again positive definite, so the argument repeats on it.

The scalar LDL recurrence is left-looking. It builds column kk from the columns already finished rather than updating the trailing block as each pivot is eliminated:

dk=akk−∑j<klkj2dj,lik=1dk(aik−∑j<klijdjlkj),i>k. \begin{align*} d_k &= a_{kk}-\sum_{j<k}l_{kj}^2d_j,\\ l_{ik} &= \frac{1}{d_k}\left(a_{ik}-\sum_{j<k}l_{ij}d_jl_{kj}\right), \qquad i>k. \end{align*}

LDL avoids square roots and keeps the signs of the pivots explicit. The inertia of a symmetric matrix is the triple of counts of its positive, negative, and zero eigenvalues. In exact arithmetic, and whenever the unpivoted factorization exists, the signs of the pivots give the inertia of AA by Sylvester's law.

Symmetry alone does not make unpivoted elimination safe. A nonsingular symmetric indefinite matrix can have a zero or tiny diagonal pivot, and there is no guarantee that any diagonal entry is usable. The smallest example is

[0110], \begin{bmatrix}0&1\\1&0\end{bmatrix},

which is symmetric and nonsingular with no nonzero diagonal entry at all. The remedy is to widen what counts as a pivot, and this matrix is its own 2×22\times2 pivot. A stable factorization then has the form

PAPT=LDLT, PAP^T=LDL^T,

where DD is block diagonal with 1×11\times1 and 2×22\times2 blocks, following Bunch and Parlett (1971).

Choosing these blocks involves the same search-cost tradeoff as LU pivoting. The Bunch–Kaufman rule uses at most two column searches per step and bounds element growth, but not the entries of LL. Bounded Bunch–Kaufman and symmetric rook pivoting search further to control the multipliers as well, as analyzed by Ashcraft, Grimes, and Lewis (1998).

The permutation here acts on both sides. Unlike LU row pivoting, a symmetric factorization may only reorder rows and columns together. That constraint is what will make symmetric pivoting hard to reconcile with an ordering chosen for sparsity.

Solving Ax=bAx=b from these factors mirrors the LU case with one step inserted in the middle:

Lw=Pb,Dz=w,LTv=z,x=PTv. Lw=Pb, \qquad Dz=w, \qquad L^Tv=z, \qquad x=P^Tv.

The middle solve is diagonal, or block diagonal once 2×22\times2 pivots appear, and costs O(n)O(n) either way.

Cholesky is scaled LDL

For A≻0A\succ0 every dkd_k is positive, so the pivots can be split as D=D1/2D1/2D=D^{1/2}D^{1/2} and absorbed into the triangular factors:

A=LDLT=(LD1/2)(LD1/2)T=GGT, A=LDL^T=(LD^{1/2})(LD^{1/2})^T=GG^T,

where G=LD1/2G=LD^{1/2} is lower triangular with positive diagonal gkk=dkg_{kk}=\sqrt{d_k}. This is the Cholesky factorization, and the positive diagonal makes it unique. I name the factor GG following Golub and Van Loan, since LL already names the unit lower triangular factor and RR would suggest an upper triangular one.

Cholesky costs the same n3/3+O(n2)n^3/3+O(n^2) flops as LDL, plus nn square roots. It is backward stable without pivoting provided the computation completes: the computed factor satisfies

A+ΔA=G^G^T,∣ΔA∣≲u ∣G^∣ ∣G^∣T, A+\Delta A=\hat{G}\hat{G}^T, \qquad |\Delta A|\lesssim u\,|\hat{G}|\,|\hat{G}|^T,

up to dimension-dependent constants. Positive definiteness removes the stability reason to pivot. Permutations remain essential in sparse problems, but only to reduce fill.

The distinction appears when a pivot is nonpositive. A nonpositive dkd_k proves in exact arithmetic that AA is not positive definite. LDL records a negative pivot and continues. Cholesky meets it as a negative argument to a square root and stops. A zero pivot before the last column makes the scalar LDL recurrence break down, since it divides by dkd_k. A zero final pivot requires no division and does not prevent an LDL factorization, though the matrix is singular.

In floating point, even an exactly SPD matrix sufficiently close to singularity can produce a nonpositive computed pivot and cause Cholesky to stop. A small negative value may therefore reflect roundoff, or an input that is only numerically semidefinite. Silently clipping it changes the problem, so a regularization or diagonal shift belongs in the model rather than in a solver.

The normal equations MTMx=MTbM^TMx=M^Tb deserve the same caution. When MM has full column rank, MTMM^TM is SPD, but its 2-norm condition number is κ2(MTM)=κ2(M)2\kappa_2(M^TM)=\kappa_2(M)^2. Cholesky is stable only for the matrix it is handed, not for the one that matrix came from. Björck (1996) is the standard account.

The difference that matters for what follows is that the square root demands positivity and LDL does not. Unpivoted LDL asks only that the leading principal submatrices of order less than nn be nonsingular. It exposes the inertia, and with a symmetric permutation and 2×22\times2 blocks it covers every nonsingular symmetric matrix. Cholesky is the special case in which the pivots happen to be positive. That is why the rest of this series is written in terms of LDL.

Block elimination is the same identity

The scalar formulas hide the form that high-performance implementations actually use. Partition an SPD matrix after a leading block:

A=[A11A21TA21A22]. A=\begin{bmatrix}A_{11}&A_{21}^T\\A_{21}&A_{22}\end{bmatrix}.

First factor A11=G11G11TA_{11}=G_{11}G_{11}^T, then solve G21G11T=A21G_{21}G_{11}^T=A_{21}, and finally factor the Schur complement

S=A22−G21G21T. S=A_{22}-G_{21}G_{21}^T.

This is block Cholesky. It is the same step as before with a leading submatrix in place of a scalar pivot. For block LDL, first factor A11=L11D1L11TA_{11}=L_{11}D_1L_{11}^T, then solve for L21L_{21} and form the Schur complement:

L21D1L11T=A21,S=A22−L21D1L21T. L_{21}D_1L_{11}^T=A_{21}, \qquad S=A_{22}-L_{21}D_1L_{21}^T.

Factoring SS completes the block LDL factorization. In both versions, most of the work is the matrix–matrix trailing update, which is why blocked dense implementations reach level-3 BLAS speed.

Sparse multifrontal methods run on the same identity. There the leading block is a group of columns eliminated together, and the update is not applied to A22A_{22} right away. It is held as a dense contribution block and assembled into a later frontal matrix, following Duff and Reid (1983) and the account in Liu (1992). Block elimination is the reason a sparse factorization can spend most of its time inside dense kernels. I take this up in the third note.

Left-looking, right-looking, and multifrontal algorithms differ mainly in when they assemble and apply Schur-complement updates. In exact arithmetic, for a fixed ordering, they produce the same factor. Their memory traffic and their access to dense kernels differ a great deal.