Skip to main content

LU Factorization Method

LU Factorization method is also known as Triangular method or LU Decomposition method. It uses the fact that if a square matrix, A=[aij]A=[a_{ij}] has non zero principal minors i.e

a110, a11a12a21a220, a11a12a13a21a22a23a31a32a330, etc.a_{11} \neq 0,\ \begin{vmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{vmatrix} \neq 0,\ \begin{vmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{vmatrix} \neq 0, \text{ etc.}

then it can be factored into a multiple of a lower triangular matrix LL and an upper triangular matrix UU as A=LUA=LU. There are two main approaches for solving a linear system with LU factorization, they differ in the assumption of the diagonal elements for either LL or UU matrix. These methods are:

  1. Doolittle Method
  2. Crout Method

Doolittle Method

In the Doolittle method, we set the diagonal elements of the LL matrix to be 11. On the other hand, the diagonal elements of the UU matrix may take any value. We initialize LL and UU as:

L=[100l2110l31l321] and U=[u11u12u130u22u2300u33]L=\begin{bmatrix} 1 & 0 & 0\\ l_{21} & 1 & 0\\ l_{31} & l_{32} & 1 \end{bmatrix} \text{ and } U=\begin{bmatrix} u_{11} & u_{12} & u_{13}\\ 0 & u_{22} & u_{23}\\ 0 & 0 & u_{33} \end{bmatrix}

Doolittle Method Working Procedure

We know a system of linear equations is represented in matrix notation as:

AX=B\begin{equation} AX=B \end{equation}

We suppose,

A=LU\begin{equation} A=LU \end{equation}

From (1)(1) and (2)(2), we can write,

LUX=B\begin{equation} LUX=B \end{equation}

Again suppose,

UX=Y\begin{equation} UX=Y \end{equation} or,[u11u12u130u22u2300u33][x1x2x3]=[y1y2y3]or, \begin{bmatrix} u_{11} & u_{12} & u_{13}\\ 0 & u_{22} & u_{23}\\ 0 & 0 & u_{33} \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3 \end{bmatrix}= \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix} or,[u11x1+u12x2+u13x3u22x2+u23x3u33x3]=[y1y2y3]\begin{equation} or, \begin{bmatrix} u_{11}x_1 + u_{12}x_2 + u_{13}x_3\\ u_{22}x_2 + u_{23}x_3\\ u_{33}x_3 \end{bmatrix}= \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix} \end{equation}

From (3)(3) and (4)(4), we can write,

LY=BLY=B or,[100l2110l31l321][y1y2y3]=[b1b2b3]or, \begin{bmatrix} 1 & 0 & 0\\ l_{21} & 1 & 0\\ l_{31} & l_{32} & 1 \end{bmatrix} \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix}= \begin{bmatrix} b_1\\ b_2 \\ b_3 \end{bmatrix} or,[y1l21y1+y2l31y1+l32y2+y3]=[b1b2b3]\begin{equation} or, \begin{bmatrix} y_1\\ l_{21}y_1+y_2\\ l_{31}y_1+l_{32}y_2+y_3 \end{bmatrix}=\begin{bmatrix} b_1\\ b_2 \\ b_3 \end{bmatrix} \end{equation}

Expanding eqn(2)eq^n(2), we get,

[a11a12a13a21a22a23a31a32a33]=[100l2110l31l321][u11u12u130u22u2300u33]\begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33} \end{bmatrix}= \begin{bmatrix} 1 & 0 & 0\\ l_{21} & 1 & 0\\ l_{31} & l_{32} & 1 \end{bmatrix} \begin{bmatrix} u_{11} & u_{12} & u_{13}\\ 0 & u_{22} & u_{23}\\ 0 & 0 & u_{33} \end{bmatrix} or,[u11u12u13l21u11l21u12+u22l21u13+u23l31u11l31u12+l32u22l31u13+l32u23+u33]=[a11a12a13a21a22a23a31a32a33]or, \begin{bmatrix} u_{11} & u_{12} & u_{13}\\ l_{21}u_{11} & l_{21}u_{12}+u_{22} & l_{21}u_{13} + u_{23}\\ l_{31}u_{11} & l_{31}u_{12}+l_{32}u_{22} & l_{31}u_{13} + l_{32}u_{23} + u_{33} \end{bmatrix}=\begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33} \end{bmatrix}

