开始读研了,研究方向是SLAM。SLAM中很重要的一部分是位姿估计,需要用到一些优化算法对位姿进行优化。预处理共轭梯度法PCG(Preconditioned Conjugate Gradient)是一种SLAM中常用的位姿优化算法,从共轭梯度法(Conjugate Gradient)衍生而来,用于快速计算最优值。
假设有一个线性方程:
Ax = b \textbf{A}\textbf{x} = \textbf{b} Ax=b
其中 A A A是一个已知的对称且正定的矩阵,b也已知。记 x ∗ \textbf{x}_* x∗为方程的唯一解。如果两个非零向量 u,v \textbf{u,v} u,v满足:
u T Av = 0 \textbf{u}^{\rm T}\textbf{A}\textbf{v} = 0 uTAv=0
则称 u \textbf{u} u和 v \textbf{v} v共轭(相对于 A \textbf A A)。共轭是一种对称的关系,如果 u \textbf u u对于 v \textbf v v共轭,那么 v \textbf v v对于 u \textbf u u共轭。
由于 A \textbf{A} A对称且正定,于是可以定义內积:
⟨ u , v ⟩ A : = ⟨ Au , v ⟩ = ⟨ u , A T v ⟩ = ⟨ u , Av ⟩ = u T Av \langle \textbf{u},\textbf{v} \rangle_{\textbf{A}} := \langle \textbf{A}\textbf{u},\textbf{v} \rangle = \langle \textbf{u},\textbf{A}^{\rm T}\textbf{v} \rangle = \langle \textbf{u},\textbf{A}\textbf{v} \rangle = \textbf{u}^{\rm T}\textbf{A}\textbf{v} ⟨u,v⟩A:=⟨Au,v⟩=⟨u,ATv⟩=⟨u,Av⟩=uTAv
如果有一个矩阵 P \textbf{P} P:
P = { P 1 , P 2 , . . . . , P n } \textbf{P} = \left\{\textbf{P}_{1},\textbf{P}_{2},....,\textbf{P}_{n}\right\} P={P1,P2,....,Pn}
且 P \textbf{P} P中的列向量两两共轭,那么 Ax = b \textbf{Ax} = \textbf{b} Ax=b的解 x ∗ \textbf{x}_{*} x∗可以写成:
x ∗ = ∑ i = 1 n α i P i \textbf{x}_{*} = \sum\limits_{i=1}^{n}\alpha_{i}\textbf{P}_{i} x∗=i=1∑nαiPi
于是,
A x ∗ = ∑ i = 1 n α i A P i \textbf{A}\textbf{x}_{*} = \sum\limits_{i=1}^{n}\alpha_{i}\textbf{A}\textbf{P}_{i} Ax∗=i=1∑nαiAPi
左乘 P k T \textbf{P}_{k}^{\rm T} PkT:
P k T A x ∗ = ∑ i = 1 n α i P k T A P i \textbf{P}_{k}^{\rm T}\textbf{A}\textbf{x}_{*} = \sum\limits_{i=1}^{n}\alpha_{i}\textbf{P}_{k}^{\rm T}\textbf{A}\textbf{P}_{i} PkTAx∗=i=1∑nαiPkTAPi
将 Ax = b \textbf{A}\textbf{x} = \textbf{b} Ax=b和 u T Av = ⟨ u , v ⟩ A \textbf{u}^{\rm T}\textbf{A}\textbf{v} = \langle \textbf{u},\textbf{v} \rangle_{\textbf{A}} uTAv=⟨u,v⟩A代入得:
P k T b = ∑ i = 1 n α i ⟨ P k , P i ⟩ A \textbf{P}_{k}^{\rm T}\textbf{b} = \sum\limits_{i=1}^{n}\alpha_{i}\langle\textbf{P}_k,\textbf{P}_i\rangle_{\textbf{A}} PkTb=i=1∑nαi⟨Pk,Pi⟩A
因为 u T v = ⟨ u , v ⟩ \textbf{u}^{\rm T}\textbf{v} = \langle \textbf{u},\textbf{v} \rangle uTv=⟨u,v⟩,且对于 ∀ i ̸ = k : ⟨ u , v ⟩ A = 0 \forall i\not= k:\langle \textbf{u},\textbf{v}\rangle_{\textbf{A}} = 0 ∀i̸=k:⟨u,v⟩A=0,所以:
⟨ P k , b ⟩ = α k ⟨ P k , P k ⟩ A \langle \textbf{P}_{k},\textbf{b}\rangle = \alpha_{k}\langle \textbf{P}_{k},\textbf{P}_{k}\rangle_{\textbf{A}} ⟨Pk,b⟩=αk⟨Pk,Pk⟩A
由此可以得到 α k \alpha_{k} αk的表达式:
α k = ⟨ b k , b ⟩ ⟨ P k , P k ⟩ A \alpha_{k} = \frac{\langle \textbf{b}_{k},\textbf{b}\rangle}{\langle \textbf{P}_{k},\textbf{P}_{k}\rangle_{\textbf{A}}} αk=⟨Pk,Pk⟩A⟨bk,b⟩
结合 x ∗ = ∑ i = 1 n α i A P i \textbf{x}_{*} = \sum\limits_{i=1}^{n}\alpha_{i}\textbf{A}\textbf{P}_{i} x∗=i=1∑nαiAPi就可以求解 x ∗ \textbf{x}_{*} x∗。
当 n n n很大时,用直接法求解就会非常耗时,于是引出迭代法。
为了求得 x ∗ \textbf{x}_{*} x∗的一个很好的近似,我们并不需要全部的 P k \textbf{P}_{k} Pk,当 n n n很大且 A \textbf{A} A又具有一定的稀疏性时,可以用迭代法来求得一个近似的结果。令 x ∗ \textbf{x}_{*} x∗的初始估计值为 x 0 \textbf{x}_{0} x0( x 0 = 0 \textbf{x}_{0}=\textbf{0} x0=0,etc.)。
构建二次函数:
f ( x ) = 1 2 x T Ax − x T b f(x) = \frac{1}{2}\textbf{x}^{\rm T}\textbf{A}\textbf{x} - \textbf{x}^{\rm T}\textbf{b} f(x)=21xTAx−xTb
该函数一、二阶导为:
D f ( x ) = Ax − b , Df(x) = \textbf{A}\textbf{x} - \textbf{b}, Df(x)=Ax−b,
D 2 f ( x ) = A , D^2f(x) = \textbf{A}, D2f(x)=A,
由于 A \textbf{A} A对称且正定, f ( x ) f(x) f(x)有唯一最小值。取 P 0 \textbf{P}_{0} P0为 f ( x ) f(x) f(x)在 x 0 \textbf{x}_{0} x0处的负梯度,即 P 0 = b − Ax 0 \textbf{P}_{0} = \textbf{b} - \textbf{Ax}_{0} P0=b−Ax0, P 0 \textbf{P}_{0} P0同时也是算法初始步骤的残差项。
令 r k \textbf{r}_{k} rk为第 k k k步的残差:
r k = b − Ax k \textbf{r}_{k} = \textbf{b} - \textbf{Ax}_{k} rk=b−Axk
r k \textbf{r}_{k} rk也是梯度下降法中的下降方向,在共轭梯度法中,为保证当前下降方向与之前步骤中的下降方向共轭,取:
P k = r k − ∑ i < k P i T A r k P i T A P i P i \textbf{P}_{k} = \textbf{r}_{k} - \sum\limits_{i<k}{}\frac{\textbf{P}_{i}^{\rm T}\textbf{A}\textbf{r}_{k}}{\textbf{P}_{i}^{\rm T}\textbf{A}\textbf{P}_{i}}\textbf{P}_{i} Pk=rk−i<k∑PiTAPiPiTArkPi
沿着这个方向,更新后的 x \textbf{x} x值为:
x k + 1 = x k + α k P k \textbf{x}_{k+1} = \textbf{x}_{k} + \alpha_{k}\textbf{P}_{k} xk+1=xk+αkPk
其中
α k = P k T ( b − Ax k ) P k T A P k = P k T r k P k T A P k \alpha_k = \frac{\textbf{P}_k^{\rm T}\left(\textbf{b} - \textbf{Ax}_{k}\right)}{\textbf{P}_k^{\rm T}\textbf{A}\textbf{P}_k} = \frac{\textbf{P}_k^{\rm T}\textbf{r}_k}{\textbf{P}_k^{\rm T}\textbf{A}\textbf{P}_k} αk=PkTAPkPkT(b−Axk)=PkTAPkPkTrk
α k \alpha_{k} αk通过最小化下式得到,
f ( x k + 1 ) = f ( x k + α k P k ) = : g ( α k ) f(\textbf{x}_{k+1}) = f(\textbf{x}_{k} + \alpha_{k}\textbf{P}_{k}) =: g(\alpha_{k}) f(xk+1)=f(xk+αkPk)=:g(αk)
令其对 α k \alpha_k αk的导数为0。
g ′ ( α k ) = ! 0 ⇔ α k = P k T ( b − Ax k ) P k T AP k g'(\alpha_{k})\stackrel{!}{=}0\quad\Leftrightarrow\quad \alpha_{k} = \frac{\textbf{P}_{k}^{\rm T}(\textbf{b} - \textbf{Ax}_{k})}{\textbf{P}_{k}^{\rm T}\textbf{AP}_{k}} g′(αk)=!0⇔αk=PkTAPkPkT(b−Axk)
r 0 : = b − Ax 0 \textbf{r}_{0} := \textbf{b} - \textbf{Ax}_{0} r0:=b−Ax0
P 0 : = r 0 \textbf{P}_0 := \textbf{r}_0 P0:=r0
k : = 0 k := 0 k:=0
repeat
α k : = r k T r k P k T AP k \alpha_{k} := \frac{\textbf{r}_k^{\rm T}\textbf{r}_k}{\textbf{P}_{k}^{\rm T}\textbf{AP}_{k}} αk:=PkTAPkrkTrk
x k + 1 : = x k + α k P k \textbf{x}_{k+1} := \textbf{x}_{k} + \alpha_{k}\textbf{P}_{k} xk+1:=xk+αkPk
r k + 1 : = r k − α k A P k \textbf{r}_{k+1} := \textbf{r}_k - \alpha_k\textbf{A}\textbf{P}_k rk+1:=rk−αkAPk
if r k + 1 \textbf{r}_{k+1} rk+1 is suffiently small ,then exit loop.
β k : = r k + 1 T r k + 1 r k T r k \beta_k := \frac{\textbf{r}_{k+1}^{\rm T}\textbf{r}_{k+1}}{\textbf{r}_k^{\rm T}\textbf{r}_k} βk:=rkTrkrk+1Trk+1
P k + 1 : = r k + 1 + β k P k \textbf{P}_{k+1} := \textbf{r}_{k+1} + \beta_k\textbf{P}_{k} Pk+1:=rk+1+βkPk
k : = k + 1 k := k + 1 k:=k+1
end repeat
function [x] = conjgrad(A, b, x)
r = b - A * x;
p = r;
rsold = r' * r;
for i = 1:length(b)
Ap = A * p;
alpha = rsold / (p' * Ap);
x = x + alpha * p;
r = r - alpha * Ap;
rsnew = r' * r;
if sqrt(rsnew) < 1e-10
break;
end
p = r + (rsnew / rsold) * p;
rsold = rsnew;
end
end
没写完,待续、