1+ % tridiagonal matrix solver for x in Ax = d
2+ function [alpha , beta , z , x ] = tridiag_lu_decomp(n , a , b , c , d )
3+ % INPUT
4+ % n: size of matrix A
5+ % a: diagonal values of A
6+ % b: lower diagonal values of A (1st value will be ignored)
7+ % c: upper diagonal values of A (nth value will be ignored)
8+ % d: vector in Ax = d
9+ % following criteria must be met for the script to work
10+ % |a1| > |c1|, |an| > |bn|
11+ % |ai| >= |bi| + |ci| and bici != 0 for i = 2,3,...,n-1
12+
13+ % OUTPUT
14+ % alpha: diagonal values of U (upper diagonal values are c)
15+ % beta: lower diagonal values of L (diagonal values are 1)
16+ % z: vector values of z = Ux
17+ % x: solution (vector values of x in Ax = d)
18+
19+ % validate input
20+ assert(n > 2 , ' n must be > 2' ) % tridiagonal
21+ assert(length(a ) == n , ' length of a should be n' )
22+ assert(length(b ) == n , ' length of b should be n' )
23+ assert(length(c ) == n , ' length of c should be n' )
24+ assert(length(d ) == n , ' length of d should be n' )
25+ assert(abs(a(1 )) > abs(c(1 )), ' criteria not met: |a1| > |c1|' )
26+ assert(abs(a(n )) > abs(c(n )), ' criteria not met: |an| > |cn|' )
27+ for i= 2 : n - 1
28+ assert(b(i )*c(i ) ~= 0 , ' criteria not met b%d * c%d != 0' , i , i )
29+ assert(abs(a(i )) >= abs(b(i )) + abs(c(i )), ...
30+ ' criteria not met: |a%d | >= |b%d | + |c%d |' , i , i , i )
31+ end
32+
33+ % create vectors for output
34+ alpha = zeros(1 ,n );
35+ beta = zeros(1 ,n );
36+ z = zeros(1 ,n );
37+ x = zeros(1 ,n );
38+
39+ % find the LU decomp of A
40+ alpha(1 ) = a(1 );
41+ for i= 2 : n
42+ beta(i ) = b(i ) / alpha(i - 1 );
43+ alpha(i ) = a(i ) - (beta(i )*c(i - 1 ));
44+ end
45+
46+ % now have LUx = d
47+ % (forward) substitution: z = Ux --> Lz = d
48+ z(1 )= d(1 ); % z1 = d1;
49+ for i= 2 : n
50+ z(i ) = d(i ) - (beta(i )*z(i - 1 ));
51+ end
52+
53+ % (backward) substitution: z = Ux
54+ x(n ) = z(n ) / alpha(n );
55+ for i= n - 1 : -1 : 1
56+ x(i ) = (z(i ) - (c(i )*x(i + 1 )))/alpha(i );
57+ end
0 commit comments