Equating corresponding components we get,

  1. u11=a11, u12=a12, u13=a13u_{11}=a_{11},\ u_{12}=a_{12},\ u_{13}=a_{13}
  2. l21u11=a21l21=a21u11l_{21}u_{11}=a_{21}\rightarrow l_{21}=\frac{a_{21}}{u_{11}}
  3. l31u11=a31l31=a31u11l_{31}u_{11}=a_{31}\rightarrow l_{31}=\frac{a_{31}}{u_{11}}
  4. l21u12+u22=a22u22=a22l21u12l_{21}u_{12}+u_{22}=a_{22}\rightarrow u_{22}=a_{22}-l_{21}u_{12}
  5. l21u13+u23=a23u23=a23l21u13l_{21}u_{13}+u_{23}=a_{23}\rightarrow u_{23}=a_{23}-l_{21}u_{13}
  6. l31u12+l32u22=a32l32=a32l31u12u22l_{31}u_{12}+l_{32}u_{22}=a_{32}\rightarrow l_{32}=\frac{a_{32}-l_{31}u_{12}}{u_{22}}
  7. l31u13+l32u23+u33=a33u33=a33l31u13l32u23l_{31}u_{13}+l_{32}u_{23}+u_{33}=a_{33}\rightarrow u_{33}=a_{33}-l_{31}u_{13}-l_{32}u_{23}

We can also find out the coefficients of LL and UU matrices directly with:

uij=aijk=1i1likukj {i=1...N,j=1...N,ji}u_{ij} = a_{ij}-\sum_{k=1}^{i-1}l_{ik}u_{kj}\ \{i=1...N,j=1...N, j\geq i\} lij=aijk=1j1likukjujj {i=1...N,j=1...N,j<i}l_{ij} = \frac{a_{ij}-\sum_{k=1}^{j-1}l_{ik}u_{kj}}{u_{jj}}\ \{i=1...N,j=1...N, j<i\}

Thus we know LL and UU matrices are known. Then we need to find out YY by solving LY=BLY=B and finally XX by solving UX=YUX=Y.

Doolittle Method Algorithm

  1. Start
  2. Read the size of the system
  3. Read the elements of the coefficient matrix AA
  4. Read the elements of constant vector BB
  5. Calculate the matrices LL and UU
  6. Find YY by solving LY=BLY=B using forward substitution
  7. Find XX by solving UX=YUX=Y using backward substitution
  8. Print XX
  9. Stop

Doolittle Method Program

/*
* Doolittle LU factorization in C
*/

#include <stdio.h>

// Maximum system size
#define MS 3

void printMat(char *name, double m[][MS], int N)
{
printf("%s:\n", name);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf("%8.3f", m[i][j]);
printf("\n");
}
}

void printVec(char *name, double m[], int N)
{
printf("%s:\n", name);
for (int i = 0; i < N; i++)
printf("%8.3f", m[i]);
printf("\n");
}

int main()
{
// The size of linear system
int N = MS;

// Preallocate enough memory for the system
double A[MS][MS] = {0}, L[MS][MS] = {0}, U[MS][MS] = {0};
double X[MS] = {0}, Y[MS] = {0}, B[MS] = {0};

// Get the size of the system
printf("Enter the size of linear system: ");
scanf("%d", &N);

// Limit the max system size
if (N >= MS)
{
printf("Please enter size below %d", MS);
return -1;
}

// Ask for the coefficients
printf("\nEnter the coefficient matrix A:\n");
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
printf("Enter A[%d][%d] = ", i + 1, j + 1);
scanf("%lf", &A[i][j]);
}
}

// Ask for the constants
printf("\nEnter the constant vector B:\n");
for (int i = 0; i < N; i++)
{
printf("Enter B[%d] = ", i + 1);
scanf("%lf", &B[i]);
}

// Find out U and L matrix
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (j >= i)
{
if (j == i)
L[i][j] = 1;
else
L[i][j] = 0;

U[i][j] = A[i][j];
for (int k = 0; k < i; k++)
U[i][j] -= L[i][k] * U[k][j];
}
else
{
L[i][j] = A[i][j];
for (int k = 0; k < j; k++)
L[i][j] -= L[i][k] * U[k][j];

L[i][j] /= U[j][j];
U[i][j] = 0;
}
}
}

printMat("L matrix is", L, N);
printMat("U matrix is", U, N);

// Find out Y by solving LY=B using forward substitution
for (int i = 0; i < N; i++)
{
Y[i] = B[i];
for (int j = 0; j < i; j++)
{
Y[i] -= L[i][j] * Y[j];
}
}
printVec("Y is", Y, N);

