The special case of a system of linear equations that is tridiagonal,
that is, has non-zero elements only on the diagonal plus or minus one
column, is one that occurs frequently. Also common are systems that are band-diagonal, with non-zero elements only along a few diagonal lines
adjacent to the main diagonal (above and below).
For triadiagonal sets, the procedures
LU
-decomposition, forward- and back- substitution each take only
O(n)
operations and the whole
solution can be coded very concisely. In this blog post, I am going to
explore solving triadiagonal matrix systems. I closely follow Daniel
Duffy's exposition in Chapter 13 of his excellent book Financial
Instrument Pricing using C++
Let
A
be a
m×n
general banded matrix with
kl
subdiagonals and
ku
superdiagonals. Then,
aij=0
, when ∣i−j∣>kl+ku+1
. All non-zero elements are positioned on the
main diagonal,
kl
subdiagonals below it and
ku
superdiagonals
above it.
A diagonal matrix is a
n×n
band matrix with
kl=ku=0
.
A Toeplitz matrix is a
n×n
band matrix Tn=[tk,j;k,j=0,1,…,n−1]
where
tk,j=tk−j
. That is,
a matrix of the form:
Consider a two-point boundary value problem on the interval
(0,1)
with Dirichlet boundary conditions:
dx2d2uu(0)u(1)=f(x),0<x<1=ϕ,=ψ
{#eq-two-point-bvp}
We approximate the solution
u
by creating a discrete mesh of
points defined by
xj
,
j=0,…,N
where
N
is a
positive integer. At each interior mesh point the second derivative in
the @eq-two-point-bvp can be approximated by a second-order divided
difference. The corresponding discrete scheme is:
The Thomas algorithm is an efficient way of solving tridiagonal matrix
systems. It is based on
LU
-decomposition in which the matrix system Ax=r
is written as
LUx=r
, where
L
is a lower-triangular
matrix and
U
is an upper triangular matrix. The system can be
efficiently solved by setting
Ux=ρ
and then solving first Lρ=r
and then
Ux=ρ
for
x
. The Thomas algorithm
consists of two steps. In step 1, decomposing the matrix
M=LU
and
solving
Lρ=r
are accomplished in a single downwards sweep, taking
us straight from
Ax=r
to
Ux=ρ
. In step 2, the equation Ux=ρ
is solved for
x
in an upward sweep.
Stage 1
In the first stage, the matrix equation
Ax=r
is converted to the
form
Ux=ρ
. Initially, the matrix equation looks like this:
Continuing in this fashion, we find that,
x6=ρ6
and
xj=ρj−γjxj+1
for all
j=1:5
.
Computational Solution
Let's quickly code up the algorithm in Julia.
function thomasAlgorithm(a,b,c,r)N=size(a)[1]# Stage 1γ=Array{Float64,1}(undef,N)ρ=Array{Float64,1}(undef,N)u=Array{Float64,1}(undef,N)γ[1]=c[1]/b[1]ρ[1]=r[1]/b[1]forj=2:Nγ[j]=c[j]/(b[j]-a[j]*γ[j-1])ρ[j]=(r[j]-a[j]*ρ[j-1])/(b[j]-a[j]*γ[j-1])end# Stage 2u[N]=ρ[N]forj=reverse(1:N-1)u[j]=ρ[j]-γ[j]*u[j+1]endreturnuend# Test Casea=Array{Float64,1}([0,2,2,2])b=Array{Float64,1}([3,3,3,3])c=Array{Float64,1}([2,2,2,0])r=Array{Float64,1}([12,17,14,7])u=thomasAlgorithm(a,b,c,r)print(u)
Consider a slender homogenous rod, lying along the
x
-axis and
insulated, so that no heat can escape across its longitudinal surface.
In addition, we make the simplifying assumption that the temperature in
the rod is constant on each cross-section perpendicular to the x
-axis, and thus that the flow of heat in the rod takes place only
in the
x
-direction.
Consider a small segment of the rod at position
x
of length Δx
.
The thermal energy in this segment at time
t
is:
E(x,x+Δx,t)≈u(x,t)sρΔx
where
s
is the constant of specific heat i.e. amount of heat
required to raise one unit of mass by one unit of temperature,
ρ
is the mass density.
Fourier's law of heat conduction quantifies the idea that heat flows
from warmer to colder regions and states that the (rightward) heat flux
density
ϕ(x,t)
(the flow of heat energy per unit area per unit
time, SI units
J/s/m2
) at any point is:
ϕ(x,t)=−K0ux(x,t)
where
K0
is the thermal conductivity of the rod. The negative sign
shows that the heat flows from higher temperature regions to colder
temperature regions.
Appealing to the law of conservation of energy:
Heat flux through segment∂t∂(u(x,t)sρΔx)=Flux in(−K0ux(x,t))−Flux out(−K0ux(x+Δx,t))
{#eq-heat-content}
Dividing throughout by
Δx
we have:
ut(x,t)≈sρK0Δxux(x+Δx,t)−ux(x,t)
Letting
Δx→0
improves the approximation and leads to the
heat equation:
ut=c2uxx
where
c2=ρsK0
is called the thermal diffusivity.
The Crank-Nicolson and Theta methods
Consider the initial boundary value problem for the
1
d-heat
equation:
In this case, we can assume without the loss of generality that L=1
. Here,
a
,
A
and
B
are constants.
We find a solution to this system in the case when
A=B=0
and a=1
by the method of the separation of variables. In this case,
the analytical solution is:
u(x,t)=π28n=1∑∞n21sin(2nπ)sin(nπx)exp(−n2π2t)
and we are going to use this solution as a benchmark against which the
numerical solutions can be compared.
We can discretize a parabolic PDE in the space dimension (using centered
difference schemes) while keeping the time variable continuous. We
examine the following initial boundary value problem for the
1
d-heat
equation on the unit interval with zero Dirichlet boundary conditions.
Then, we can rewrite the system @eq-IBVP as a system of ordinary
differential equations:
dtdUU(0)=AU=U0
{#eq-heat-eq-1}
where the matrix
A
is given by:
A=h21⎣⎡−2101−2101−2………………10−211−2⎦⎤
There are many discretization schemes. I plan to explore various finite
difference schemes and their application to derivatives pricing in
future posts. For now, I will concentrate on the one-step explicit and
implicit methods to discretise the system of ODEs(@eq-heat-eq-1) as:
ΔtUn+1−UnU0=θAUn+1+(1−θ)AUn,0≤n≤N−1,0≤θ≤1=U(0)
{#eq-heat-eq-2}
In this case,
Δt
is the constant mesh size in time.
We can rewrite @eq-heat-eq-2 in the equivalent form:
When the schemes are implicit, we can solve the system of equations
(@eq-heat-eq-2) at each time level
n+1
using the Thomas algorithm.
No matrix inversion is needed in the case of explicit schemes. The
formulation (@eq-heat-eq-1) is called the method of lines and it
corresponds to semi-discretization of the PDE in the space direction
while keeping the time variable continuous (I will explore MOL in future
posts).
We can write the scheme (@eq-heat-eq-3 - @eq-heat-eq-5) in the component
form:
The system (@eq-finite-difference-scheme) is tridiagonal and we can apply the Thomas algorithm to solve it. In the case of the explicit Euler scheme
(θ=0)
, these algorithms are not needed, because the solution at time level
n+1
can be explicitly computed:
Un+1j=λUnj+1+(1−2λ)Unj+λUnj−1
{#eq-explicit-euler}
Computational Solution
I implemented the algorithm in @eq-finite-difference-scheme. This is a one-step marching scheme called BTCS(Backward in Time, Centered in Space) that computes the solution at time level
n+1
in terms of the solution at time
n
. Since there are three unknowns to be computed at each time level
n+1
, we need to use the Thomas algorithm. The main steps in the algorithm are:
Choose input parameters and generate meshes
Define the initial solution and the boundary conditions
Compute the solution at each time upto and including expiration.
function initialCondition(x::Float64)if(x>=0&&x<=0.50)return2.0*xreturn2.0*(1-x)end# BTCS scheme for the heat equationJ=20
Top comments (0)
Subscribe
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)