Solving Linear Systems with Direct Methods#

Teng-Jui Lin

Content adapted from UW AMATH 301, Beginning Scientific Computing, in Spring 2020.

Matrix inversion#

Given a system Ax=b, we technically have

Ax=bA1Ax=A1bx=A1b

However, we do not use matrix inversion because it is slow, have large error, and not all matrices have an inverse. Singular (non-invertable) matrices have det(A)=0, or cond(A)1015.

Problem Statement. Use matrix inversion to solve the linear system Ax=b where

A=[100110213],x=[xyz],b=[529]
import numpy as np
import scipy
from scipy import linalg
A = np.array([[1, 0, 0], [1, -1, 0], [2, -1, 3]])
b = np.array([5, -2, 9])
# solve by inversion
x = scipy.linalg.inv(A) @ b
x
array([5., 7., 2.])

LU decomposition#

Goal: Solve a system of form Ax=b.

We can decompose the matrix A into an upper triangular matrix L and lower triangular matrix U:

A=LU

so we have

Ax=bLUx=bLy=b

where Ux=y. We can first solve for y, then solve for x. Note that upper triangular and lower triangular matrices are easy to solve, so LU decomposition is faster than Gaussian elimination.

LU decomposition is advantageous when the same A is used to solve many different b.

Problem Statement. Use LU decomposition to solve the linear system Ax=b where

A=[100110213],x=[xyz],b=[529]
A = np.array([[1, 0, 0], [1, -1, 0], [2, -1, 3]])
b = np.array([5, -2, 9])
# solve by LU decomposition
L, U = scipy.linalg.lu(A, permute_l=True)
y = scipy.linalg.solve(L, b)
x = scipy.linalg.solve(U, y)
x
array([5., 7., 2.])

LU decomposition with partial pivoting#

Partial pivoting uses permutation matrix P to change column order, reducing numerical error. In this case, we LU decompose PA:

PAx=PbLUx=PbLy=Pb

where Ux=y. We can then first solve for y, then solve for x.

Problem Statement. Use LU decomposition with partial pivoting to solve the linear system Ax=b where

A=[100110213],x=[xyz],b=[529]
A = np.array([[1, 0, 0], [1, -1, 0], [2, -1, 3]])
b = np.array([5, -2, 9])
# solve by LU decomposition with partial pivoting
P, L, U = scipy.linalg.lu(A)
y = scipy.linalg.solve(L, P@b)
x = scipy.linalg.solve(U, y)
x
array([5., 7., 2.])

Solving linear systems with scipy#

scipy.linalg.solve() directly solves the linear system Ax=b.

Problem Statement. Use scipy.linalg.solve() to solve the linear system Ax=b where

A=[100110213],x=[xyz],b=[529]
A = np.array([[1, 0, 0], [1, -1, 0], [2, -1, 3]])
b = np.array([5, -2, 9])
# solve by scipy
x = scipy.linalg.solve(A, b)
x
array([5., 7., 2.])