// Find out X by solving UX=Y using backward substitution
for (int i = N - 1; i >= 0; i--)
{
X[i] = Y[i];
for (int j = i + 1; j < N; j++)
{
X[i] -= X[j] * U[i][j];
}
X[i] /= U[i][i];
}

printVec("The solution X is", X, N);
return 0;
}

Crout Method

In this method we set the diagonal elements of UU matrix to be 11. On the other hand, the diagonal elements of LL may assume any value. We initialize LL and UU as:

L=[l1100l21l220l31l32l33] and U=[1u12u1301u23001]L=\begin{bmatrix} l_{11} & 0 & 0\\ l_{21} & l_{22} & 0\\ l_{31} & l_{32} & l_{33} \end{bmatrix} \text{ and } U=\begin{bmatrix} 1 & u_{12} & u_{13}\\ 0 & 1 & u_{23}\\ 0 & 0 & 1 \end{bmatrix}

Crout Method Working Procedure

We know a system of linear equations is represented in matrix notation as:

AX=B\begin{equation} AX=B \end{equation}

We suppose,

A=LU\begin{equation} A=LU \end{equation}

From (1)(1) and (2)(2), we can write,

LUX=B\begin{equation} LUX=B \end{equation}

Again suppose,

UX=Y\begin{equation} UX=Y \end{equation} or,[1u12u1301u23001][x1x2x3]=[y1y2y3]or, \begin{bmatrix} 1 & u_{12} & u_{13}\\ 0 & 1 & u_{23}\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3 \end{bmatrix}= \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix} or,[x1+u12x2+u13x3x2+u23x3x3]=[y1y2y3]\begin{equation} or, \begin{bmatrix} x_1 + u_{12}x_2 + u_{13}x_3\\ x_2 + u_{23}x_3\\ x_3 \end{bmatrix}= \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix} \end{equation}

From (3)(3) and (4)(4), we can write,

LY=BLY=B or,[l1100l21l220l31l32l33][y1y2y3]=[b1b2b3]or, \begin{bmatrix} l_{11} & 0 & 0\\ l_{21} & l_{22} & 0\\ l_{31} & l_{32} & l_{33} \end{bmatrix} \begin{bmatrix} y_1\\ y_2 \\ y_3 \end{bmatrix}= \begin{bmatrix} b_1\\ b_2 \\ b_3 \end{bmatrix} or,[l11y1l21y1+l22y2l31y1+l32y2+l33y3]=[b1b2b3]\begin{equation} or, \begin{bmatrix} l_{11}y_1\\ l_{21}y_1+l_{22}y_2\\ l_{31}y_1+l_{32}y_2+l_{33}y_3 \end{bmatrix}=\begin{bmatrix} b_1\\ b_2 \\ b_3 \end{bmatrix} \end{equation}

Expanding eqn(2)eq^n(2), we get,

[l1100l21l220l31l32l33][1u12u1301u23001]=[a11a12a13a21a22a23a31a32a33]\begin{bmatrix} l_{11} & 0 & 0\\ l_{21} & l_{22} & 0\\ l_{31} & l_{32} & l_{33} \end{bmatrix} \begin{bmatrix} 1 & u_{12} & u_{13}\\ 0 & 1 & u_{23}\\ 0 & 0 & 1 \end{bmatrix}= \begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33} \end{bmatrix} or,[l11l11u12l11u13l21l21u12+l22l21u13+l22u23l31l31u12+l32l31u13+l32u23+l33]=[a11a12a13a21a22a23a31a32a33]or, \begin{bmatrix} l_{11} & l_{11}u_{12} & l_{11}u_{13}\\ l_{21} & l_{21}u_{12}+l_{22} & l_{21}u_{13} + l_{22}u_{23}\\ l_{31} & l_{31}u_{12}+l_{32} & l_{31}u_{13} + l_{32}u_{23} + l_{33} \end{bmatrix}=\begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33} \end{bmatrix}

