目录
线性方程组的求解是计算机视觉工程实践中经常碰到的问题,这篇文章对其常见解法进行整理和总结.先上结论:
针对线性方程组 A x = b Ax=b Ax=b的求解问题,我们按照系数矩阵 A A A的性质进行分类讨论。
1. A A A为方阵
-
d e t ( A ) ≠ 0 det(A)\neq0 det(A)=0
方程组有唯一解.
-
d e t ( A ) = 0 det(A)=0 det(A)=0
- 若 r ( A ) < r ( A , b ) r(A)<r(A,b) r(A)<r(A,b),则方程组无解
- r ( A ) = r ( A , b ) < n r(A)=r(A,b)<n r(A)=r(A,b)<n,则方程组有无穷多解
求解方法在数值分析这门课程中有详细介绍,可分为两类:
直接法
直接法主要针对低阶稠密矩阵(200阶以内)
- Gauss消去法及其改进(列选主元的Gauss消去法)
- 直接三角分解法(LU分解,LDU分解,Cholesky分解(针对对称正定矩阵),Gauss消去法的代数实质就是LU分解)
迭代法
迭代法主要针对大型矩阵,而且在实际中,这类矩阵通常在结构上有特点,比如稀疏
- 雅可比迭代法
- 高斯-赛德尔迭代法
- 超松弛(SOR)迭代法
2. A A A为非方阵且 A ∈ R m × n , m > n A\in R^{m\times n},m>n A∈Rm×n,m>n
行数大于列数,即方程数目大于未知数个数.此时方程组称为超定方程组,一般来说无精确解,但可以求其最小二乘解.所谓的最小二乘解是指:在欧几里得空间中以2-范数作为距离,使得向量
A
x
Ax
Ax与
b
b
b之间距离最小的
x
x
x.这个问题在优化理论中被称为线性最小二乘问题(这个概念与非线性最小二乘相对应,两者的区别见https://www.jianshu.com/p/bf6ec56e26bd),即我们的目标转换为下式:
min
x
∈
R
n
∥
A
x
−
b
∥
2
\min_{x\in{R^n}}{{\lVert{Ax-b}\rVert}_{2}}
x∈Rnmin∥Ax−b∥2
先给出三个定理,说明超定方程组最小二乘解的存在性和唯一性
-
定理1
超定方程组必存在最小二乘解,且 x x x是方程组的最小二乘解的充要条件是: x x x是 A T A x = A T b A^TAx=A^Tb ATAx=ATb的解
-
定理2
若 r ( A ) = n < m r(A)=n<m r(A)=n<m,超定方程组存在唯一最小二乘解
-
定理3
若 r ( A ) < n < m r(A)<n<m r(A)<n<m,则超定方程组有无穷多个最小二乘解,其中2-范数最小的解称为方程组的最小二范数解,且该解是唯一的
下面按照 A A A的秩分类讨论.
2.1. r ( A ) = n < m r(A)=n<m r(A)=n<m
此情形对应于定理2
正规方程法
证明:
∥
A
x
−
b
∥
2
2
=
(
A
x
−
b
)
T
∗
(
A
x
−
b
)
∥
A
x
−
b
∥
2
2
=
x
T
A
T
A
x
−
b
T
A
x
−
x
T
A
T
b
+
b
T
b
求
导
并
令
导
数
为
0
:
∂
∥
A
x
−
b
∥
2
2
∂
x
=
2
A
T
A
x
−
2
A
T
b
=
0
得
到
方
程
:
A
T
A
x
=
A
T
b
因
为
r
(
A
T
A
)
=
r
(
A
)
,
所
以
d
e
t
(
A
T
A
)
≠
0
x
=
(
A
T
A
)
−
1
A
T
b
{\lVert{Ax-b}\rVert}_2^2={(Ax-b)}^T*(Ax-b)\\ {\lVert{Ax-b}\rVert}_2^2=x^TA^TAx-b^TAx-x^TA^Tb+b^Tb\\ 求导并令导数为0: {\partial{{{\lVert{Ax-b}\rVert}_2}^2}\over{\partial{x}}}=2A^TAx-2A^Tb=0\\ 得到方程:A^TAx=A^Tb\\ 因为r(A^TA)=r(A),所以det(A^TA)\neq0\\ x=(A^TA)^{-1}A^Tb
∥Ax−b∥22=(Ax−b)T∗(Ax−b)∥Ax−b∥22=xTATAx−bTAx−xTATb+bTb求导并令导数为0:∂x∂∥Ax−b∥22=2ATAx−2ATb=0得到方程:ATAx=ATb因为r(ATA)=r(A),所以det(ATA)=0x=(ATA)−1ATb
A
T
A
x
=
A
T
b
A^TAx=A^Tb
ATAx=ATb称为正规方程组,
(
A
T
A
)
−
1
A
T
(A^TA)^{-1}A^T
(ATA)−1AT称为广义逆
缺点:
- 数值不稳定
- 需要求逆,计算量大
SVD法
这里先给出矩阵的SVD(奇异值分解)的定义:
对于任意给定的 A ∈ R m × n A\in R^{m\times n} A∈Rm×n,都存在正交矩阵 U ∈ R m × m U\in R^{m\times m} U∈Rm×m, V ∈ R n × n V\in R^{n\times n} V∈Rn×n使得 A = U S V T A=USV^T A=USVT
其中:
U U U的列向量为 A A T AA^T AAT的特征向量
V
V
V的列向量为
A
T
A
A^TA
ATA的特征向量
S
=
[
S
1
0
0
0
]
,
S
∈
R
m
×
n
S=\begin{bmatrix} S_1 & 0 \\ 0 & 0 \end{bmatrix},S\in R^{m\times n}
S=[S1000],S∈Rm×n
S
1
=
d
i
a
g
(
σ
1
,
.
.
.
σ
r
)
,
r
=
r
(
A
)
,
σ
1
⩾
.
.
.
⩾
σ
r
>
0
,
σ
i
为
矩
阵
A
的
奇
异
值
S_1=diag(\sigma_1,...\sigma_r),r=r(A),\sigma_1\geqslant...\geqslant\sigma_r>0,\sigma_i为矩阵A的奇异值
S1=diag(σ1,...σr),r=r(A),σ1⩾...⩾σr>0,σi为矩阵A的奇异值
矩阵的SVD分解是唯一的.
SVD如何应用到最小二乘问题的求解中呢?推导如下:
∥
A
x
−
b
∥
2
2
=
∥
U
[
S
1
0
]
V
T
x
−
b
∥
2
2
=
∥
[
S
1
0
]
V
T
x
−
U
T
b
∥
2
2
对
U
矩
阵
进
行
分
块
:
U
=
[
U
n
,
U
m
−
n
]
,
则
上
式
=
∥
[
S
1
0
]
V
T
x
−
[
U
n
,
U
m
−
n
]
T
b
∥
2
2
=
∥
[
S
1
V
T
x
−
U
n
T
b
−
U
m
−
n
T
b
]
∥
2
2
=
∥
S
1
V
T
x
−
U
n
T
b
∥
2
2
+
∥
U
m
−
n
T
b
∥
2
2
⩾
∥
U
m
−
n
T
b
∥
2
2
\Vert Ax-b\Vert_2^2=\Vert U\begin{bmatrix} S_1 \\0 \end{bmatrix}V^Tx-b\Vert_2^2=\Vert\begin{bmatrix} S_1 \\0 \end{bmatrix}V^Tx-U^Tb\Vert_2^2\\ 对U矩阵进行分块:U=[U_{n},U_{m-n}],则上式\\ =\Vert\begin{bmatrix} S_1 \\0 \end{bmatrix}V^Tx-[U_n,U_{m-n}]^Tb\Vert_2^2\\ =\Vert\begin{bmatrix} S_1 V^Tx-U_n^Tb \\ -U_{m-n}^Tb\end{bmatrix}\Vert_2^2\\ =\Vert S_1 V^Tx-U_n^Tb \Vert_2^2+\Vert U_{m-n}^Tb\Vert_2^2 \geqslant \Vert U_{m-n}^Tb\Vert_2^2
∥Ax−b∥22=∥U[S10]VTx−b∥22=∥[S10]VTx−UTb∥22对U矩阵进行分块:U=[Un,Um−n],则上式=∥[S10]VTx−[Un,Um−n]Tb∥22=∥[S1VTx−UnTb−Um−nTb]∥22=∥S1VTx−UnTb∥22+∥Um−nTb∥22⩾∥Um−nTb∥22
显然上式在
∥
S
1
V
T
x
−
U
n
T
b
∥
2
2
=
0
\Vert S_1 V^Tx-U_n^Tb \Vert_2^2=0
∥S1VTx−UnTb∥22=0时取得最小值,此时解为:
x
=
(
S
1
V
T
)
−
1
U
n
T
b
=
V
S
1
−
1
U
n
T
b
x=(S_1 V^T)^{-1}U_n^Tb=VS_1^{-1}U_n^Tb
x=(S1VT)−1UnTb=VS1−1UnTb
S
1
S_1
S1是对角矩阵,求逆非常简单,且
S
1
S_1
S1对角线上的值是按照奇异值由大到小排列的,一般而言前10%的奇异值之和就占到了总和的95%以上,因此实践中我们可以将小于某个阈值的的奇异值及其对应的左右奇异向量全部舍弃掉,进一步缩减矩阵规模
SVD解法是数值稳定的
下面我们特别讨论下超定齐次方程组
A
x
=
0
Ax=0
Ax=0的解法,该问题的目标为:
min
x
∈
R
n
∥
A
x
∥
2
s
.
t
∥
x
∥
2
=
1
\min_{x\in{R^n}}{{\lVert{Ax}\Vert}_{2}}\\ s.t\quad \|x\|_2=1
x∈Rnmin∥Ax∥2s.t∥x∥2=1
对
A
A
A进行奇异值分解:
∥
A
x
∥
2
=
∥
U
S
V
T
x
∥
2
=
∥
S
V
T
x
∥
2
记
V
T
x
=
y
{{\lVert{Ax}\Vert}_{2}}=\|USV^Tx\|_2=\|SV^Tx\|_2\\ 记V^Tx=y\\
∥Ax∥2=∥USVTx∥2=∥SVTx∥2记VTx=y
原问题转化为
min
y
∈
R
n
∥
S
y
∥
2
s
.
t
∥
y
∥
2
=
1
\min_{y\in{R^n}}\|Sy\|_2\\s.t\quad\|y\|_2=1
y∈Rnmin∥Sy∥2s.t∥y∥2=1
由于在奇异值分解中,
S
S
S矩阵的对角线元素是递减排列的,那么取
y
=
[
0
,
0
,
.
.
.
1
]
T
y=[0,0,...1]^T
y=[0,0,...1]T
此时, ∥ A x ∥ 2 = σ n \|Ax\|_2=\sigma_n ∥Ax∥2=σn, x x x为矩阵 V V V的最后一列列向量
QR分解法
这里先介绍QR分解的定义:
对于矩阵
A
∈
C
m
×
n
,
m
⩾
n
A\in C^{m\times n},m\geqslant n
A∈Cm×n,m⩾n,存在一个单位列正交矩阵
Q
∈
C
m
×
n
Q\in C^{m\times n}
Q∈Cm×n和一个上三角矩阵
R
∈
C
n
×
n
R\in C^{n\times n}
R∈Cn×n,使得:
A
=
Q
R
A=QR
A=QR
若 A A A列满秩,并要求 R R R的对角线元素都为正,则 A A A的 Q R QR QR分解存在且唯一
我们将
Q
Q
Q扩充成一个正交矩阵,记为
[
Q
,
Q
m
−
n
]
∈
R
m
×
m
[Q,Q_{m-n}]\in R^{m\times m}
[Q,Qm−n]∈Rm×m ,则推导过程如下:
∥
A
x
−
b
∥
2
2
=
∥
[
Q
,
Q
m
−
n
]
T
(
Q
R
x
−
b
)
∥
2
2
=
∥
[
R
x
−
Q
T
b
−
Q
m
−
n
T
b
]
∥
2
2
=
∥
R
x
−
Q
T
b
∥
2
2
+
∥
Q
m
−
n
T
b
∥
2
2
⩾
∥
Q
m
−
n
T
b
∥
2
2
\Vert Ax-b\Vert_2^2=\Vert [Q,Q_{m-n}]^T(QRx-b)\Vert_2^2\\ =\|\begin{bmatrix}Rx-Q^Tb\\-Q_{m-n}^Tb\end{bmatrix}\|_2^2\\ =\|Rx-Q^Tb\|_2^2+\|Q_{m-n}^Tb\|_2^2 \geqslant\|Q_{m-n}^Tb\|_2^2
∥Ax−b∥22=∥[Q,Qm−n]T(QRx−b)∥22=∥[Rx−QTb−Qm−nTb]∥22=∥Rx−QTb∥22+∥Qm−nTb∥22⩾∥Qm−nTb∥22
当且仅当
R
x
=
Q
T
b
Rx=Q^Tb
Rx=QTb时取得最小值,所以最小二乘解为:
x
=
R
−
1
Q
T
b
x=R^{-1}Q^Tb
x=R−1QTb
QR分解法是数值稳定的
以上三种解法的测试代码:
def TestOverDetermine():
A=np.array([[1,2],[3,4],[5,6]])
x=np.array([7,8]).reshape(-1,1)
b=np.dot(A,x)
x_solve_inverse=np.linalg.inv(A.T@A)@A.T@b #广义逆
print(x_solve_inverse)
U,S,V=np.linalg.svd(A) #SVD
V=V.T #注意调用numpy得到的V是我们公式里的V转置
S=np.diag(S)
x_solve_svd=V@np.linalg.inv(S)@U[:,:2].T@b
print(x_solve_svd)
q,r=np.linalg.qr(A) #qr分解
x_solve_qr=np.linalg.inv(r)@q.T@b
print(x_solve_qr)
2.2. r ( A ) < n < m r(A)<n<m r(A)<n<m
此情形对应于定理3,此时线性方程组称为亏秩方程组.
同样对
A
A
A进行SVD分解,推导如下:
∥
A
x
−
b
∥
2
2
=
∥
U
[
S
1
0
0
0
]
V
T
x
−
b
∥
2
2
=
∥
[
S
1
0
0
0
]
V
T
x
−
U
T
b
∥
2
2
对
V
进
行
矩
阵
分
块
:
V
=
[
V
r
,
V
n
−
r
]
对
U
矩
阵
进
行
分
块
:
U
=
[
U
r
,
U
m
−
r
]
,
r
=
r
(
A
)
,
则
上
式
=
∥
[
S
1
0
0
0
]
[
V
r
,
V
n
−
r
]
T
x
−
[
U
r
,
U
m
−
r
]
T
b
∥
2
2
=
∥
[
S
1
V
r
T
x
−
U
r
T
b
−
U
m
−
r
T
b
]
∥
2
2
=
∥
S
1
V
r
T
x
−
U
r
T
b
∥
2
2
+
∥
U
m
−
r
T
b
∥
2
2
⩾
∥
U
m
−
r
T
b
∥
2
2
\Vert Ax-b\Vert_2^2=\Vert U\begin{bmatrix} S_1&0 \\0&0 \end{bmatrix}V^Tx-b\Vert_2^2=\Vert\begin{bmatrix} S_1&0 \\0&0 \end{bmatrix}V^Tx-U^Tb\Vert_2^2\\ 对V进行矩阵分块:V=[V_r,V_{n-r}]\\ 对U矩阵进行分块:U=[U_{r},U_{m-r}],r=r(A),则上式\\ =\Vert\begin{bmatrix} S_1&0 \\0&0 \end{bmatrix}[V_r,V_{n-r}]^Tx-[U_r,U_{m-r}]^Tb\Vert_2^2\\ =\Vert\begin{bmatrix} S_1 V_r^Tx-U_r^Tb \\ -U_{m-r}^Tb\end{bmatrix}\Vert_2^2\\ =\Vert S_1 V_r^Tx-U_r^Tb \Vert_2^2+\Vert U_{m-r}^Tb\Vert_2^2 \geqslant \Vert U_{m-r}^Tb\Vert_2^2
∥Ax−b∥22=∥U[S1000]VTx−b∥22=∥[S1000]VTx−UTb∥22对V进行矩阵分块:V=[Vr,Vn−r]对U矩阵进行分块:U=[Ur,Um−r],r=r(A),则上式=∥[S1000][Vr,Vn−r]Tx−[Ur,Um−r]Tb∥22=∥[S1VrTx−UrTb−Um−rTb]∥22=∥S1VrTx−UrTb∥22+∥Um−rTb∥22⩾∥Um−rTb∥22
显然上式在
∥
S
1
V
r
T
x
−
U
r
T
b
∥
2
2
=
0
\Vert S_1 V_r^Tx-U_r^Tb \Vert_2^2=0
∥S1VrTx−UrTb∥22=0时取得最小值
注意这里 V r T V_r^T VrT是一个行正交向量,请不要通过直接左乘 V r S 1 − 1 V_rS_1^{-1} VrS1−1进行求解
令
y
1
=
V
r
T
x
,
y
2
=
V
n
−
r
T
x
y_1=V_r^Tx,y_2=V_{n-r}^Tx
y1=VrTx,y2=Vn−rTx, 则
y
=
V
T
x
=
[
y
1
y
2
]
=
[
S
1
−
1
U
r
T
b
y
2
]
y=V^Tx=\begin{bmatrix} y_1 \\y_2 \end{bmatrix}=\begin{bmatrix} S_1^{-1}U_r^Tb \\y_2 \end{bmatrix}
y=VTx=[y1y2]=[S1−1UrTby2]
时
∥
A
x
−
b
∥
2
2
\Vert Ax-b\Vert_2^2
∥Ax−b∥22取得最小值.此时
x
=
V
y
=
[
V
r
,
V
n
−
r
]
[
y
1
y
2
]
x=Vy=[V_r,V_{n-r}]\begin{bmatrix} y_1 \\y_2 \end{bmatrix}
x=Vy=[Vr,Vn−r][y1y2]
我们取 y 2 = 0 y_2=0 y2=0,此时 x x x的范数最小,即方程组的最小二范数解,为 x = V r S 1 − 1 U r T b x=V_rS_1^{-1}U_r^Tb x=VrS1−1UrTb
3. A A A为非方阵且 A ∈ R m × n , m < n A\in R^{m\times n},m<n A∈Rm×n,m<n
行数小于列数,即方程数目小于未知数个数.此时线性方程组称为欠定方程组.
1. r ( A ) = m < n r(A)=m<n r(A)=m<n
此时线性方程组存在无穷多解.类似于亏秩方程组,我们可以得到一个最小二范数解.推导过程也是类似的,这里不再赘述,直接给出结论:
假 设 A 矩 阵 的 S V D 分 解 为 : A = U [ S 1 0 ] V T = U [ S 1 0 ] [ V m , V n − m ] T 那 么 最 小 二 范 数 解 为 : x = V m S 1 − 1 U T b 假设A矩阵的SVD分解为:\\ A= U\begin{bmatrix} S_1&0 \end{bmatrix}V^T=U\begin{bmatrix} S_1&0 \end{bmatrix}[V_m,V_{n-m}]^T\\ 那么最小二范数解为:\\ x=V_mS_1^{-1}U^Tb\\ 假设A矩阵的SVD分解为:A=U[S10]VT=U[S10][Vm,Vn−m]T那么最小二范数解为:x=VmS1−1UTb
测试代码:
def TestUnderDetermine():
A=np.array([[1,2,3],[4,5,6]])
x=np.array([7,8,9]).reshape(-1,1)
b=np.dot(A,x)
U,S,V=np.linalg.svd(A)
S=np.diag(S)
V=V.T
x_solve=V[:,0:2]@np.linalg.inv(S)@U.T@b
print(x_solve)
print(A@x_solve)