6.6. LU Decomposition¶
A variant of Gaussian elimination called LU decomposition (for
Lower–Upper) factors a matrix into products of two matrices. The first
is a lower triangular matrix, and the second an upper triangular matrix.
The LU decomposition algorithm can be implemented in software to achieve
the best possible accuracy from a general elimination based
algorithm [1]. It is used internally by MATLAB for computing inverses,
solving square matrix systems of equations, and calculating
determinants. MATLAB’s lu
function finds a matrix’s LU
decomposition.
Recall that to solve a system of equations we can use Gaussian
elimination with an augmented matrix so that changes made to matrix
are also applied to vector
.
In the modified equation, is an upper triangular matrix
for which simple back substitution may be used to solve for the unknown
vector
. The LU decomposition method differs in that it
operates only on the
matrix to find a matrix factoring,
, where
is lower triangular
and
is upper triangular. Thus the substitution phase for
solving
has two steps—solving
and then solving
.
LU decomposition changes the equations used to solve systems of
equations as follows. In addition to and
,
we have an elimination matrix,
. Its inverse is
. We also introduce the
matrix, which is
the permutation matrix that orders the rows to match the row
exchanges. [2] Note that the parentheses are important to ensure that
substitution is applied in the correct order.
(6.16)¶
Which algorithm is faster?
There are some applications where there is a need to solve several
systems of equations with the same matrix but with
different
vectors. It is faster to find the LU factors
once and then use forward and backward substitution with each
vector than to do full elimination each time. The
combined forward and backward substitution for LU decomposition has
run time of
.
Elimination with an augmented matrix and the LU decomposition
algorithm have the same order of magnitude run time performance,
which depending on the exact implementation is approximately
. But more precisely, the cost of computation
for LU decomposition is
floating point
operations (flops) [HIGHAM11], which explains why
experimentation shows that LU decomposition is faster than the
rref
function, especially for larger matrices. Here is a quick
experiment performed on a personal computer.
>> A = rand(100); b = rand(100,1);
>> tic; [L,U,P] = lu(A); x = U\(L\(P*b)); toc;
Elapsed time is 0.000605 seconds.
>> tic; x = rref([A b]); toc;
Elapsed time is 0.069932 seconds.
6.6.1. LU Example¶
Before demonstrating how to use the lu
function in MATLAB, we will
first work part of a problem manually and then turn to MATLAB to help
with the computation. We will use the same example that was solved in
Elimination. For purposes of understanding how the
and
matrices are factors of the
matrix, we will follow a traditional elimination strategy
to find
and will form
from a record of the
row operations needed to convert
into
. We
will focus on how the
and
matrices are
found. We will not make row exchanges in this example, but will use row
exchanges in
The needed row operations are the same as noted in Elimination.
Each row operation is represented by a matrix
that can multiply with
to affect the change. These
matrices start with an identity matrix and then change one element to
represent each operation. We call these matrices Elementary Matrices.
Then the product of the elementary matrices is called the elimination
matrix.
- Add
of row 1 to row 3, called
.
- Add
of row 1 to row 2, called
.
- Add
of row 2 to row 3, called
.
>> E1
E1 =
1 0 0
0 1 0
-1 0 1
>> E2
E2 =
1 0 0
-2 1 0
0 0 1
>> E3
E3 =
1 0 0
0 1 0
0 -2 1
The combined row operations can be found by multiplying these together.
The order of matrices must be such that the first operation applied is
next to in the equation
.
>> E = E3*E2*E1
E =
1 0 0
-2 1 0
-1 -2 1
>> U = E*A
U =
2 -3 0
0 1 1
0 0 -5
Another way to find E and U is with elimination of an augmented matrix.
Start with and
perform row operations until the matrix in the position of
is upper triangular. The resulting augmented matrix is
then
[KUTZ13].
The matrix is the inverse of
. Recall that
to take the inverse of a product of matrices, we reverse the order of
the
matrices—
.
Note that each elementary matrix only differs from the identity matrix at one element. The inverse of each elementary matrix is found by just changing the sign of the additional nonzero value to the identity matrix.
>> inv(E1)
ans =
1 0 0
0 1 0
1 0 1
>> inv(E2)
ans =
1 0 0
2 1 0
0 0 1
>> inv(E3)
ans =
1 0 0
0 1 0
0 2 1
>> L = inv(E1)*inv(E2)*inv(E3)
L =
1 0 0
2 1 0
1 2 1
>> inv(E)
ans =
1.0000 0 0
2.0000 1.0000 0
1.0000 2.0000 1.0000
Also note that the matrix does the reverse of
, so
could be found directly from the list
of row operations.
Now, with and
found, we can find the
solution to
. Since these are
lower and upper triangular matrices, the left-divide operator will
quickly solve them. If several solutions are needed, the one-time
calculations of
and
will substantially
expedite the calculations.
>> b
b =
3
9
-1
>> x = U\(L\b)
x =
3.0000
1.0000
2.0000
Note
The substitution phase has two steps—solving
and
. When presented with upper or
lower triangular matrices, the left-divide operator will skip
directly to substitution. So either another vector,
is
needed, or parenthesis may be used to dictate the ordering of the
operations.
6.6.2. Example with Row Exchanges¶
We find the LU decomposition with partial pivoting (row exchanges) in this example. We will show the row exchanges with a permutation matrix. A permutation matrix has the rows of an identity matrix, but the order of the rows shows what row exchanges were performed.
Looking at the first column, we will use the largest value, 8, as our
first pivot, so we exchange rows one and two and define a permutation
matrix. The matrix will reflect the row exchanges.
The
matrix begins as an identity matrix and the ones
on the diagonal will remain. We will document our elimination row
operations directly in the
matrix as the negative
values of what we would add to the elementary matrices.
Add of row 1 to row 3.
We will keep the pivot of in row 2, so no change to the
permutation matrix is needed. Add
of row 2 to row 3.
6.6.3. MATLAB Examples of LU¶
First, we ask MATLAB to just compute and
.
We can see that
is not lower triangular as we think it
should be. That is because we did not accept a permutation matrix in the
output.
>> [L, U] = lu(A)
L =
0.5000 -0.3333 1.0000
1.0000 0 0
0.5000 1.0000 0
U =
4.0000 -5.0000 1.0000
0 1.5000 -3.5000
0 0 -1.6667
Now we will accept a permutation matrix as an output matrix. The
relationship of the matrices is .
Note that the permutation matrix merely swaps the rows of whatever
vector or matrix it is multiplied by. Like the identity matrix,
permutation matrices are orthogonal, thus their inverse is just their
transpose, so
. Now,
is lower triangular as
expected, but
and
are different than they
were with the manual solution because of the permutation matrix. So the
solution comes from equation (6.16), or in MATLAB,
x = U\(L\(P*b))
. Note here that the parenthesis are important. The
left-divide operators will not use the correct matrices without the
parenthesis.
% Returning to
% our previous example ...
>> [L, U, P] = lu(A)
L =
1.0000 0 0
0.5000 1.0000 0
0.5000 -0.3333 1.0000
U =
4.0000 -5.0000 1.0000
0 1.5000 -3.5000
0 0 -1.6667
P =
0 1 0
0 0 1
1 0 0
>> x = U\(L\(P*b))
x =
3.0000
1.0000
2.0000
Another option is to have MATLAB return the row exchange information as an ordering of the rows rather than as a permutation matrix.
>> [L, U, P] = ...
lu(A, 'vector');
>> P
P =
2 3 1
>> x = U\(L\(b(P)))
x =
3.0000
1.0000
2.0000
6.6.4. Turing’s LU Elimination Algorithm¶
The MATLAB documentation for lu
states that “The LU factorization is
computed using a variant of Gaussian elimination”. There are several
implementations of LU decomposition. In this section, we present a
simple, yet efficient, and numerically stable LU algorithm that was
developed and reported in a 1948 paper by British mathematician Alan
Turing who is considered to be a founding father of computer
science [TURING48], [DOPICO13]. Modern numerical linear
algebra literature call Turing’s algorithm the “kij” version of the
outer product LU algorithm. Golub and Van Loan’s text on Matrix
Computations gives a proof showing that potential round-off errors are
minimized by this algorithm [GOLUB13].
A simple function turingLU
implements Turing’s kij algorithm with a few
added lines of code for partial pivoting.
function [L, U, P] = turingLU(A)
% [L,U,P] = TURINGLU(A)
% A simplified LU factorization of a matrix using Alan Turing's
% kij variant of Gaussian elimination algorithm.
%
% Input: A - square matrix
% Output: L - lower triangular matrix
% U - upper triangular matrix
% P - permutation matrix
% P*A = L*U, A = P'*L*U
%
% This code is for educational purposes only.
% For any other purpose, use MATLAB's lu function.
[m, n] = size(A);
if m ~= n
error('Matrix is not square')
end
P = eye(n);
% The kij nested elimination loop
for k = 1:(n - 1)
[A(k:n,:), idx] = sortrows(A(k:n,:), k, 'descend', ...
'ComparisonMethod','abs');
I = P(k:n,:);
P(k:n,:) = I(idx,:); % Permutation matrix
for i = k + 1:n
A(i, k) = A(i, k)/A(k, k);
for j = (k + 1):n
A(i, j) = A(i, j) - A(i, k) * A(k, j);
end
end
end
% L is now in the lower triangular of A.
% U is now in the upper triangular of A.
L = tril(A, -1) + eye(n); % extract lower
U = triu(A); % and upper triangular
The and
matrices are taken directly from
the modified
matrix after the algorithm is completed.
After the elimination steps are finished, the
matrix is
in the lower triangular of
and the
matrix
is in the upper triangular of
.
Turing’s algorithm has good performance and produces accurate results. Unfortunately, the algorithm is specific to LU decomposition and not usable with traditional elimination.
It is a little difficult from a first reading of the code to see how it
achieves the same result as found from normal Gaussian elimination. With
elimination, row operations zero out the lower triangular part of the
matrix and then is found from the action of the row
operations. Whereas, in Turing’s algorithm the row operations directly
yield both
an
.
The variable k
references the pivot variable. Row exchanges are
performed each time the pivot is advanced. There are only two statements
that alter the values of the matrix. First, the elements in the column
below the pivot are divided by the pivot. This equates to recording the
row operations in the matrix. There is no need to set
those values to zero since they will become part of the
matrix. Secondly, row operations are performed between the pivot row and
the rows below the pivot row. This operation is preparation for future
steps that set the
matrix values at positions left of the
diagonal. It also sets the needed
matrix values for
elements on or to the right of the diagonal.
Let’s work through a step-by-step elimination example with a
matrix to see how the algorithm produces the same
result as achieved by Gaussian elimination. We will use letters for the
matrix values so that we don’t let fraction reductions cause us to lose
track of the numeric operations.
The elimination step is to add of row 1 to row
2. In the
matrix,
should be put in
the (2, 1) position. The
matrix now reflects what we
would see in the Gaussian elimination matrix. We show what the matrix
looks like below in the LU algorithm and the resulting
and
matrices.
Experimentation with this function found that it reliably returns the
same results as MATLAB’s lu
function. Please experiment with it
yourself. Set breakpoints for the debugging tool or add printing
statements to learn how the algorithm works. But for applications other
than education, use the lu
function that comes with MATLAB, which
runs faster, and has more flexible usage options. Note that this
function could be implemented with vectorized array indices, but nested
for
loops are used for clarity of reading the code.
6.6.5. Determinant Shortcut¶
Another application of LU decomposition is a faster algorithm for computing the determinant of a matrix. The product of the determinants of a matrix factorization is equal to the determinant of the original matrix. Thus,
Because of the zeros in all three of these matrices, their determinants
are quick to compute. It is not necessary to take the transpose of
before finding its determinant because the determinant of
a square matrix is the same as the determinant of its transpose,
det(P) = det(P')
. The determinant of is either 1 or
-1. Since each row has only a single one, the determinant is quick to
calculate. The determinant of
is always 1, which is the
product of the ones along the diagonal. The determinant of
is the product of the values on its diagonal.
Refer to the normal method for calculating the determinant in Determinant and take a moment to see why the determinant of an upper or lower triangular matrix is the product of the diagonal values.
The MATLAB det
function computes the determinant of a matrix as
follows.
>> [L, U, P] = lu(A)
>> determinant = det(P)*prod(diag(U))
Footnotes:
[1] | Matrices in a special form such as triangular, positive definite, Hermitian, or upper Hessenberg have more efficient solvers that are briefly mentioned in Left-Divide Operator. The LU decomposition is a general algorithm because it is applicable to all non-singular, square matrix systems. |
[2] | Equation (6.16) is expressed with a pure mathematics
notation using the inverse of matrices. The expression that is
preferred with MATLAB is an expression that directly uses back
substitution on triangular matrices (x = U\(L\(P*b)) ). |