Equating corresponding elements we get,

  1. l11=a11, l21=a21, l31=a31l_{11}=a_{11},\ l_{21} = a_{21},\ l_{31}=a_{31}
  2. l11u12=a12u12=a12l11l_{11}u_{12}=a_{12}\rightarrow u_{12}=\frac{a_{12}}{l_{11}}
  3. l11u13=a13u13=a13l11l_{11}u_{13}=a_{13}\rightarrow u_{13}=\frac{a_{13}}{l_{11}}
  4. l21u12+l22=a22l22=a22l21u12l_{21}u_{12}+l_{22}=a_{22}\rightarrow l_{22} = a_{22}-l_{21}u_{12}
  5. l31u12+l32=a32l32=a32l31u12l_{31}u_{12}+l_{32}=a_{32}\rightarrow l_{32}=a_{32}-l_{31}u_{12}
  6. l21u13+l22u23=a23u23=a23l21u13l22l_{21}u_{13}+l_{22}u_{23}=a_{23}\rightarrow u_{23}=\frac{a_{23}-l_{21}u_{13}}{l_{22}}
  7. l31u13+l32u23+l33=a33l33=a33l31u13l32u23l_{31}u_{13}+l_{32}u_{23}+l_{33}=a_{33}\rightarrow l_{33}=a_{33}-l_{31}u_{13}-l_{32}u_{23}

We can directly find these coefficients for the Crout method with the following:

uij=aijk=1i1likukjlii {i=1...N,j=1...N,j>i}u_{ij} = \frac{a_{ij}-\sum_{k=1}^{i-1}l_{ik}u_{kj}}{l_{ii}}\ \{i=1...N,j=1...N, j> i\} lij=aijk=1j1likukj {i=1...N,j=1...N,ji}l_{ij} = a_{ij} - \sum_{k=1}^{j-1}l_{ik}u_{kj}\ \{i=1...N,j=1...N, j\leq i\}

Crout Method Algorithm

The algorithm is the same as that of the Doolittle method only the part for calculating LL and UU is different.

Crout Method Programs

/*
* Crout LU factorization in C
*/

#include <stdio.h>

// Maximum system size
#define MS 20

void printMat(char *name, double m[][MS], int N)
{
printf("%s:\n", name);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf("%8.3f", m[i][j]);
printf("\n");
}
}

void printVec(char *name, double m[], int N)
{
printf("%s:\n", name);
for (int i = 0; i < N; i++)
printf("%8.3f", m[i]);
printf("\n");
}

int main()
{
// The size of linear system
int N = MS;

// Preallocate enough memory for the system
double A[MS][MS] = {0}, L[MS][MS] = {0}, U[MS][MS] = {0};
double X[MS] = {0}, Y[MS] = {0}, B[MS] = {0};

// Get the size of the system
printf("Enter the size of linear system: ");
scanf("%d", &N);

// Limit the max system size
if (N >= MS)
{
printf("Please enter size below %d", MS);
return -1;
}

// Ask for the coefficients
printf("\nEnter the coefficient matrix A:\n");
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
printf("Enter A[%d][%d] = ", i + 1, j + 1);
scanf("%lf", &A[i][j]);
}
}

// Ask for the constants
printf("\nEnter the constant vector B:\n");
for (int i = 0; i < N; i++)
{
printf("Enter B[%d] = ", i + 1);
scanf("%lf", &B[i]);
}

// Find out the L and U matrices
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (j > i)
{
L[i][j] = 0;
U[i][j] = A[i][j];
for (int k = 0; k < i; k++)
U[i][j] -= L[i][k] * U[k][j];
U[i][j] /= L[i][i];
}
else
{
if (j == i)
U[i][j] = 1;
else
U[i][j] = 0;

L[i][j] = A[i][j];
for (int k = 0; k < j; k++)
L[i][j] -= L[i][k] * U[k][j];
}
}
}
printMat("L", L, N);
printMat("U", U, N);

// Find out Y by solving LY=B using forward substitution
for (int i = 0; i < N; i++)
{
Y[i] = B[i];
for (int j = 0; j < i; j++)
{
Y[i] -= L[i][j] * Y[j];
}
Y[i] /= L[i][i];
}
printVec("Y", Y, N);

// Find out X by solving UX=Y using backward substitution
for (int i = N - 1; i >= 0; i--)
{
X[i] = Y[i];
for (int j = i + 1; j < N; j++)
{
X[i] -= X[j] * U[i][j];
}
}
printVec("\nThe solution X is", X, N);
}

Complexity

The time complexity of the LU Factorization method is O(N3)O(N^3). Similarly, its space complexity is O(N2)O(N^2). However, it uses three times the memory compared to Gauss-Jordan and Gauss-Elimination methods.

Advantages

  1. Since the system is represented with extra matrices/vectors, the precision of calculation is doubled.

Disadvantages

  1. Complicated to implement.
  2. Uses 3 times the memory compared to Gauss-Elimination and Gauss-Jordan methods.