In numerical linear algebra, the tridiagonal matrix algorithm, also known as the Thomas algorithm (named after Llewellyn Thomas), is a simplified form of Gaussian elimination that can be used to solve tridiagonal systems of equations. A tridiagonal system for n unknowns may be written as
aixi-1+bixi+cixi+1=di,
a1=0
cn=0
\begin{bmatrix} b1&c1&&&0\\ a2&b2&c2&&\\ &a3&b3&\ddots&\\ &&\ddots&\ddots&cn-1\\ 0&&&an&bn \end{bmatrix} \begin{bmatrix} x1\\ x2\\ x3\\ \vdots\\ xn \end{bmatrix} = \begin{bmatrix} d1\\ d2\\ d3\\ \vdots\\ dn \end{bmatrix} .
For such systems, the solution can be obtained in
O(n)
O(n3)
ai
Thomas' algorithm is not stable in general, but is so in several special cases, such as when the matrix is diagonally dominant (either by rows or columns) or symmetric positive definite;[1] for a more precise characterization of stability of Thomas' algorithm, see Higham Theorem 9.12.[2] If stability is required in the general case, Gaussian elimination with partial pivoting (GEPP) is recommended instead.[3]
The forward sweep consists of the computation of new coefficients as follows, denoting the new coefficients with primes:
c'i= \begin{cases} \cfrac{ci}{bi},&i=1,\\ \cfrac{ci}{bi-aic'i
and
d'i= \begin{cases} \cfrac{di}{bi},&i=1,\\ \cfrac{di-aid'i
The solution is then obtained by back substitution:
xn=d'n,
xi=d'i-c'ixi, i=n-1,n-2,\ldots,1.
The method above does not modify the original coefficient vectors, but must also keep track of the new coefficients. If the coefficient vectors may be modified, then an algorithm with less bookkeeping is:
For
i=2,3,...,n,
w=\cfrac{ai}{bi-1
bi:=bi-wci-1,
di:=di-wdi-1,
followed by the back substitution
xn=\cfrac{dn}{bn},
xi=\cfrac{di-cixi+1
The implementation as a C function, which uses scratch space to avoid modifying its inputs for a-c, allowing them to be reused:
The derivation of the tridiagonal matrix algorithm is a special case of Gaussian elimination.
Suppose that the unknowns are
x1,\ldots,xn
\begin{alignat}{4} &&&b1x1&&+c1x2&&=d1\\ &aixi&&+bixi&&+cixi&&=di, i=2,\ldots,n-1\\ &anxn&&+bnxn&&&&=dn. \end{alignat}
Consider modifying the second (
i=2
(equation2) ⋅ b1-(equation1) ⋅ a2
which would give:
(b2b1-c1a2)x2+c2b1x3=d2b1-d1a2.
Note that
x1
(b3(b2b1-c1a2)-c2b1a3)x3+c3(b2b1-c1a2)x4 =d3(b2b1-c1a2)-(d2b1-d1a2)a3.
This time
x2
nth
nth
xn
(n-1)th
Clearly, the coefficients on the modified equations get more and more complicated if stated explicitly. By examining the procedure, the modified coefficients (notated with tildes) may instead be defined recursively:
\tildeai=0
\tildeb1=b1
\tildebi=bi\tildebi-\tildeciai
\tildec1=c1
\tildeci=ci\tildebi
\tilded1=d1
\tildedi=di\tildebi-\tildediai.
To further hasten the solution process,
\tildebi
a'i=0
b'i=1
c'1=
c1 | |
b1 |
c'i=
ci | |
bi-c'iai |
d'1=
d1 | |
b1 |
d'i=
di-d'iai | |
bi-c'iai |
.
This gives the following system with the same unknowns and coefficients defined in terms of the original ones above:
\begin{array}{lcl} xi+c'ixi=d'i &;& i=1,\ldots,n-1\\ xn=d'n &;& i=n.\\ \end{array}
The last equation involves only one unknown. Solving it in turn reduces the next last equation to one unknown, so that this backward substitution can be used to find all of the unknowns:
xn=d'n
xi=d'i-c'ixi ; i=n-1,n-2,\ldots,1.
In some situations, particularly those involving periodic boundary conditions, a slightly perturbed form of the tridiagonal system may need to be solved:
\begin{alignat}{4} &a1xn&&+b1x1&&+c1x2&&=d1\\ &aixi&&+bixi&&+cixi&&=di, i=2,\ldots,n-1\\ &anxn&&+bnxn&&+cnx1&&=dn. \end{alignat}
In this case, we can make use of the Sherman–Morrison formula to avoid the additional operations of Gaussian elimination and still use the Thomas algorithm. The method requires solving a modified non-cyclic version of the system for both the input and a sparse corrective vector, and then combining the solutions. This can be done efficiently if both solutions are computed at once, as the forward portion of the pure tridiagonal matrix algorithm can be shared.
If we indicate by:
Then the system to be solved is:
In this case the coefficients
a1
cn
B\inRn x
u,v\inRn
\gamma\inR
A
A=B+uvT
Then we reconstruct the solution
x
The implementation as a C function, which uses scratch space to avoid modifying its inputs for a-c, allowing them to be reused:
There is also another way to solve the slightly perturbed form of the tridiagonal system considered above. Let us consider two auxiliary linear systems of dimension
(n-1) x (n-1)
For convenience, we additionally define
u1=0
v1=1
\{u2,u3...,un\}
\{v2,v3...,vn\}
The solution
\{x1,x2...,xn\}
Indeed, multiplying each equation of the second auxiliary system by
x1
xi=ui+x1vi
2
n
1
i=2
i=n
x2=u2+x1v2
xn=un+x1vn
x1
As such, we find:
The implementation as a C function, which uses scratch space to avoid modifying its inputs for a-c, allowing them to be reused:
In both cases the auxiliary systems to be solved are genuinely tri-diagonal, so the overall computational complexity of solving system
Ax=d
n
O(n)
In other situations, the system of equations may be block tridiagonal (see block matrix), with smaller submatrices arranged as the individual elements in the above matrix system (e.g., the 2D Poisson problem). Simplified forms of Gaussian elimination have been developed for these situations.[5]
The textbook Numerical Mathematics by Alfio Quarteroni, Sacco and Saleri, lists a modified version of the algorithm which avoids some of the divisions (using instead multiplications), which is beneficial on some computer architectures.
Parallel tridiagonal solvers have been published for many vector and parallel architectures, including GPUs[6] [7]
For an extensive treatment of parallel tridiagonal and block tridiagonal solvers see [8]