预处理共轭梯度法(PCG)

开始读研了,研究方向是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,vA:=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=1nα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=1nα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=1nα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,vA代入得:
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=1nαiPkPiA

因为 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,vA=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=αkPk,PkA

由此可以得到 α 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,PkAbk,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=1nα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)=21xTAxxTb

该函数一、二阶导为:

D f ( x ) = Ax − b , Df(x) = \textbf{A}\textbf{x} - \textbf{b}, Df(x)=Axb

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=bAx0 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=bAxk

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=rki<kPiTAPiPiTArkPi

沿着这个方向,更新后的 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(bAxk)=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(bAxk)

共轭梯度法流程


r 0 : = b − Ax 0 \textbf{r}_{0} := \textbf{b} - \textbf{Ax}_{0} r0:=bAx0
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

没写完,待续、

你可能感兴趣的:(数值优化)