# Nakafa Framework: LLM
URL: https://nakafa.com/en/subject/university/bachelor/ai-ds/linear-methods/lu-decomposition
Source: https://raw.githubusercontent.com/nakafaai/nakafa.com/refs/heads/main/packages/contents/subject/university/bachelor/ai-ds/linear-methods/lu-decomposition/en.mdx
Output docs content for large language models.
---
export const metadata = {
    title: "LU Decomposition",
    description: "Master LU decomposition: factorize matrices into lower/upper triangular forms using Gaussian elimination, with Python implementation and system solving.",
    authors: [{ name: "Nabil Akbarazzima Fatih" }],
    date: "07/13/2025",
    subject: "Linear Methods of AI",
};
## What is LU Decomposition?
LU decomposition is an abbreviation for **Lower-Upper decomposition**. This name comes from the two matrices resulting from decomposition:
- **L (Lower)** = Lower triangular matrix that has zero elements above the main diagonal
- **U (Upper)** = Upper triangular matrix that has zero elements below the main diagonal
Why do we need this decomposition? Because solving linear equation systems with triangular matrices is much easier than with regular matrices.
## Basic Concepts of LU Decomposition
LU decomposition is a way to break down a matrix into the multiplication of two simpler matrices. Imagine we have a complex puzzle, then we disassemble it into pieces that are easier to reassemble.
For a given matrix , we get:
Where  is a permutation matrix (row order arranger),  is a lower triangular matrix, and  is an upper triangular matrix.
Gaussian elimination computes this LU decomposition through a series of systematic row operations. This process can be written as:
with , row exchange matrix  or  and elimination matrix:
The inverse of  is:
Since , we can rewrite this sequence of operations into a simpler form until we finally get .
## Structure of Decomposition Results
From Gaussian elimination with steps , we get three matrices with special structure:
Matrix  is obtained from applying permutation vector  to the rows of the identity matrix. The three matrices have properties:
1.  is an upper triangular matrix in row echelon form with rank 
2.  is a regular lower triangular matrix with 1 on the diagonal
3.  is a permutation matrix with 
## Gaussian Elimination Steps
Let's look at a concrete example. Imagine we are cleaning house floor by floor, starting from the top.
1. **First column** with pivot element . We swap the first and second rows like rearranging furniture positions.
   
   
   
   
   Eliminate other entries in that column: , 
2. **Second column** with pivot element . No exchange needed.
   Elimination: 
3. **Third column** has no pivot element that can be used.
4. **Fourth column** with pivot element . No more operations needed.
Final result:
From this elimination result, we obtain:
The proof shows that  for the initially given matrix .
## Algorithm and Complexity
The Gaussian elimination algorithm works like systematic cleaning. For each column, we perform:
1. Find the best pivot element
2. Swap rows if necessary
3. Eliminate elements below the pivot
4. Store multiplier information
The time complexity for computing LU decomposition is  arithmetic operations. The proof shows that multiplication and addition occur simultaneously in the elimination row transformation .
## Algorithm Implementation in Python
Here is the implementation of the LU decomposition algorithm in Python:
 abs(U[max_row, i]):
                max_row = k
        
        if max_row != i:
            U[[i, max_row]] = U[[max_row, i]]
            P[[i, max_row]] = P[[max_row, i]]
            if i > 0:
                L[[i, max_row], :i] = L[[max_row, i], :i]
        
        for k in range(i + 1, n):
            if U[i, i] != 0:
                factor = U[k, i] / U[i, i]
                L[k, i] = factor
                U[k, i:] = U[k, i:] - factor * U[i, i:]
    
    np.fill_diagonal(L, 1)
    return L, U, P
def forward_substitution(L, b):
    """
    Forward substitution to solve L * y = b
    """
    n = len(b)
    y = np.zeros(n)
    
    for i in range(n):
        y[i] = b[i] - np.dot(L[i, :i], y[:i])
    
    return y
def backward_substitution(U, y):
    """
    Backward substitution to solve U * x = y
    """
    n = len(y)
    x = np.zeros(n)
    
    for i in range(n - 1, -1, -1):
        if U[i, i] != 0:
            x[i] = (y[i] - np.dot(U[i, i+1:], x[i+1:])) / U[i, i]
    
    return x
def solve_linear_system(A, b):
    """
    Solve system Ax = b using LU decomposition
    """
    L, U, P = lu_decomposition(A)
    pb = np.dot(P, b)
    y = forward_substitution(L, pb)
    x = backward_substitution(U, y)
    return x, L, U, P`
}]} />
## Solving Linear Systems
After obtaining LU decomposition, solving the system  becomes like solving a puzzle that has been sorted.
The system  transforms into  through two stages:
### Forward Substitution
The forward substitution algorithm solves  with regular lower triangular matrix  and vector . This process is like filling stairs from bottom to top, where each step depends on the previous step.
For each row , we calculate:
This algorithm is efficient because we only need to calculate one value at each step. The diagonal element  is always 1 for matrix  from LU decomposition, so division becomes simple.
### Backward Substitution
The backward substitution algorithm solves  with matrix  in row echelon form with  steps on columns  and vector .
First, we check whether the system can be solved. If  and there exists  for , then the system has no solution.
If the system can be solved, we initialize kernel matrix  with size , and start with  and .
The algorithm works backward from column  to . For each column, we check whether that column is a pivot step or not.
1. **If column j is a pivot step**, meaning  for step , then we calculate the solution for variable :
   
   And we also calculate the contribution of this variable to the kernel matrix:
   
   
   for , then we decrease  by 1.
2. **If column j is not a pivot step**, meaning there is no pivot in that column, then variable  is a free variable. We set:
   - 
   -  (particular solution)
   -  (kernel basis)
This algorithm produces solution  and matrix  that satisfy  and .
The columns of matrix  form a basis for the kernel (null space) of matrix . This means that each column  is a vector that when multiplied by  produces a zero vector.
The complete solution set is:
## Application Example
Let's see how LU decomposition is used to solve linear systems concretely. Suppose we have vector  and want to solve system .
1. **The first step** is to calculate . Since permutation matrix  swaps the first row with the second row, we get:
   
2. **The second step** is forward substitution to solve . We use the lower triangular matrix  that we have obtained. This process is done from top to bottom like filling stairs one by one.
   For the first row with , we get .
   For the second row with , we get .
   For the third row with , we calculate:
   
   
   
   
   
   So we obtain:
   
3. **The third step** is backward substitution to solve . Matrix  in row echelon form has pivots in columns 1, 2, and 4. Column 3 has no pivot so it becomes a free variable.
   From the backward substitution process, we obtain the particular solution:
   
   and kernel matrix:
   
4. **Result interpretation** is very important to understand. Solution  is one particular solution of the equation system. Matrix  shows the direction in which we can move in the solution space without changing the result of multiplication .
5. **Mathematical verification** shows that for any parameter value , the general solution  still satisfies the original equation.
   Let's prove by calculating . The result is:
   
   
   
   
   Note that , which means vector  is in the null space of matrix . This explains why adding multiples of  to the solution does not change the result.
Compared to computing LU decomposition completely, this forward and backward substitution process is much more efficient for solving linear systems with different right-hand side vectors.