Logo

矩阵分解

1. 矩阵分解的概念

矩阵分解是将一个矩阵表示为多个矩阵乘积的方法。它对复杂的矩阵进行预处理,简化数据的计算和处理。在计算机科学中,矩阵分解是一项常用技术,通过将矩阵拆分为具有特定结构的部分,提高了矩阵运算的效率,特别适用于大规模数据处理和数值计算。请看下面的矩阵分解过程:

上面这种分解方式将矩阵 A ~\mathbf{A}~分解为下三角矩阵( Lower triangular matrix~\textcolor{red}{L}ower~triangular~matrixL \mathbf{L}~和上三角矩阵( Upper triangular matrix~\textcolor{red}{U}pper~triangular~matrixU \mathbf{U}~,这种分解方式被称为 LU ~\mathbf{LU}~分解。示例中的下三角矩阵 L ~\mathbf{L}~对角线元素都是 1 ~1~,它又叫单位下三角矩阵,满足这个条件的分解法就是标准的 LU ~\mathbf{LU}~分解算法。在矩阵运算中,将原始矩阵转化为三角矩阵可以显著提升计算效率。

2. LU ~\mathbf{LU}~分解解线性方程组

 LU ~\mathbf{LU}~分解在许多应用场景中非常重要,尤其是在解线性方程组、矩阵求逆和特征值计算等方面,它能显著提高计算效率。接下来,我们以求解线性方程组为例,来理解 LU ~\mathbf{LU}~分解如何应用于实际问题。

在实际的工业和科研应用中,解线性方程组是非常常见的任务,尤其是多个方程组共享相同的系数矩阵的情况。例如:
Ax=b1,Ax=b2,,Ax=bp\mathbf{Ax} = \mathbf{b}_1, \quad \mathbf{Ax} = \mathbf{b}_2, \quad \dots, \quad \mathbf{Ax} = \mathbf{b}_p
此时,矩阵 A ~\mathbf{A}~是相同的,而向量( b1,b2,,bp ~\mathbf{b}_1,\mathbf{b}_2, \dots, \mathbf{b}_p~) 是不同的。传统方法是通过直接行列式或高斯消元法来求解每个方程组,但这种方法效率较低,特别是当方程组数量 p ~p~较大时。通过 LU ~\mathbf{LU}~分解,可以将矩阵 A ~\mathbf{A}~分解为两个简单的三角矩阵 L ~\mathbf{L}~ U ~\mathbf{U}~,然后在第一次求解时进行一次分解,后续的方程组只需要基于这个分解进行较为简单的运算即可。这样,解每个方程组的效率大大提高。具体来说, LU ~\mathbf{LU}~分解允许我们将方程组 Ax=b ~\mathbf{Ax}=\mathbf{b}~转化为两个更容易求解的方程组:
Ax=(LU)x=L(Ux)=bLy=b,Ux=y\begin{align*}\mathbf{Ax}=(\mathbf{LU})\mathbf{x} = \mathbf{L}(\mathbf{Ux})=\mathbf{b} \\[2ex] \Rightarrow \quad \mathbf{Ly}=\mathbf{b},\quad \mathbf{Ux} = \mathbf{y} \end{align*}
这两个方程组可以通过前代回代来分别求解,复杂度远低于直接求解原方程组。请看下面案例:

首先,我们将矩阵 A ~\mathbf{A}~分解为下三角矩阵 L ~\mathbf{L}~和上三角矩阵 U ~\mathbf{U}~,使得: A=LU ~\mathbf{A}=\mathbf{LU}~,对于矩阵 A ~\mathbf{A}~,通过 LU ~\mathbf{LU}~分解得到:
L=[100210331],U=[231010002]\mathbf{L} = \begin{bmatrix} 1 & 0 & 0 \\ 2 & 1 & 0 \\ 3 & 3 & 1 \end{bmatrix}, \quad \mathbf{U} = \begin{bmatrix} 2 & 3 & 1 \\ 0 & 1 & 0 \\ 0 & 0 & 2 \end{bmatrix}

我们要先求解方程 Ly=b ~\mathbf{Ly}=\mathbf{b}~,这是一个前代问题,因为 L ~L~是下三角矩阵。方程形式如下:
[100210331][y1y2y3]=[51020]y=[505]\begin{bmatrix} 1 & 0 & 0 \\ 2 & 1 & 0 \\ 3 & 3 & 1 \end{bmatrix} \begin{bmatrix} y_1 \\ y_2 \\ y_3 \end{bmatrix} = \begin{bmatrix} 5 \\ 10 \\ 20 \end{bmatrix}\quad \Rightarrow \quad \mathbf{y}=\begin{bmatrix} 5 \\ 0 \\ 5 \end{bmatrix}

求解方程  Ux=y ~\mathbf{Ux}=y~,这是一个回代问题,因为 U ~\mathbf{U}~是上三角矩阵。方程形式如下:
[231010002][x1x2x3]=[505]x=[5/405/2]\begin{bmatrix} 2 & 3 & 1 \\ 0 & 1 & 0 \\ 0 & 0 & 2 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} = \begin{bmatrix} 5 \\ 0 \\ 5 \end{bmatrix}\quad \Rightarrow \quad \mathbf{x}=\begin{bmatrix}5/4 \\ 0 \\ 5/2 \end{bmatrix}

3. LU ~\mathbf{LU}~分解算法

LU \mathbf{LU}~分解可以通过初等行变换来实现。我们不断地对矩阵 A ~\mathbf{A}~施加初等行变换(左乘初等矩阵)先得到上三角矩阵 U ~\mathbf{U}~
(EpE1)A=U(\mathbf{E}_p \dots \mathbf{E}_1)\mathbf{A}=\mathbf{U}
我们在上面的等式两边乘以初等矩阵乘积的逆,就可以分解出 L,U ~\mathbf{L},\mathbf{U}~
A=(EpE1)1U=LU\mathbf{A}=\textcolor{red}{(\mathbf{E}_p\dots \mathbf{E}_1)^{-1}}\mathbf{U}=\textcolor{red}{\mathbf{L}}\mathbf{U}
请观察下面分解矩阵 A ~\mathbf{A}~的过程:
观察上面的分解过程可以发现,对 A ~\mathbf{A}~进行 LU ~\mathbf{LU}~分解时,我们只使用了行倍加变换 ( row replacements ) ~(~\text{row replacements}~)~,这样做是为了保证 LU ~\mathbf{LU}~分解是唯一的。要满足只使用行倍加进行矩阵行化简的条件,我们就要保证在矩阵化简的过程中不能出现零主元(也就是矩阵 U ~\mathbf{U}~的主元不能出现零),这种方法可以归类为一般的 LU ~\mathbf{LU}~分解

4. PLU ~\mathbf{PLU}~分解

在实际分解过程中,我们通常会遇到主元为零或过小导致无法继续进行分解、或产生数值不稳定的情况。这时,我们会使用到行交换 ( row interchanges ) ~(~\textbf{row interchanges}~)~来进行 LU ~\mathbf{LU}~分解,这种分解方式是带行交换的 LU ~\mathbf{LU}~分解。它的分解形式为:

A=PLU\mathbf{A}=\mathbf{PLU}

,所以通常我们称这种分解法为 PLU ~\mathbf{PLU}~分解,其中 P ~\mathbf{P}~表示置换矩阵 ( Permutation matrix ) ~(~\textbf{Permutation~matrix}~)~。请观察下面的示例:

上面这个矩阵 A ~\mathbf{A}~的第一个主元就是 0 ~0~,所以我们需要尝试使用  PLU ~\mathbf{PLU}~分解。注意,分解出的 U ~\mathbf{U}~的主元都不为  0 ~0~。 不过,由于我们可以选择不同的行交换方式(也就是置换矩阵 P ~\mathbf{P}~不唯一),所以我们不能保证分解得到的 L,U ~\mathbf{L},\mathbf{U}~是唯一的。请观察下面的分解过程:

上面的这次分解中,我们选择不同的置换矩阵,得到了不同的分解结果。除非,我们固定主元选取的策略,例如每次总是选择绝对值最大的元素(对于相等的元素设置固定的选择规则)进行行交换,那么 PLU ~\mathbf{PLU}~分解也可以是唯一的。事实上,所有的方阵都可以写成 PLU ~\mathbf{PLU}~分解的形式。例如下面这个矩阵也可以进行 PLU ~\mathbf{PLU}~分解:

上面的分解过程是一般的 LU ~\mathbf{LU}~分解,它也可以写成 PLU ~\mathbf{PLU}~的形式,只不过此时的 P ~\mathbf{P}~表示单位矩阵。另外,上面的矩阵 A ~\mathbf{A}~明显是个奇异矩阵,虽然奇异矩阵也可以进行一般的 LU~\mathbf{LU}PLU\mathbf{PLU})分解,但分解结果通常包含零行或退化结构,因此在解线性方程组或计算矩阵逆等实际应用中价值有限(还不如不分解)。相反,若将 LU~\mathbf{LU}PLU \mathbf{PLU}~)分解限制于可逆矩阵,不仅能够有效地求解线性方程、计算矩阵的逆,还能保证分解的唯一性和数值稳定性。总之,对可逆矩阵进行 LU~\mathbf{LU}PLU\mathbf{PLU})分解通常更“划算”。

