LU 分解とは、ある行列 A \boldsymbol{A} A を L \boldsymbol{L} L (下三角行列)と U \boldsymbol{U} U (上三角行列)の積に分解するものです。
LU 分解が役に立つのは、同じ行列に対してベクトルが違う方程式をいくつも解く場合です。 LU 分解自体はガウスの消去法と同じオーダーの計算量となりますが、 LU 分解を用いる場合、分解は方程式がいくつあっても 1 度しか行わないため、その分方程式を解くのにかかる時間は少なくなります
解くべき方程式を A x = b \boldsymbol{A}\boldsymbol{x}=\boldsymbol{b} Ax = b とするとき、 A \boldsymbol{A} A を LU 分解するとします。このとき、
A = L U ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ) = ( l 11 0 ⋯ 0 l 21 l 22 ⋯ 0 ⋮ ⋮ ⋱ ⋮ l n 1 l n 2 ⋯ l n n ) ( u 11 u 12 ⋯ u 1 n 0 u 22 ⋯ u 2 n ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ u n n ) ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ) = ( l 11 u 11 l 11 u 12 ⋯ l 11 u 1 n l 21 u 11 l 21 u 12 + l 22 u 22 ⋯ l 21 u 1 n + l 22 u 2 n ⋮ ⋮ ⋱ ⋮ l n 1 u 11 l n 2 u 12 + l n 2 u 22 ⋯ ∑ i = 1 n l n i u i n ) \begin{aligned}
\boldsymbol{A} & =\boldsymbol{L}\boldsymbol{U}\\
\left(\begin{array}{cccc}
a_{11} & a_{12} & \cdots & a_{1n}\\
a_{21} & a_{22} & \cdots & a_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
a_{n1} & a_{n2} & \cdots & a_{nn}
\end{array}\right) & =\left(\begin{array}{cccc}
l_{11} & 0 & \cdots & 0\\
l_{21} & l_{22} & \cdots & 0\\
\vdots & \vdots & \ddots & \vdots\\
l_{n1} & l_{n2} & \cdots & l_{nn}
\end{array}\right)\left(\begin{array}{cccc}
u_{11} & u_{12} & \cdots & u_{1n}\\
0 & u_{22} & \cdots & u_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
0 & 0 & \cdots & u_{nn}
\end{array}\right)\\
\left(\begin{array}{cccc}
a_{11} & a_{12} & \cdots & a_{1n}\\
a_{21} & a_{22} & \cdots & a_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
a_{n1} & a_{n2} & \cdots & a_{nn}
\end{array}\right) & =\left(\begin{array}{cccc}
l_{11}u_{11} & l_{11}u_{12} & \cdots & l_{11}u_{1n}\\
l_{21}u_{11} & l_{21}u_{12}+l_{22}u_{22} & \cdots & l_{21}u_{1n}+l_{22}u_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
l_{n1}u_{11} & l_{n2}u_{12}+l_{n2}u_{22} & \cdots & \sum_{i=1}^{n}l_{ni}u_{in}
\end{array}\right)
\end{aligned} A a 11 a 21 ⋮ a n 1 a 12 a 22 ⋮ a n 2 ⋯ ⋯ ⋱ ⋯ a 1 n a 2 n ⋮ a nn a 11 a 21 ⋮ a n 1 a 12 a 22 ⋮ a n 2 ⋯ ⋯ ⋱ ⋯ a 1 n a 2 n ⋮ a nn = LU = l 11 l 21 ⋮ l n 1 0 l 22 ⋮ l n 2 ⋯ ⋯ ⋱ ⋯ 0 0 ⋮ l nn u 11 0 ⋮ 0 u 12 u 22 ⋮ 0 ⋯ ⋯ ⋱ ⋯ u 1 n u 2 n ⋮ u nn = l 11 u 11 l 21 u 11 ⋮ l n 1 u 11 l 11 u 12 l 21 u 12 + l 22 u 22 ⋮ l n 2 u 12 + l n 2 u 22 ⋯ ⋯ ⋱ ⋯ l 11 u 1 n l 21 u 1 n + l 22 u 2 n ⋮ ∑ i = 1 n l ni u in
であることより、 L \boldsymbol{L} L と U \boldsymbol{U} U の要素は下のように計算されます。
u 1 j = a 1 j l 11 l i 1 = a i 1 u 11 u i j = a i j − ∑ k = 1 i l i k u k j l i i l i j = a i j − ∑ k = 1 i − 2 l j k u k i u i i \begin{aligned}
u_{1j} & =\frac{a_{1j}}{l_{11}}\\
l_{i1} & =\frac{a_{i1}}{u_{11}}\\
u_{ij} & =\frac{a_{ij}-\sum_{k=1}^{i}l_{ik}u_{kj}}{l_{ii}}\\
l_{ij} & =\frac{a_{ij}-\sum_{k=1}^{i-2}l_{jk}u_{ki}}{u_{ii}}
\end{aligned} u 1 j l i 1 u ij l ij = l 11 a 1 j = u 11 a i 1 = l ii a ij − ∑ k = 1 i l ik u kj = u ii a ij − ∑ k = 1 i − 2 l jk u ki
プログラムで実装する際、 L \boldsymbol{L} L の対角要素を 1 1 1 と決めておくことにより、 L \boldsymbol{L} L と U \boldsymbol{U} U の要素の算出を同時に行い、2 つまとめて A \boldsymbol{A} A として保持するという処理が行われます。処理・領域の効率が良いので、プログラムでは大抵この技法を取っています。
これらの行列から x \boldsymbol{x} x を求めるためには、計算の間に新たなベクトル y \boldsymbol{y} y を置くようにすることで、
A x = b L U x = b U x = y L y = b \begin{aligned}
\boldsymbol{A}\boldsymbol{x} & =\boldsymbol{b}\\
\boldsymbol{L}\boldsymbol{U}\boldsymbol{x} & =\boldsymbol{b}\\
\boldsymbol{U}\boldsymbol{x} & =\boldsymbol{y}\\
\boldsymbol{L}\boldsymbol{y} & =\boldsymbol{b}
\end{aligned} Ax LUx Ux Ly = b = b = y = b
という式を使って解いていきます。この処理は以前の処理と似ており、
L y = b ( l 11 0 ⋯ 0 l 21 l 22 ⋯ 0 ⋮ ⋮ ⋱ ⋮ l n 1 l n 2 ⋯ l n n ) ( y 1 y 2 ⋮ y n ) = ( b 1 b 2 ⋮ b n ) ( y 1 y 2 ⋮ y n ) = ( b 1 l 11 b 2 − l 21 y 1 l 22 ⋮ b n − ∑ i = 1 n − 1 l n i y i l n n ) ( y 1 y 2 ⋮ y n ) = ( b 1 b 2 − l 21 y 1 ⋮ b n − ∑ i = 1 n − 1 l n i y i ) ( ∵ l i i = 1 ) \begin{aligned}
\boldsymbol{L}\boldsymbol{y} & =\boldsymbol{b}\\
\left(\begin{array}{cccc}
l_{11} & 0 & \cdots & 0\\
l_{21} & l_{22} & \cdots & 0\\
\vdots & \vdots & \ddots & \vdots\\
l_{n1} & l_{n2} & \cdots & l_{nn}
\end{array}\right)\left(\begin{array}{c}
y_{1}\\
y_{2}\\
\vdots\\
y_{n}
\end{array}\right) & =\left(\begin{array}{c}
b_{1}\\
b_{2}\\
\vdots\\
b_{n}
\end{array}\right)\\
\left(\begin{array}{c}
y_{1}\\
y_{2}\\
\vdots\\
y_{n}
\end{array}\right) & =\left(\begin{array}{c}
\frac{b_{1}}{l_{11}}\\
\frac{b_{2}-l_{21}y_{1}}{l_{22}}\\
\vdots\\
\frac{b_{n}-\sum_{i=1}^{n-1}l_{ni}y_{i}}{l_{nn}}
\end{array}\right)\\
\left(\begin{array}{c}
y_{1}\\
y_{2}\\
\vdots\\
y_{n}
\end{array}\right) & =\left(\begin{array}{c}
b_{1}\\
b_{2}-l_{21}y_{1}\\
\vdots\\
b_{n}-\sum_{i=1}^{n-1}l_{ni}y_{i}
\end{array}\right)\;\left(\because l_{ii}=1\right)
\end{aligned} Ly l 11 l 21 ⋮ l n 1 0 l 22 ⋮ l n 2 ⋯ ⋯ ⋱ ⋯ 0 0 ⋮ l nn y 1 y 2 ⋮ y n y 1 y 2 ⋮ y n y 1 y 2 ⋮ y n = b = b 1 b 2 ⋮ b n = l 11 b 1 l 22 b 2 − l 21 y 1 ⋮ l nn b n − ∑ i = 1 n − 1 l ni y i = b 1 b 2 − l 21 y 1 ⋮ b n − ∑ i = 1 n − 1 l ni y i ( ∵ l ii = 1 )
によってまず y \boldsymbol{y} y を求め、それから
U x = y ( u 11 u 12 ⋯ u 1 n 0 u 22 ⋯ u 2 n ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ u n n ) ( x 1 x 2 ⋮ x n ) = ( y 1 y 2 ⋮ y n ) ( x 1 x 2 ⋮ x n ) = ( y 1 − ∑ i = 2 n u 1 i y i u 11 y 2 − ∑ i = 3 n u 2 i y i u 22 ⋮ y n u n n ) \begin{aligned}
\boldsymbol{U}\boldsymbol{x} & =\boldsymbol{y}\\
\left(\begin{array}{cccc}
u_{11} & u_{12} & \cdots & u_{1n}\\
0 & u_{22} & \cdots & u_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
0 & 0 & \cdots & u_{nn}
\end{array}\right)\left(\begin{array}{c}
x_{1}\\
x_{2}\\
\vdots\\
x_{n}
\end{array}\right) & =\left(\begin{array}{c}
y_{1}\\
y_{2}\\
\vdots\\
y_{n}
\end{array}\right)\\
\left(\begin{array}{c}
x_{1}\\
x_{2}\\
\vdots\\
x_{n}
\end{array}\right) & =\left(\begin{array}{c}
\frac{y_{1}-\sum_{i=2}^{n}u_{1i}y_{i}}{u_{11}}\\
\frac{y_{2}-\sum_{i=3}^{n}u_{2i}y_{i}}{u_{22}}\\
\vdots\\
\frac{y_{n}}{u_{nn}}
\end{array}\right)
\end{aligned} Ux u 11 0 ⋮ 0 u 12 u 22 ⋮ 0 ⋯ ⋯ ⋱ ⋯ u 1 n u 2 n ⋮ u nn x 1 x 2 ⋮ x n x 1 x 2 ⋮ x n = y = y 1 y 2 ⋮ y n = u 11 y 1 − ∑ i = 2 n u 1 i y i u 22 y 2 − ∑ i = 3 n u 2 i y i ⋮ u nn y n
によって