QR分解是数值线性代数中最核心的矩阵分解方法之一,其价值在于通过正交变换将任意矩阵转化为正交矩阵与上三角矩阵的乘积,在保持数值稳定性的同时为线性代数问题提供高效求解路径 。
正交变换能够保持向量二范数不变,避免了普通线性变换的误差放大效应,这是QR分解具备优异数值稳定性的根源。
一、基础理论:定义、几何与性质
1.1 数学定义与两种分解形式
对于任意实矩阵 A∈Rm×nA\in \mathbb{R}^{m\times n}A∈Rm×n,QR分解将其表示为:
A=QRA=QRA=QR
其中:
- QQQ 满足 QTQ=IQ^TQ=IQTQ=I,即列向量两两正交且为单位向量,称为正交矩阵;
- RRR 为上三角矩阵。
对于复数矩阵,正交条件替换为共轭转置形式 QHQ=IQ^HQ=IQHQ=I,其余结构保持一致。
LAPACK的标准例程DGEQRF专门用于实矩阵的QR分解计算,对于 m≥nm\ge nm≥n 的矩阵,其输出为正交矩阵与上三角矩阵的乘积形式。
完全QR分解
假设 A∈Rm×nA\in\mathbb{R}^{m\times n}A∈Rm×n 且 m≥nm\ge nm≥n,完全QR分解(Full QR)的形式为:
A=QRA=QRA=QR
其中 Q∈Rm×mQ\in\mathbb{R}^{m\times m}Q∈Rm×m 为方阵,R∈Rm×nR\in\mathbb{R}^{m\times n}R∈Rm×n 为上梯形矩阵,可分块表示为:
R=R10R= \begin{bmatrix} R_1\\ 0 \end{bmatrix}R=R10
其中 R1∈Rn×nR_1\in\mathbb{R}^{n\times n}R1∈Rn×n 为上三角方阵。
将Q按列分块为 Q=Q1Q2Q=\begin{bmatrix}Q_1 & Q_2\end{bmatrix}Q=Q1Q2,其中 Q1∈Rm×nQ_1\in\mathbb{R}^{m\times n}Q1∈Rm×n,Q2∈Rm×(m−n)Q_2\in\mathbb{R}^{m\times(m-n)}Q2∈Rm×(m−n),则分解可改写为:
A=Q1Q2R10=Q1R1A= \begin{bmatrix} Q_1 & Q_2 \end{bmatrix} \begin{bmatrix} R_1\\ 0 \end{bmatrix} =Q_1R_1A=Q1Q2R10=Q1R1
经济型QR分解
实际工程应用中,绝大多数场景无需保留完整的方阵Q与零元素部分,通常仅保存:
A=Q1R1A=Q_1R_1A=Q1R1
其中 Q1∈Rm×nQ_1\in\mathbb{R}^{m\times n}Q1∈Rm×n,R1∈Rn×nR_1\in\mathbb{R}^{n\times n}R1∈Rn×n。该形式也被称为Thin QR、Reduced QR或Economy-size QR(紧致QR)。
NumPy的numpy.linalg.qr函数通过mode="reduced"参数返回该形式;对于一般形状的矩阵,令 k=min(m,n)k=\min(m,n)k=min(m,n),经济型分解返回 Q∈Rm×kQ\in\mathbb{R}^{m\times k}Q∈Rm×k,R∈Rk×nR\in\mathbb{R}^{k\times n}R∈Rk×n。
维度示例
以 A∈R5×3A\in\mathbb{R}^{5\times3}A∈R5×3 为例,两种分解形式的维度对比如下:
| 分解形式 | Q的尺寸 | R的尺寸 |
|---|---|---|
| 完全QR | 5×55\times55×5 | 5×35\times35×3 |
| 经济型QR | 5×35\times35×3 | 3×33\times33×3 |
绝大多数最小二乘、正交基构造问题仅需使用经济型QR即可。
1.2 几何本质与上三角结构的来源
设矩阵A的列向量为 A=a1a2⋯anA=\begin{bmatrix}a_1&a_2&\cdots&a_n\end{bmatrix}A=a1a2⋯an,正交矩阵Q的列向量为 Q=q1q2⋯qnQ=\begin{bmatrix}q_1&q_2&\cdots&q_n\end{bmatrix}Q=q1q2⋯qn。
由 A=QRA=QRA=QR 且R为上三角矩阵,展开可得:
a1=r11q1a2=r12q1+r22q2a3=r13q1+r23q2+r33q3⋮aj=∑i=1jrijqi \begin{align*} a_1 &= r_{11}q_1 \\ a_2 &= r_{12}q_1 + r_{22}q_2 \\ a_3 &= r_{13}q_1 + r_{23}q_2 + r_{33}q_3 \\ &\vdots \\ a_j &= \sum_{i=1}^{j}r_{ij}q_i \end{align*} a1a2a3aj=r11q1=r12q1+r22q2=r13q1+r23q2+r33q3⋮=i=1∑jrijqi
由此可得到列空间的对应关系:
span(a1)=span(q1)span(a1,a2)=span(q1,q2)span(a1,...,aj)=span(q1,...,qj) \begin{align*} \operatorname{span}(a_1) &= \operatorname{span}(q_1) \\ \operatorname{span}(a_1,a_2) &= \operatorname{span}(q_1,q_2) \\ \operatorname{span}(a_1,\dots,a_j) &= \operatorname{span}(q_1,\dots,q_j) \end{align*} span(a1)span(a1,a2)span(a1,...,aj)=span(q1)=span(q1,q2)=span(q1,...,qj)
因此,QR分解本质上完成了两件事:
- 矩阵Q为原矩阵的列空间构造了一组标准正交基;
- 矩阵R记录了原始列向量在这组标准正交基下的坐标。
用基变换的视角可总结为:
原始基底=标准正交基底×坐标变换矩阵\boxed{\text{原始基底} = \text{标准正交基底} \times \text{坐标变换矩阵}}原始基底=标准正交基底×坐标变换矩阵
QR分解中R的上三角特性并非人为规定,而是正交基构造过程的自然结果。构造第j个正交基向量 qjq_jqj 时,仅需从原始向量 aja_jaj 中减去其在已有基向量 q1,q2,...,qj−1q_1,q_2,\dots,q_{j-1}q1,q2,...,qj−1 上的投影:
uj=aj−∑i=1j−1(qiTaj)qiu_j = a_j - \sum_{i=1}^{j-1}(q_i^Ta_j)q_iuj=aj−i=1∑j−1(qiTaj)qi
随后对 uju_juj 归一化得到 qjq_jqj:
qj=uj∥uj∥2q_j=\frac{u_j}{\|u_j\|_2}qj=∥uj∥2uj
定义:
- rij=qiTaj(i<j)r_{ij}=q_i^Ta_j \quad (i<j)rij=qiTaj(i<j):原始向量在已有基上的投影系数;
- rjj=∥uj∥2r_{jj}=\|u_j\|_2rjj=∥uj∥2:正交分量的长度。
则原始向量可表示为:
aj=r1jq1+r2jq2+⋯+rjjqja_j = r_{1j}q_1 + r_{2j}q_2 + \cdots + r_{jj}q_jaj=r1jq1+r2jq2+⋯+rjjqj
由于 aja_jaj 的线性组合仅用到前j个基向量,无需 qj+1,qj+2,...,qnq_{j+1},q_{j+2},\dots,q_nqj+1,qj+2,...,qn,因此当 i>ji>ji>j 时,rij=0r_{ij}=0rij=0,这正是R矩阵上三角结构的来源。
1.3 存在性与唯一性
普遍存在性
任意实矩阵或复矩阵都可以进行某种形式的QR分解。即使矩阵列不满秩,依然可以构造QR分解,仅会出现以下特性:
- R的部分对角元素可能为零;
- Q的部分列不能由原矩阵唯一确定;
- 整体分解通常不唯一。
分解的不唯一性
假设 A=QRA=QRA=QR 是一组合法分解,构造对角矩阵 D=diag(±1,±1,...,±1)D=\operatorname{diag}(\pm1,\pm1,\dots,\pm1)D=diag(±1,±1,...,±1),易知 D2=ID^2=ID2=I。此时有:
A=(QD)(DR)A = (QD)(DR)A=(QD)(DR)
即同时将Q的某一列乘以-1、R的对应行乘以-1,乘积结果保持不变。
因此不同软件、不同算法返回的Q和R可能存在符号差异,但均为正确的QR分解结果。
唯一性条件
当同时满足以下三个条件时,QR分解是唯一的:
- 矩阵A列满秩;
- 使用经济型QR分解;
- 约定R的所有对角元素均为正,即 rii>0r_{ii}>0rii>0。
二、三类QR实现算法
2.1 Gram-Schmidt正交化
Gram-Schmidt正交化是最直观的QR分解算法,直接对应"逐列构造正交基"的几何过程。
经典Gram-Schmidt(CGS)
设 A=a1,...,anA=a_1,\\dots,a_nA=a1,...,an,经典Gram-Schmidt(Classical Gram-Schmidt, CGS)的计算流程如下:
第1个向量:
r11=∥a1∥2,q1=a1r11r_{11}=\|a_1\|2, \quad q_1=\frac{a_1}{r{11}}r11=∥a1∥2,q1=r11a1
第2个向量:
r12=q1Ta2,u2=a2−r12q1,r22=∥u2∥2,q2=u2r22r_{12}=q_1^Ta_2, \quad u_2=a_2-r_{12}q_1, \quad r_{22}=\|u_2\|2, \quad q_2=\frac{u_2}{r{22}}r12=q1Ta2,u2=a2−r12q1,r22=∥u2∥2,q2=r22u2
第j个向量:
rij=qiTaj(i=1,...,j−1)r_{ij}=q_i^Ta_j \quad (i=1,\dots,j-1)rij=qiTaj(i=1,...,j−1)
uj=aj−∑i=1j−1rijqiu_j = a_j-\sum_{i=1}^{j-1}r_{ij}q_iuj=aj−i=1∑j−1rijqi
rjj=∥uj∥2,qj=ujrjjr_{jj}=\|u_j\|2, \quad q_j=\frac{u_j}{r{jj}}rjj=∥uj∥2,qj=rjjuj
对应的伪代码为:
text
for j = 1 ... n
for i = 1 ... j-1
R[i,j] = Q[:,i]^T A[:,j]
end
v = A[:,j] - Σ R[i,j] Q[:,i]
R[j,j] = ||v||₂
Q[:,j] = v / R[j,j]
end
修改Gram-Schmidt(MGS)
修改Gram-Schmidt(Modified Gram-Schmidt, MGS)不一次性计算所有投影,而是每确定一个基向量,就将其从所有剩余向量中减去,逐次更新剩余向量:
text
V = A
for i = 1 ... n
R[i,i] = ||V[:,i]||₂
Q[:,i] = V[:,i] / R[i,i]
for j = i+1 ... n
R[i,j] = Q[:,i]^T V[:,j]
V[:,j] = V[:,j] - R[i,j] Q[:,i]
end
end
在数学精确运算下,CGS与MGS得到的结果完全等价;但在有限精度浮点数运算中,二者的误差传播路径存在显著差异。
数值稳定性与重正交化
经典Gram-Schmidt的数值稳定性较差。当矩阵的两个列向量几乎平行时,例如 a2≈αa1a_2\approx \alpha a_1a2≈αa1,计算正交分量 u2=a2−(q1Ta2)q1u_2=a_2-(q_1^Ta_2)q_1u2=a2−(q1Ta2)q1 时会发生灾难性消去 :两个数值接近的大数相减,有效数字大量损失,导致最终得到的 q2q_2q2 不再与 q1q_1q1 严格正交。
经典数值分析研究表明,有限精度下经典Gram-Schmidt会出现明显的正交性损失;修改Gram-Schmidt的稳定性显著优于经典形式,在多数场景下可满足工程需求。
对于正交性要求极高的场景,可在单次正交化的基础上执行第二次正交化,称为重正交化:
- 第一次计算:v=aj−Q(QTaj)v=a_j-Q(Q^Ta_j)v=aj−Q(QTaj)
- 第二次修正:v←v−Q(QTv)v\leftarrow v-Q(Q^Tv)v←v−Q(QTv)
对应的算法称为CGS2或MGS2,计算代价翻倍,但可显著降低正交误差 ∥I−QTQ∥\|I-Q^TQ\|∥I−QTQ∥。
手算示例
以3×2矩阵为例,完整演示QR分解的计算过程:
A=111001=a1a2A= \begin{bmatrix} 1&1\\ 1&0\\ 0&1 \end{bmatrix} =\begin{bmatrix} a_1&a_2 \end{bmatrix}A= 110101 =a1a2
其中 a1=110a_1=\begin{bmatrix}1\\1\\0\end{bmatrix}a1= 110 ,a2=101a_2=\begin{bmatrix}1\\0\\1\end{bmatrix}a2= 101 。
-
计算第一个正交基 q1q_1q1
r11=∥a1∥2=12+12+02=2r_{11}=\|a_1\|_2 =\sqrt{1^2+1^2+0^2} =\sqrt2r11=∥a1∥2=12+12+02 =2
q1=12110q_1= \frac{1}{\sqrt2}\begin{bmatrix}1\\1\\0\end{bmatrix}q1=2 1 110
-
计算 a2a_2a2 在 q1q_1q1 上的投影
r12=q1Ta2=12110101=12r_{12}=q_1^Ta_2 =\frac{1}{\sqrt2}\begin{bmatrix}1&1&0\end{bmatrix}\begin{bmatrix}1\\0\\1\end{bmatrix} =\frac{1}{\sqrt2}r12=q1Ta2=2 1110 101 =2 1
投影向量为:
r12q1=12110r_{12}q_1 =\frac{1}{2}\begin{bmatrix}1\\1\\0\end{bmatrix}r12q1=21 110
-
计算正交分量与第二个基向量
u2=a2−r12q1=101−1/21/20=1/2−1/21u_2=a_2-r_{12}q_1 =\begin{bmatrix}1\\0\\1\end{bmatrix} -\begin{bmatrix}1/2\\1/2\\0\end{bmatrix} =\begin{bmatrix}1/2\\-1/2\\1\end{bmatrix}u2=a2−r12q1= 101 − 1/21/20 = 1/2−1/21
r22=∥u2∥2=14+14+1=32=62r_{22}=\|u_2\|_2 =\sqrt{\frac{1}{4}+\frac{1}{4}+1} =\sqrt{\frac{3}{2}} =\frac{\sqrt6}{2}r22=∥u2∥2=41+41+1 =23 =26
q2=u2r22=161−12q_2=\frac{u_2}{r_{22}} =\frac{1}{\sqrt6}\begin{bmatrix}1\\-1\\2\end{bmatrix}q2=r22u2=6 1 1−12
最终分解结果:
Q=121612−16026,R=212062Q= \begin{bmatrix} \frac{1}{\sqrt2}&\frac{1}{\sqrt6}\\ \frac{1}{\sqrt2}&-\frac{1}{\sqrt6}\\ 0&\frac{2}{\sqrt6} \end{bmatrix}, \quad R= \begin{bmatrix} \sqrt2&\frac{1}{\sqrt2}\\ 0&\frac{\sqrt6}{2} \end{bmatrix}Q= 2 12 106 1−6 16 2 ,R=2 02 126
可验证满足 QTQ=IQ^TQ=IQTQ=I 且 QR=AQR=AQR=A。
2.2 Householder反射
对于普通稠密矩阵,工业界标准的QR分解算法是Householder QR。LAPACK的核心QR例程xGEQRF均基于Householder反射实现,并通过分块技术适配BLAS Level 3运算,大幅提升缓存效率与并行性能。
Householder反射最早由A. S. Householder提出,用于将一般矩阵正交三角化。
Householder矩阵的定义与性质
给定非零向量v,Householder矩阵定义为:
H=I−2vvTvTvH=I-2\frac{vv^T}{v^Tv}H=I−2vTvvvT
若v已归一化,则简化为 H=I−2vvTH=I-2vv^TH=I−2vvT。LAPACK中采用更通用的形式 H=I−τvvTH=I-\tau vv^TH=I−τvvT,其中 τ\tauτ 为缩放系数。
Householder矩阵具备以下核心性质:
- 对称性 :HT=HH^T=HHT=H
- 正交性 :HTH=H2=IH^TH=H^2=IHTH=H2=I,因此 H−1=HH^{-1}=HH−1=H
- 几何意义 :表示关于向量v垂直的超平面的镜像反射,不改变向量的二范数,即 ∥Hx∥2=∥x∥2\|Hx\|_2=\|x\|_2∥Hx∥2=∥x∥2
单向量反射消元原理
给定向量 x=x1x2⋮xmx=\begin{bmatrix}x_1\\x_2\\\vdots\\x_m\end{bmatrix}x= x1x2⋮xm ,希望构造Householder矩阵H,使得H作用于x后,仅保留第一个元素,其余元素均为0:
Hx=±∥x∥20⋮0Hx= \begin{bmatrix} \pm\|x\|_2\\ 0\\ \vdots\\ 0 \end{bmatrix}Hx= ±∥x∥20⋮0
构造方法:
- 令 α=−sign(x1)∥x∥2\alpha=-\operatorname{sign}(x_1)\|x\|_2α=−sign(x1)∥x∥2
- 令 v=x−αe1v=x-\alpha e_1v=x−αe1
- 构造 H=I−2vvTvTvH=I-2\frac{vv^T}{v^Tv}H=I−2vTvvvT
则有 Hx=αe1Hx=\alpha e_1Hx=αe1。
选择 α=−sign(x1)∥x∥2\alpha=-\operatorname{sign}(x_1)\|x\|_2α=−sign(x1)∥x∥2 而非任意符号,是为了避免 x1x_1x1 与 ∥x∥\|x\|∥x∥ 数值接近时发生严重的相消误差,保证数值稳定性。
逐列消元的QR构造过程
对m×n矩阵A,从第一列开始,依次对每一列构造Householder反射,消去对角线下方的所有元素:
-
构造第一个反射 H1H_1H1,消去第一列对角线下方元素:
H1A=×××0××0××0××H_1A= \begin{bmatrix} \times&\times&\times\\ 0&\times&\times\\ 0&\times&\times\\ 0&\times&\times \end{bmatrix}H1A= ×000××××××××
-
对右下角子矩阵构造第二个反射 H2H_2H2,消去第二列下方元素:
H2H1A=×××0××00×00×H_2H_1A= \begin{bmatrix} \times&\times&\times\\ 0&\times&\times\\ 0&0&\times\\ 0&0&\times \end{bmatrix}H2H1A= ×000××00××××
重复该过程,最终得到:
Hk⋯H2H1A=RH_k\cdots H_2H_1A=RHk⋯H2H1A=R
由于每个Householder矩阵都是自逆的(Hi−1=HiH_i^{-1}=H_iHi−1=Hi),因此:
A=H1H2⋯HkRA=H_1H_2\cdots H_kRA=H1H2⋯HkR
令 Q=H1H2⋯HkQ=H_1H_2\cdots H_kQ=H1H2⋯Hk,即得到QR分解 A=QRA=QRA=QR。
高效实现与存储方案
若直接构造完整的m×m Householder矩阵,存储与计算代价都极高。实际工程中利用Householder矩阵的秩-1修正结构,通过向量运算完成矩阵更新:
HA=A−τv(vTA)HA = A - \tau v(v^TA)HA=A−τv(vTA)
计算步骤为:
- 计算行向量 wT=vTAw^T=v^TAwT=vTA
- 计算外积 vwTvw^TvwT
- 更新矩阵 A←A−τvwTA\leftarrow A-\tau vw^TA←A−τvwT
整个过程无需生成完整的H矩阵,仅需存储向量v与系数τ。
LAPACK的DGEQRF例程采用紧凑存储方案:
- R矩阵存储在原矩阵的上三角部分;
- Householder向量v存储在原矩阵的下三角部分;
- 每个反射的τ系数存入独立的TAU数组。
当需要显式生成Q矩阵时,调用xORGQR例程;若仅需计算 QTbQ^TbQTb 或 QBQBQB,可直接调用xORMQR例程,避免显式生成完整Q矩阵带来的额外开销。
计算复杂度与分块优化
当 m≥nm\ge nm≥n 时,Householder QR的主要计算量约为 2mn2−23n32mn^2-\frac{2}{3}n^32mn2−32n3 次浮点运算。对于n阶方阵,计算量约为 43n3\frac{4}{3}n^334n3,整体时间复杂度为 O(mn2)O(mn^2)O(mn2)。
为适配现代CPU的缓存架构,工业级实现普遍采用分块QR(Block QR)算法。其核心思想是将连续的b个Householder向量组合为一个块反射变换,将原本大量的向量-向量运算(BLAS Level 1)转换为矩阵-矩阵运算(BLAS Level 3)。
分块算法通过提高计算密度,充分利用CPU缓存的空间局部性,同时为多核并行提供了更粗粒度的任务划分。对于大规模稠密矩阵,分块QR可带来数倍的性能提升,是LAPACK等高性能库的核心优化手段。
2.3 Givens旋转
Givens旋转由Wallace Givens于1958年提出,其核心思想是通过二维平面酉旋转逐元素消元,而非一次消去整列。
二维平面旋转原理
考虑二维向量 ab\begin{bmatrix}a\\b\end{bmatrix}ab,构造旋转矩阵:
G=cs−scG= \begin{bmatrix} c&s\\ -s&c \end{bmatrix}G=c−ssc
其中 c2+s2=1c^2+s^2=1c2+s2=1,满足正交性。
希望通过旋转将第二个元素消为0:
Gab=r0G\begin{bmatrix}a\\b\end{bmatrix} =\begin{bmatrix}r\\0\end{bmatrix}Gab=r0
令 r=a2+b2r=\sqrt{a^2+b^2}r=a2+b2 ,取:
c=ar,s=brc=\frac{a}{r}, \quad s=\frac{b}{r}c=ra,s=rb
即可达到消元目的。
实际实现中通常采用类似hypot(a,b)的缩放算法,避免直接计算 a2+b2a^2+b^2a2+b2 时发生数值上溢或下溢。
高维扩展与稀疏性适配
在m维空间中,Givens矩阵 G(i,j)G(i,j)G(i,j) 仅在第i、j行与列构成二维旋转子矩阵,其余位置与单位矩阵一致:
G(i,j)=1cs1−sc1G(i,j)= \begin{bmatrix} 1&&&&\\ &c&&s&\\ &&1&&\\ &-s&&c&\\ &&&&1 \end{bmatrix}G(i,j)= 1c−s1sc1
Givens矩阵作用于矩阵时,仅改变对应的两行,因此特别适合稀疏矩阵------它不会引入额外的非零元素,能够保持矩阵的稀疏结构。
典型应用场景
Givens旋转的逐元素消元特性使其在以下场景具备不可替代的优势:
- 稀疏矩阵QR分解;
- 仅需消去少数特定元素的场景;
- 矩阵新增/删除行后的QR更新;
- 在线最小二乘与流式数据拟合;
- 需要保持稀疏结构的数值计算。
尤其在QR更新问题中,当矩阵新增一行数据时,无需重新执行完整QR分解,仅需通过若干次Givens旋转即可消去新元素,在 O(n2)O(n^2)O(n2) 时间内完成分解更新,计算效率远高于重新分解。
2.4 算法综合对比
| 算法 | 基本操作 | 数值稳定性 | 典型用途 |
|---|---|---|---|
| 经典Gram-Schmidt | 列向量投影 | 较差 | 教学演示、条件良好的小规模问题 |
| 修改Gram-Schmidt | 顺序投影更新 | 较好 | Krylov子空间算法、逐列正交化场景 |
| Householder反射 | 超平面反射 | 很好 | 稠密矩阵标准QR分解 |
| Givens旋转 | 二维平面旋转 | 很好 | 稀疏矩阵、在线更新、局部消元 |
补充说明:
- Householder与Givens均基于严格的正交变换,具备优异的后向稳定性;
- MGS的增量式特性与Krylov子空间迭代高度契合,是Arnoldi、GMRES等算法的标准组件;
- 普通稠密矩阵的通用QR分解优先选择Householder算法;
- 矩阵可能秩亏时,应使用带列主元的Householder QR;
- 不建议将经典Gram-Schmidt用于生产级通用求解器。
三、进阶特性:列主元QR与秩揭示
3.1 带列主元的QR分解(QRCP)
普通QR分解严格按原始列顺序进行消元,当矩阵列秩不足或列相关性较强时,可能无法有效揭示秩信息。带列主元的QR分解(QR with Column Pivoting, QRCP)通过动态调整列顺序解决这一问题。
带列主元的QR分解形式为:
AΠ=QRA\Pi=QRAΠ=QR
其中 Π\PiΠ 为列置换矩阵,用于重新排列A的列顺序,例如 AΠ=a3a1a2A\Pi=\begin{bmatrix}a_3&a_1&a_2\end{bmatrix}AΠ=a3a1a2。
标准的列主元策略采用贪心选择:每一步消元前,在剩余列中选择范数最大的列作为主元列,交换到当前处理位置,使得R的对角元素大致呈递减趋势:
∣r11∣≥∣r22∣≥⋯≥∣rnn∣|r_{11}|\ge |r_{22}|\ge \cdots \ge |r_{nn}|∣r11∣≥∣r22∣≥⋯≥∣rnn∣
LAPACK的DGEQP3例程实现了高效的带列主元QR分解,官方指南建议,当矩阵不满秩或秩不确定时,优先使用带主元QR或SVD进行求解。
3.2 数值秩判断能力
设 AΠ=QRA\Pi=QRAΠ=QR,将R分块为:
R=R11R120R22R= \begin{bmatrix} R_{11}&R_{12}\\ 0&R_{22} \end{bmatrix}R=R110R12R22
若 R11R_{11}R11 的对角元素较大,而 R22R_{22}R22 的元素整体很小,则说明矩阵接近秩亏。
工程中通常通过阈值判断数值秩:若 ∣rii∣≤τ∣r11∣|r_{ii}| \le \tau |r_{11}|∣rii∣≤τ∣r11∣,则认为第i个方向数值上接近线性相关。
常用经验阈值为 τ∼max(m,n)ε\tau \sim \max(m,n)\varepsilonτ∼max(m,n)ε,其中 ε\varepsilonε 为机器精度。实际应用中还需结合数据尺度、测量噪声、物理单位、可接受误差与矩阵条件数综合判断。
3.3 与SVD的定位差异
带列主元QR能够以较低的计算成本提供秩信息,但并非SVD的完全替代品:
- 对于极端病态的近秩亏问题,SVD对数值秩的判断通常更可靠;
- SVD的计算成本显著高于QR分解;
- QRCP更适合追求计算速度与较好秩揭示能力的平衡场景。
四、应用:最小二乘与线性代数求解
4.1 超定最小二乘问题
最小二乘是QR分解最重要的应用场景之一。考虑超定线性方程组:
Ax≈bAx\approx bAx≈b
其中 A∈Rm×nA\in\mathbb{R}^{m\times n}A∈Rm×n,m>nm>nm>n。通常不存在精确解,因此求解最小二乘解:
x⋆=argminx∥Ax−b∥2x^\star = \arg\min_x\|Ax-b\|_2x⋆=argxmin∥Ax−b∥2
LAPACK的线性最小二乘例程在满秩超定问题中默认使用QR分解;若秩不确定,则采用带主元QR、完整正交分解或SVD。
基于QR的推导过程
设A的完全QR分解为:
A=Q1Q2R0=Q1RA= \begin{bmatrix} Q_1&Q_2 \end{bmatrix} \begin{bmatrix} R\\0 \end{bmatrix} =Q_1RA=Q1Q2R0=Q1R
由于正交矩阵保持二范数不变,因此:
∥Ax−b∥2=∥QT(Ax−b)∥2\|Ax-b\|_2 = \|Q^T(Ax-b)\|_2∥Ax−b∥2=∥QT(Ax−b)∥2
代入分解形式:
QTA=Q1TQ2TQ1R=R0Q^TA = \begin{bmatrix} Q_1^T\\ Q_2^T \end{bmatrix} Q_1R= \begin{bmatrix} R\\ 0 \end{bmatrix}QTA=Q1TQ2TQ1R=R0
令 QTb=cdQ^Tb=\begin{bmatrix}c\\d\end{bmatrix}QTb=cd,其中 c=Q1Tbc=Q_1^Tbc=Q1Tb,d=Q2Tbd=Q_2^Tbd=Q2Tb。则残差的平方可展开为:
∥Ax−b∥22=∥R0x−cd∥22=∥Rx−c∥22+∥d∥22\|Ax-b\|_2^2= \left\| \begin{bmatrix} R\\0 \end{bmatrix}x- \begin{bmatrix} c\\d \end{bmatrix} \right\|_2^2 =\|Rx-c\|_2^2+\|d\|_2^2∥Ax−b∥22= R0x−cd 22=∥Rx−c∥22+∥d∥22
第二项 ∥d∥22\|d\|_2^2∥d∥22 与x无关,因此残差的最小值在 Rx=cRx=cRx=c 时取得。最终最小二乘解满足:
Rx=Q1Tb\boxed{Rx=Q_1^Tb}Rx=Q1Tb
通过上三角矩阵回代即可求解x。
残差的几何意义
最小二乘解对应的残差为 r=b−Ax⋆r=b-Ax^\starr=b−Ax⋆,该残差向量位于A的列空间的正交补中,满足 ATr=0A^Tr=0ATr=0。
在QR分解框架下:
- Ax⋆=Q1Q1TbAx^\star=Q_1Q_1^TbAx⋆=Q1Q1Tb 是向量b在A的列空间上的正交投影;
- 残差 r=b−Q1Q1Tb=Q2Q2Tbr= b-Q_1Q_1^Tb = Q_2Q_2^Tbr=b−Q1Q1Tb=Q2Q2Tb 是b在列空间正交补上的分量。
残差的范数满足 ∥r∥2=∥Q2Tb∥2\|r\|_2=\|Q_2^Tb\|_2∥r∥2=∥Q2Tb∥2,其几何结构可直观表示为:
text
b
├── 在 A 列空间中的分量:Q₁Q₁ᵀb (拟合部分)
└── 与 A 列空间正交的分量:Q₂Q₂ᵀb (残差部分)
为什么不推荐直接使用正规方程
最小二乘问题理论上可转化为正规方程:
ATAx=ATbA^TAx=A^TbATAx=ATb
但该方法在数值上存在固有缺陷。
设A的奇异值为 σ1≥⋯≥σn>0\sigma_1\ge\cdots\ge\sigma_n>0σ1≥⋯≥σn>0,则 ATAA^TAATA 的特征值为 σ12,...,σn2\sigma_1^2,\dots,\sigma_n^2σ12,...,σn2,因此条件数满足:
κ2(ATA)=σ12σn2=κ2(A)2\kappa_2(A^TA) = \frac{\sigma_1^2}{\sigma_n^2} = \kappa_2(A)^2κ2(ATA)=σn2σ12=κ2(A)2
例如当 κ2(A)=108\kappa_2(A)=10^8κ2(A)=108 时,κ2(ATA)=1016\kappa_2(A^TA)=10^{16}κ2(ATA)=1016,在双精度浮点数下已接近有效精度极限,可能导致求解结果严重失真。简言之:
正规方程会将矩阵的条件数平方\boxed{\text{正规方程会将矩阵的条件数平方}}正规方程会将矩阵的条件数平方
而QR分解通过正交变换直接求解,无需显式构造 ATAA^TAATA,避免了条件数恶化的问题。Björck的经典研究对Gram-Schmidt QR求解最小二乘的舍入误差进行了系统分析,验证了其数值可靠性。
工程实践中的选型原则:
| 场景 | 推荐方案 |
|---|---|
| 条件良好、追求极致速度 | Cholesky分解/正规方程可作为选项 |
| 一般最小二乘问题 | Householder QR |
| 可能存在秩亏 | 带列主元QR(QRCP) |
| 严重病态或需精确秩判断 | SVD |
4.2 方阵线性方程组求解
对于n阶方阵线性方程组 Ax=bAx=bAx=b,若A可逆,可通过QR分解求解:
QRx=bQRx=bQRx=b
两边左乘 QTQ^TQT 得:
Rx=QTbRx=Q^TbRx=QTb
求解步骤:
- 对A进行QR分解;
- 计算 y=QTby=Q^Tby=QTb;
- 通过上三角回代求解 Rx=yRx=yRx=y。
注意:生产代码中不应显式计算 R−1R^{-1}R−1,即避免写成 x=R−1QTbx=R^{-1}Q^Tbx=R−1QTb,而应直接使用三角回代算法,以减少计算量与数值误差。
与LU分解相比,QR分解求解方阵方程的数值稳定性更好,但计算量约为LU分解的两倍,因此非病态方阵通常优先使用LU分解,病态方阵可考虑QR分解。
4.3 特征值QR算法
需要明确区分"QR分解"与"QR算法":
- QR分解:单次运算,将矩阵分解为正交矩阵与上三角矩阵的乘积;
- QR算法:迭代算法,反复执行QR分解以计算矩阵的特征值。
基本QR迭代
基本QR迭代的流程如下:
- 初始化 A0=AA_0=AA0=A;
- 第k步对当前矩阵做QR分解:Ak=QkRkA_k=Q_kR_kAk=QkRk;
- 交换乘积顺序得到下一个迭代矩阵:Ak+1=RkQkA_{k+1}=R_kQ_kAk+1=RkQk。
由于 Ak+1=RkQk=QkTAkQkA_{k+1}=R_kQ_k = Q_k^TA_kQ_kAk+1=RkQk=QkTAkQk,因此 Ak+1A_{k+1}Ak+1 与 AkA_kAk 相似,保持特征值不变。
迭代足够多次后,矩阵通常会逐渐趋近于上三角矩阵(实矩阵为实Schur形式),特征值可直接从对角块中读取。
工业级算法的优化策略
真实的数值线性代数库不会直接对完整稠密矩阵执行裸QR迭代,通常包含多层优化:
- 预化简:先通过正交相似变换将矩阵化为上Hessenberg矩阵,减少每轮迭代的计算量;
- 位移策略:引入单位移、双位移或多位移技术,大幅加速收敛速度;
- 收缩(Deflation):当子矩阵已收敛时,将其拆分出来,降低后续迭代规模;
- 最终输出实Schur形式,支持特征值与特征向量的计算。
LAPACK的DHSEQR例程用于对上Hessenberg矩阵计算特征值与可选的Schur分解,其底层QR过程采用单移或双移QR算法。
五、稳定性分析与分解家族对比
5.1 数值稳定性分析
正交变换的稳定性根源
正交变换是数值线性代数中最稳定的变换类型,核心原因在于:若Q为正交矩阵,则对任意向量x有 ∥Qx∥2=∥x∥2\|Qx\|_2=\|x\|_2∥Qx∥2=∥x∥2,且矩阵的二范数 ∥Q∥2=1\|Q\|_2=1∥Q∥2=1。
这意味着正交变换不会放大小的扰动误差,输入的误差会被原样传递到输出中,不会出现误差指数级放大的情况。Householder反射、Givens旋转、正交相似变换等数值方法的稳定性均源于此。
后向稳定性的定义
数值算法的稳定性通常用后向误差衡量。假设程序计算得到的分解为 Q^,R^\hat{Q},\hat{R}Q^,R^,后向稳定并非要求计算结果与精确解完全一致,而是要求存在一个很小的扰动 ΔA\Delta AΔA,使得:
A+ΔA=Q^R^A+\Delta A=\hat{Q}\hat{R}A+ΔA=Q^R^
且相对误差 ∥ΔA∥∥A∥\frac{\|\Delta A\|}{\|A\|}∥A∥∥ΔA∥ 与机器精度 ε\varepsilonε 同阶。
通俗地说:计算结果可以看作某个"与原始矩阵极其接近的矩阵"的精确QR分解。
Householder QR是公认的后向稳定算法,其扰动误差可控制在机器精度乘以小常数的量级。
结果验证的两个核心指标
验证QR分解结果时,至少需要检查两个独立的误差指标:
-
重构误差 :衡量QR乘积与原矩阵的接近程度
eres=∥A−QR∥F∥A∥Fe_{\mathrm{res}} = \frac{\|A-QR\|_F}{\|A\|_F}eres=∥A∥F∥A−QR∥F
-
正交误差 :衡量Q的列向量正交性
eorth=∥I−QTQ∥Fe_{\mathrm{orth}} = \|I-Q^TQ\|_Feorth=∥I−QTQ∥F
两个指标相互独立:可能出现重构误差很小,但Q的正交性已经严重损失的情况,这在不稳定的Gram-Schmidt实现中尤为常见。
5.2 主流矩阵分解对比
| 分解方法 | 标准形式 | 适用条件 | 典型用途 |
|---|---|---|---|
| LU分解 | PA=LUPA=LUPA=LU | 方阵或方形子问题 | 一般线性方程组求解 |
| Cholesky分解 | A=LLTA=LL^TA=LLT | 对称正定矩阵 | 高效求解SPD线性系统 |
| QR分解 | A=QRA=QRA=QR | 几乎任意矩阵 | 最小二乘、正交基构造 |
| SVD | A=UΣVTA=U\Sigma V^TA=UΣVT | 任意矩阵 | 秩判断、病态问题、伪逆 |
选型的一般原则:
- 求解一般方阵线性方程组:LU分解通常速度更快;
- 求解超定最小二乘问题:QR比正规方程更可靠;
- 矩阵可能秩不足:优先使用带列主元QR;
- 极度病态或需求最小范数解:使用SVD;
- 对称正定矩阵:Cholesky分解效率最高。
六、工程实现:主流库代码示例
6.1 Python:NumPy与SciPy
NumPy提供基础QR分解接口,支持多种分解模式;SciPy扩展支持带列主元的QR分解。
基础QR分解与误差验证
python
import numpy as np
A = np.array([
[1.0, 1.0],
[1.0, 0.0],
[0.0, 1.0],
])
Q, R = np.linalg.qr(A, mode="reduced")
print("Q =")
print(Q)
print("R =")
print(R)
reconstruction_error = (
np.linalg.norm(A - Q @ R, ord="fro")
/ np.linalg.norm(A, ord="fro")
)
orthogonality_error = np.linalg.norm(
np.eye(Q.shape[1]) - Q.T @ Q,
ord="fro",
)
print("重构误差:", reconstruction_error)
print("正交误差:", orthogonality_error)
基于QR的最小二乘求解
python
import numpy as np
A = np.array([
[1.0, 0.0],
[1.0, 1.0],
[1.0, 2.0],
[1.0, 3.0],
])
b = np.array([1.0, 2.0, 2.0, 4.0])
Q, R = np.linalg.qr(A, mode="reduced")
y = Q.T @ b
x = np.linalg.solve(R, y)
print("最小二乘解:", x)
print("残差范数:", np.linalg.norm(A @ x - b))
注意:必须使用
np.linalg.solve(R, y)进行三角回代,禁止使用np.linalg.inv(R) @ y。
SciPy带列主元QR与秩估计
python
import numpy as np
from scipy.linalg import qr
A = np.array([
[1.0, 1.0, 2.0],
[2.0, 2.0, 4.0],
[3.0, 3.0, 6.0],
])
Q, R, piv = qr(
A,
mode="economic",
pivoting=True,
)
print("列置换:", piv)
print("R:")
print(R)
diag = np.abs(np.diag(R))
if diag.size > 0:
tolerance = max(A.shape) * np.finfo(A.dtype).eps * diag[0]
estimated_rank = int(np.sum(diag > tolerance))
else:
estimated_rank = 0
print("估计秩:", estimated_rank)
# 验证 A[:, piv] = Q @ R
print("重构残差:", np.linalg.norm(A[:, piv] - Q @ R))
6.2 C++:Eigen库实现
Eigen库提供了多种QR分解实现,包括HouseholderQR、ColPivHouseholderQR、FullPivHouseholderQR与CompleteOrthogonalDecomposition。
其中ColPivHouseholderQR采用Householder变换与列主元策略,满足 AP=QRAP=QRAP=QR,并内置秩判断与线性求解接口。
cpp
#include <Eigen/Dense>
#include <Eigen/QR>
#include <iostream>
int main()
{
Eigen::MatrixXd A(4, 2);
A << 1.0, 0.0,
1.0, 1.0,
1.0, 2.0,
1.0, 3.0;
Eigen::VectorXd b(4);
b << 1.0, 2.0, 2.0, 4.0;
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qr(A);
if (qr.info() != Eigen::Success) {
std::cerr << "QR decomposition failed\n";
return 1;
}
Eigen::VectorXd x = qr.solve(b);
std::cout << "x:\n" << x << "\n";
std::cout << "estimated rank: " << qr.rank() << "\n";
std::cout << "residual norm: "
<< (A * x - b).norm() << "\n";
return 0;
}
Eigen官方也推荐链式调用形式A.colPivHouseholderQr().solve(b)作为线性系统与最小二乘问题的简洁求解方式。
七、实践指南:避坑与选型原则
7.1 工程常见误区
误区一:默认Q一定是方阵
经济型QR分解中,Q∈Rm×nQ\in\mathbb{R}^{m\times n}Q∈Rm×n 并非m阶方阵。此时满足 QTQ=InQ^TQ=I_nQTQ=In,但通常 QQT≠ImQQ^T\ne I_mQQT=Im。
事实上,QQTQQ^TQQT 是投影到A的列空间的投影矩阵,而非单位矩阵。
误区二:认为R的对角元素必须为正
QR分解并不要求R的对角元素为正。除非算法主动调整符号,否则部分 riir_{ii}rii 可能为负数,这并不影响 A=QRA=QRA=QR 的正确性。
误区三:用普通QR判断矩阵秩
不带主元的普通QR无法可靠揭示矩阵秩。矩阵可能通过列顺序掩盖线性相关性,导致R的对角元素无法反映真实的秩信息。需要判断秩时,必须使用带列主元的QR分解 AΠ=QRA\Pi=QRAΠ=QR。
误区四:用经典Gram-Schmidt处理近相关列
当列向量几乎线性相关时,经典Gram-Schmidt会发生严重的正交性损失。更优的选择包括:修改Gram-Schmidt、MGS加重正交化、Householder QR、带列主元QR或SVD。
误区五:不必要地显式构造Q矩阵
若仅需计算 QTbQ^TbQTb 或 QbQbQb,无需显式生成完整的Q矩阵。在LAPACK中可直接通过Householder向量调用xORMQR例程应用正交变换,节省内存与计算量。
误区六:通过求逆求解三角方程
求解上三角方程 Rx=yRx=yRx=y 时,不应显式计算逆矩阵 x=R−1yx=R^{-1}yx=R−1y,而应直接使用三角回代算法。求逆会增加计算量、引入额外误差且占用更多内存,三角回代是更直接高效的方案。
7.2 场景选型总览
四个理解视角
可以从四个互补的角度完整理解QR分解:
- 正交基视角:Q是原矩阵列空间的一组标准正交基;
- 坐标视角:R记录原始列向量在Q基底下的坐标;
- 消元视角:Householder或Givens通过正交变换逐步消去对角线下方元素;
- 投影视角 :最小二乘中,Q1Q1TbQ_1Q_1^TbQ1Q1Tb 是b在矩阵列空间上的正交投影。
三类算法一句话总结
- Gram-Schmidt:把每个新向量在已有基上的分量逐个减掉,增量式构造正交基。
- Householder:将整段向量反射到坐标轴上,一次消去一列的多个元素。
- Givens:每次旋转两个坐标,精确消去单个指定元素。
工程选型总表
普通稠密矩阵→Householder QR可能秩亏场景→带列主元QR (QRCP)逐列正交/Krylov子空间→MGS + 重正交化稀疏矩阵或在线更新→Givens旋转严重病态或精确秩判断→SVD \boxed{ \begin{array}{ll} \text{普通稠密矩阵} & \rightarrow \text{Householder QR}\\ \text{可能秩亏场景} & \rightarrow \text{带列主元QR (QRCP)}\\ \text{逐列正交/Krylov子空间} & \rightarrow \text{MGS + 重正交化}\\ \text{稀疏矩阵或在线更新} & \rightarrow \text{Givens旋转}\\ \text{严重病态或精确秩判断} & \rightarrow \text{SVD} \end{array} } 普通稠密矩阵可能秩亏场景逐列正交/Krylov子空间稀疏矩阵或在线更新严重病态或精确秩判断→Householder QR→带列主元QR (QRCP)→MGS + 重正交化→Givens旋转→SVD
总结
QR分解的核心本质可以用一句话概括:
A=QR⟺用一组标准正交基 Q 重新表示 A 的列向量\boxed{ A=QR \quad\Longleftrightarrow\quad \text{用一组标准正交基 }Q \text{ 重新表示 }A\text{ 的列向量} }A=QR⟺用一组标准正交基 Q 重新表示 A 的列向量
作为数值线性代数的基石之一,QR分解兼顾了数值稳定性与计算效率,横跨理论与工程两大领域。从基础的正交基构造、线性方程组求解,到最小二乘拟合、特征值计算,再到机器人、计算机视觉、优化等工程领域,QR分解都发挥着不可替代的作用。