概览

本节介绍如何利用 LUP 分解 高效求解线性方程组 。核心思想是将一个 的线性方程组分解为三个计算上更简单的步骤:首先对矩阵 进行 LUP 分解得到 ,然后通过前代(forward substitution)求解下三角方程组 ,最后通过回代(back substitution)求解上三角方程组 。整个求解过程的计算复杂度为 (分解)加 (求解),当需要求解多个具有相同系数矩阵但不同右端向量的方程组时,分解只需执行一次,后续每次求解仅需


知识结构总览

flowchart TD
    A["线性方程组<br/>a₁₁x₁ + a₁₂x₂ + ... + a₁ₙxₙ = b₁<br/>a₂₁x₁ + a₂₂x₂ + ... + a₂ₙxₙ = b₂<br/>...<br/>aₙ₁x₁ + aₙ₂x₂ + ... + aₙₙxₙ = bₙ"]
    B["矩阵形式<br/>Ax = b"]
    C["LUP 分解<br/>PA = LU"]
    D["前代<br/>Ly = Pb"]
    E["回代<br/>Ux = y"]
    F["解向量 x"]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F

    C --- C1["L: 单位下三角矩阵<br/>U: 上三角矩阵<br/>P: 置换矩阵"]
    D --- D1["时间: Θ(n²)"]
    E --- E1["时间: Θ(n²)"]
    C --- C2["时间: Θ(n³)"]

知识依赖关系

前置知识本节内容后续内容
4.1 矩阵乘法LUP 分解与求解28.2 矩阵求逆
第04章_分治策略-章节汇总前代与回代28.3 对称正定矩阵
矩阵基本运算正确性证明与复杂度分析第28章_矩阵运算-章节汇总

核心思想

2.1 线性方程组的矩阵表示

含有 个未知数、 个方程的线性方程组可以写成如下形式:

将其写成紧凑的矩阵-向量乘法形式:

其中 是一个 系数矩阵未知向量右端向量

求解线性方程组的目标是:给定 ,找到满足 的向量

生活化类比:想象你在解一个谜题——已知一组食材的混合配方(矩阵 )和最终成品的营养成分(向量 ),需要反推出每种食材的用量(向量 )。LUP 分解就像先把复杂配方拆解成几个简单步骤,然后逐步求解。

2.2 LUP 分解的定义

LUP 分解是将矩阵 分解为三个矩阵乘积的形式:

其中:

  • (Lower triangular)单位下三角矩阵,即对角线元素全为 1,对角线以下的元素可以非零,对角线以上的元素全为 0。
  • (Upper triangular)上三角矩阵,即对角线以下的元素全为 0,对角线及以上的元素可以非零。
  • (Permutation)置换矩阵,即单位矩阵的行经过重新排列后得到的矩阵,每一行和每一列恰好有一个 1,其余元素为 0。

用数学语言精确描述:

为什么需要置换矩阵 并非所有矩阵都能直接分解为 的形式。例如,当主元位置(消元过程中对角线位置)出现 0 时,消元过程无法继续。置换矩阵 通过交换矩阵 的行来避免主元为零的情况,确保分解过程始终可行。对于任意非奇异矩阵 ,LUP 分解一定存在。

2.3 前代(Forward Substitution)

LUP 分解完成后,原方程组 等价于:

代入:

,则先求解下三角方程组:

由于 是单位下三角矩阵,这个方程组可以从上到下逐个求解:

前代算法 LUP-SOLVE 中的前代部分

// 求解 Ly = Pb(前代)
for i ← 1 to n
    y[i] ← (Pb)[i]
    for j ← 1 to i - 1
        y[i] ← y[i] - L[i][j] × y[j]

时间复杂度:外层循环执行 次,内层循环分别执行 次,总操作次数为

2.4 回代(Back Substitution)

求得 之后,再求解上三角方程组:

由于 是上三角矩阵,这个方程组可以从下到上逐个求解:

回代算法 LUP-SOLVE 中的回代部分

// 求解 Ux = y(回代)
for i ← n downto 1
    x[i] ← y[i]
    for j ← i + 1 to n
        x[i] ← x[i] - U[i][j] × x[j]
    x[i] ← x[i] / U[i][i]

时间复杂度:与前代对称,总操作次数为

2.5 算法执行流程

LUP 分解求解线性方程组的完整流程

步骤一:LUP 分解 对系数矩阵 A 执行 LUP-DECOMPOSITION,得到 L、U、P 三个矩阵。时间复杂度 Θ(n³)。

步骤二:计算置换后的右端向量 用置换矩阵 P 对右端向量 b 做行置换,得到 Pb。

步骤三:前代求解 利用下三角矩阵 L,求解 Ly = Pb,得到中间向量 y。时间复杂度 Θ(n²)。

步骤四:回代求解 利用上三角矩阵 U,求解 Ux = y,得到最终解向量 x。时间复杂度 Θ(n²)。

关键优势:当需要求解多个具有相同系数矩阵 A 但不同右端向量的方程组时,LUP 分解只需执行一次,后续每次求解仅需 Θ(n²)。

flowchart LR
    A["输入: A, b"] --> B["LUP-DECOMPOSITION<br/>得到 L, U, P<br/>Θ(n³)"]
    B --> C["计算 Pb"]
    C --> D["前代: Ly = Pb<br/>得到 y<br/>Θ(n²)"]
    D --> E["回代: Ux = y<br/>得到 x<br/>Θ(n²)"]
    E --> F["输出: 解向量 x"]

2.6 LUP-SOLVE 伪代码

LUP-SOLVE(L, U, π, b)
// 输入: 单位下三角矩阵 L, 上三角矩阵 U, 置换向量 π, 右端向量 b
// 输出: 方程组 Ax = b 的解 x,其中 PA = LU, π 记录了 P 的置换信息
// π[i] = k 表示 P 的第 i 行是 I 的第 k 行

  n ← L.rows
  // 步骤一: 计算 Pb,同时执行前代求解 Ly = Pb
  for i ← 1 to n
      x[i] ← b[π[i]]           // 置换 b 的第 i 个分量
      for j ← 1 to i - 1
          x[i] ← x[i] - L[i][j] × x[j]
  // 步骤二: 回代求解 Ux = y(此时 x 中存储的是 y)
  for i ← n downto 1
      for j ← i + 1 to n
          x[i] ← x[i] - U[i][j] × x[j]
      x[i] ← x[i] / U[i][i]
  return x

代码解读

  • 第 5-8 行:将置换前代合并在一起。x[i] ← b[π[i]] 完成了对 的置换,内层循环完成前代。
  • 第 9-13 行:回代阶段,从最后一个分量 开始,逐步向前求解。
  • 注意第 13 行的除法 x[i] / U[i][i],这里要求 ,即矩阵 必须是非奇异的。

2.7 LUP-DECOMPOSITION 伪代码