5. LU ~\mathbf{LU}~分解的计算效率

解线性方程组 Ax=b ~\mathbf{Ax}=\mathbf{b}~的传统方法是高斯消元法,其计算复杂度大约 O(n3) ~O(n^3)~。这意味着对于一个大小为 n×n ~n\times n~的矩阵,计算量是随矩阵维度 n ~n~的三次方增长的。这在处理大规模矩阵时会变得非常昂贵,尤其是当矩阵规模较大(如数千维度的矩阵)时,计算时间和资源消耗会急剧增加。LU \mathbf{LU}~分解的

复杂度也是 O(n3) ~O(n^3)~

,与高斯消元法相同,但一旦 LU ~\mathbf{LU}~分解完成,后续的多次求解只需 O(n2) ~O(n^2)~的计算量。下面的图表可以直观展示两种不同算法的对比:

上面两张图表展示了当方程组的系数矩阵大小分别为 10×10 ~10\times 10~ 100×100 ~100\times 100~时,两种算法的时间复杂度随着方程组数量 p 增加的变化情况。高斯消元法的复杂度为 O(pn3) ~O(p\cdot n^3)~ LU ~\mathbf{LU}~分解的复杂度为 O(n3)+pO(n2) ~O(n^3)+p\cdot O(n^2)~,也就是说,当求解的方程组的数量( p ~p~)越多、方程组的系数矩阵规模( n ~n~)越大, LU ~\mathbf{LU}~分解相对高斯消元法的优势越明显。