LUP-DECOMPOSITION(A)
// 输入: n×n 矩阵 A
// 输出: 单位下三角矩阵 L, 上三角矩阵 U, 置换向量 π
// 满足 PA = LU,其中 P 由 π 确定

  n ← A.rows
  // 初始化 π 为恒等置换
  for i ← 1 to n
      π[i] ← i
  // 将 A 复制到 U(后续原地修改)
  for i ← 1 to n
      for j ← 1 to n
          U[i][j] ← A[i][j]
  // 初始化 L 为单位矩阵
  for i ← 1 to n
      for j ← 1 to n
          if i = j
              L[i][j] ← 1
          else
              L[i][j] ← 0
  // 主消元循环
  for k ← 1 to n
      // 部分主元选取: 在第 k 列中找到绝对值最大的元素
      k' ← k
      for i ← k + 1 to n
          if |U[i][k]| > |U[k'][k]|
              k' ← i
      // 交换行: U 的第 k 行与第 k' 行互换
      if k' ≠ k
          swap U[k][1..n] ↔ U[k'][1..n]
          swap π[k] ↔ π[k']
          swap L[k][1..k-1] ↔ L[k'][1..k-1]
      // 消元: 将第 k 列对角线以下元素消为零
      for i ← k + 1 to n
          // 计算乘数(存储在 L 中)
          L[i][k] ← U[i][k] / U[k][k]
          // 更新 U 的第 i 行
          for j ← k + 1 to n
              U[i][j] ← U[i][j] - L[i][k] × U[k][j]
          // 将 U[i][k] 设为 0(消元完成)
          U[i][k] ← 0
  return (L, U, π)

代码解读

  • 第 3-4 行:初始化置换向量 为恒等置换
  • 第 5-10 行:将 复制到 ,初始化 为单位矩阵。
  • 第 12-16 行部分主元选取(partial pivoting),在第 列的第 行到第 行中,找到绝对值最大的元素 ,将其所在行 与第 行交换。这一步保证了 ,从而提高数值稳定性。
  • 第 17-20 行:交换操作同时作用于 (完整行)、(置换记录)和 (已计算的部分)。
  • 第 22-28 行消元操作,计算乘数 并存储在 中,然后更新 的子矩阵。

2.8 正确性证明

定理:给定非奇异矩阵 ,若 LUP-DECOMPOSITION 返回满足 ,则 LUP-SOLVE 返回的 是方程组 的唯一解。

证明

【目标(证明 x 满足原方程组)】 我们需要证明 LUP-SOLVE 返回的 满足

【第一步(LUP 分解的等价性)】 由 LUP-DECOMPOSITION 的正确性(此处假设分解过程正确),我们有 。由于 是非奇异矩阵, 是置换矩阵(也是非奇异的),因此 也是非奇异的。又因为 ,所以 都是非奇异的( 的行列式为 1, 的行列式为 )。

【第二步(前代求解的正确性)】 LUP-SOLVE 的第 5-8 行求解 。由于 是单位下三角矩阵, 的对角线元素全为 1,因此 一定非奇异。根据线性代数的基本理论,下三角方程组 有唯一解 。前代过程从 开始逐个求解,每一步都是确定性的,因此得到的 确实是 的唯一解。

【第三步(回代求解的正确性)】 LUP-SOLVE 的第 9-13 行求解 。由于 是上三角矩阵且 非奇异(所有对角线元素 ),上三角方程组 有唯一解 。回代过程从 开始逐个向前求解,每一步都是确定性的,因此得到的 确实是 的唯一解。

【第四步(验证 x 满足原方程组)】 将上述两步的结果组合:

因此:

又因为 ,所以:

两边左乘 (由于 是置换矩阵,):

【结论(唯一性)】 由于 是非奇异矩阵,方程组 有且仅有一个解。我们已证明 LUP-SOLVE 返回的 满足 ,因此 就是原方程组的唯一解。

2.9 计算复杂度分析

LUP-DECOMPOSITION 的复杂度

  • 外层循环(第 11 行)执行 次。
  • 部分主元选取(第 13-16 行):每次最多比较 个元素,总计
  • 行交换(第 17-20 行):每次交换 个元素,总计
  • 消元操作(第 22-28 行):这是主要开销。对于每个 ,内层双重循环执行 次乘法和减法。总计:

因此,LUP-DECOMPOSITION 的时间复杂度为

LUP-SOLVE 的复杂度

  • 前代阶段:
  • 回代阶段:
  • 总计:

总复杂度

阶段时间复杂度
LUP 分解
前代求解
回代求解
总计

重要应用场景:当需要求解 个方程组共享同一系数矩阵 )时,LUP 分解只需执行一次(),后续每次求解仅需 ,总时间为 。当 时,这比每次从头求解()高效得多。

2.10 具体数值示例:3×3 矩阵的完整 LUP 分解求解过程

题目:求解线性方程组 ,其中:

第一步:LUP 分解

初始化

k = 1:在第 1 列中找绝对值最大的元素。

  • 最大值为 8,位于第 3 行,所以
  • 交换 的第 1 行和第 3 行,交换
  • 消元:

k = 2:在第 2 列中(第 2 行及以下)找绝对值最大的元素。

  • 最大值为 0.75,位于第 3 行,所以
  • 交换 的第 2 行和第 3 行,交换
  • 同时交换 的第 2 行和第 3 行的第 1 列(即
  • 消元:

k = 3:无需消元(已到达最后一行)。

LUP 分解结果

验证,其中 确定,即 的第 1 行取 的第 3 行,第 2 行取第 1 行,第 3 行取第 2 行:

(注:。)

第二步:前代求解

计算

求解

第三步:回代求解

验证


补充理解与拓展

部分主元选取(Partial Pivoting)与数值稳定性

部分主元选取是 LUP-DECOMPOSITION 中第 12-16 行的关键步骤。其核心策略是:在每一步消元之前,在第 列的第 行到第 行中,选择绝对值最大的元素作为主元(pivot),然后通过行交换将其移到对角线位置。

为什么需要部分主元选取?

  1. 避免除零:如果对角线元素 ,消元过程无法继续(除数为零)。部分主元选取通过选择非零元素来避免这一问题。
  2. 控制舍入误差增长:乘数 的绝对值被限制在 范围内,这有效防止了消元过程中舍入误差的指数级放大。

数值稳定性分析

  • 高斯消元(带部分主元选取)在理论上被证明是向后稳定的(backward stable),但稳定性依赖于一个关键参数——增长因子(growth factor)
  • 增长因子的理论上界为 ,对于某些特殊构造的矩阵(如 Wilkinson 矩阵),这个上界是可以达到的。
  • 尽管理论上存在不稳定的极端情况,但在实际应用中,高斯消元(带部分主元选取)表现出极好的数值稳定性。Trefethen 和 Bau 在其经典教材中指出:“Gaussian elimination with partial pivoting is explosively unstable for certain matrices, yet stable in practice. This apparent paradox has a statistical explanation.”

完全主元选取(complete pivoting)在所有剩余子矩阵中(而非仅在第 列中)选择绝对值最大的元素,同时交换行和列。完全主元选取的增长因子上界更紧(),但计算成本更高(需要 次比较 vs. 部分主元的 次),因此在实践中部分主元选取是更常用的选择。

参考来源:Lloyd N. Trefethen and David Bau III, Numerical Linear Algebra, SIAM, 1997; Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms, SIAM, 2002.

LUP 分解 vs QR 分解

LUP 分解和 QR 分解是求解线性方程组的两种主要方法,各有其适用场景和优劣。

特性LUP 分解QR 分解
主要用途求解方阵线性方程组 求解最小二乘问题
适用范围要求 非奇异方阵适用于任意 矩阵(满列秩)
数值稳定性带部分主元选取时通常稳定,但存在理论上的不稳定情况使用正交变换,天然数值稳定,不放大舍入误差
计算代价 次浮点运算 次浮点运算(约为 LU 的两倍)
分解形式 正交, 上三角)

选择建议

  • 求解方阵线性方程组且追求速度时,选择 LUP 分解(带部分主元选取),它是标准的高效方法,对大多数实际应用足够稳定。
  • 求解超定方程组(最小二乘问题)时,选择 QR 分解,它是此类问题的标准方法。
  • 当矩阵严重病态(条件数极大)且需要最大数值稳定性时,即使对方阵系统也应优先考虑 QR 分解。

参考来源:Eric Darve, A Course on Numerical Linear Algebra, Stanford University.

LAPACK 中的 LUP 分解实现

LAPACK(Linear Algebra PACKage)是数值线性代数领域的标准软件库,其 LUP 分解通过 DGETRF 子程序实现。

函数签名(Fortran 接口):

SUBROUTINE DGETRF(M, N, A, LDA, IPIV, INFO)

参数说明

参数类型说明
MINTEGER矩阵 的行数
NINTEGER矩阵 的列数
ADOUBLE PRECISION输入/输出:输入为待分解矩阵,输出时紧凑存储 的单位对角线不存储)
LDAINTEGER 的 leading dimension
IPIVINTEGER输出:主元索引数组,IPIV(i) 表示第 行与哪一行交换
INFOINTEGER输出:0 表示成功;INFO > 0 表示 奇异

实现特点

  1. 紧凑存储 紧凑地存储在同一个矩阵 中。 的上三角部分(含对角线)存储 的对应元素, 的严格下三角部分存储 的对应元素( 的单位对角线不存储,节省空间)。
  2. 分块算法:DGETRF 采用 right-looking Level 3 BLAS 版本,将矩阵分块处理,充分利用高速缓存,显著提升了实际运行性能。
  3. 配套求解器:分解完成后,调用 DGETRS 求解线性方程组,调用 DGETRI 计算矩阵逆。

Python 调用示例

import numpy as np
from scipy.linalg import lu_factor, lu_solve
 
A = np.array([[2, 1, 1], [4, 3, 3], [8, 7, 9]], dtype=float)
b = np.array([1, 1, 1], dtype=float)
 
# LUP 分解(内部调用 dgetrf)
lu, piv = lu_factor(A)
 
# 求解(内部调用 dgetrs)
x = lu_solve((lu, piv), b)

参考来源:Oracle Solaris Studio LAPACK Documentation; LAPACK Reference Guide.

Strang MIT 线性代数课程推荐

Gilbert Strang 教授的 MIT 18.06 线性代数课程是全球最受欢迎的线性代数课程之一,是理解本节内容的绝佳补充资源。

课程资源

资源链接说明
MIT OCW 视频讲座MIT OpenCourseWare 18.0635 讲完整课程视频
教材Introduction to Linear Algebra, 6th Edition (2023)Strang 亲自撰写的经典教材
课堂笔记MIT Math 18.06 Lecture Notes配套讲义,PDF 格式
Strang 讲义集Lecture Notes for Linear Algebra (SIAM, 2022)教师版详细讲义

与本节相关的重点讲座

  • Lecture 2:线性方程组的消元法(Elimination with Matrices)——对应本节的 LUP 分解核心思想
  • Lecture 3:矩阵乘法和逆矩阵(Multiplication and Inverse Matrices)——对应 4.1 矩阵乘法
  • Lecture 4 分解(Factorization into )——直接对应本节内容
  • Lecture 5:转置、置换和向量空间(Transposes, Permutations, Spaces)——置换矩阵 的深入讨论

推荐学习路径:先观看 Lecture 2 和 Lecture 4 理解消元法和 LU 分解的直觉,再阅读 CLRS 本节内容掌握算法细节和伪代码,最后通过 Lecture 5 加深对置换矩阵的理解。

参考来源:Gilbert Strang, MIT OpenCourseWare, math.mit.edu.


易混淆点

LU 分解 vs LUP 分解的区别

LU 分解(不带置换):将矩阵 直接分解为 。并非所有非奇异矩阵都存在 LU 分解——只有所有顺序主子式都非零的矩阵才保证存在 LU 分解。例如:

这个矩阵是非奇异的(),但不存在 LU 分解,因为第一步消元时 ,无法作为除数。

LUP 分解(带置换):将矩阵 分解为 。对于任意非奇异矩阵,LUP 分解一定存在。置换矩阵 通过行交换解决了主元为零的问题。

关键区别:LUP 分解是 LU 分解的推广,适用范围更广。在实际的数值计算中,几乎总是使用 LUP 分解(带部分主元选取),而非纯粹的 LU 分解。

置换矩阵 P 的作用

常见误解:认为置换矩阵 仅仅是”为了处理零主元”而添加的附属品。

实际作用:置换矩阵 有两个关键作用:

  1. 保证分解存在性:通过行交换避免主元为零,确保 LUP 分解对任意非奇异矩阵都存在。
  2. 提高数值稳定性:部分主元选取策略选择绝对值最大的元素作为主元,使得乘数 ,有效控制舍入误差的传播。即使主元不为零,如果主元很小(接近零),也会导致乘数很大,从而放大舍入误差。

置换矩阵的性质

  • 是正交矩阵:,因此
  • 的行列式为 ,其中 是行交换的次数
  • 置换矩阵的乘积仍然是置换矩阵

矩阵奇异 vs 病态

奇异矩阵(Singular Matrix):矩阵的行列式为零,即 ,等价于矩阵不可逆。此时方程组 可能无解或有无穷多解(取决于 是否在 的列空间中)。在 LUP 分解中,如果 的某个对角线元素 ,则矩阵 是奇异的。

病态矩阵(Ill-conditioned Matrix):矩阵的条件数 很大。病态矩阵不一定是奇异矩阵(它仍然可逆),但它的解对输入数据的微小扰动极其敏感。例如:

这个矩阵的条件数约为 40000,属于病态矩阵。右端向量 的微小变化可能导致解 的巨大变化。

关键区别

  • 奇异 = 不可逆 = 行列式为零 = 方程组不一定有唯一解
  • 病态 = 可逆但条件数大 = 解对扰动敏感 = 数值计算可能不准确
  • LUP 分解能检测奇异性(),但不能直接判断病态程度(需要额外计算条件数)

习题精选

题号题目难度考察重点
28.1-1验证给定的 LUP 分解是否正确★☆☆LUP 分解的定义与验证
28.1-2手动执行 LUP-SOLVE★★☆前代与回代的执行过程
28.1-4修改 LUP-SOLVE 处理奇异矩阵★★★奇异矩阵的检测与处理
28.1-5证明 LUP 分解的唯一性★★★数学证明能力

视频学习指南

资源讲者/平台与本节的关联链接
MIT 18.06 Lecture 2: Elimination with MatricesGilbert Strang / MIT OCW高斯消元法的基本思想MIT OpenCourseWare
MIT 18.06 Lecture 4: Factorization into A = LUGilbert Strang / MIT OCWLU 分解的直觉理解MIT OpenCourseWare
MIT 18.06 Lecture 5: Transposes, Permutations, SpacesGilbert Strang / MIT OCW置换矩阵 的深入讨论MIT OpenCourseWare
3Blue1Brown: Essence of Linear AlgebraGrant Sanderson / YouTube线性代数的几何直觉3b1b.co
3Blue1Brown: Chapter 5 (Inverse matrices, column space, null space)Grant Sanderson / YouTube矩阵可逆性与解空间YouTube
3Blue1Brown: Chapter 7 (Inverse matrices, column space, null space)Grant Sanderson / YouTube非方阵与最小二乘YouTube

推荐学习顺序

  1. 先观看 3Blue1Brown Essence of Linear Algebra 系列,建立线性代数的几何直觉
  2. 再观看 MIT 18.06 Lecture 2 和 Lecture 4,理解消元法和 LU 分解的计算过程
  3. 最后阅读 CLRS 本节内容,掌握算法的伪代码实现和复杂度分析

教材原文

CLRS 第4版 第28.1节

“We can regard the operation of solving a system of linear equations as a two-stage process. In the first stage, we compute an LUP decomposition of the coefficient matrix . In the second stage, we solve the resulting triangular systems by forward substitution and by back substitution. The LUP decomposition is the most common way to solve systems of linear equations in practice.”

“The key idea is that we can solve by first solving and then solving . Since and are triangular, both of these systems can be solved in time.”


参见Wiki


第28章-矩阵运算 LUP分解