%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright (C) 2020 Zaiwen Wen, Haoyang Liu, Jiang Hu
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see .
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Change log:
%
% 2017.6.10 (Chao Ma):
% First version
%
% 2020.6.23 (Jiang Hu):
% Parameter tuning
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 编码衍射模型 LM 子问题的预条件(截断)共轭梯度算法
% 考虑LM 方程对应的无约束二次优化问题:
%
% $$ \displaystyle\min_d \frac{1}{2}\|r^k\|^2+d^\top(J^k)^\top r^k
% +\frac{1}{2}d^\top\left((J^k)^\top J^k+\mu I\right)d, $$
%
% 利用预条件共轭梯度法进行近似求解。
% 为了记号的方便,在下文我们用 $x$ 表示问题的自变量,
% $r$ 表示共轭梯度法中的残差变量。预条件共轭梯度法在共轭梯度法的基础上,引入 $\hat{x}=Cx$。
% 因此,对于问题
%
% $$\min_x \frac{1}{2}x^\top A x -b^\top x,$$
%
% 采用预条件共轭梯度法等于使用共轭梯度法求解如下问题
%
% $$\min_{\hat{x}}\frac{1}{2}\hat{x}^\top(C^{-\top}AC^{-1})\hat{x}-(C^{-\top}b)^\top\hat{x}.$$
%
% 预条件共轭梯度法的迭代格式为(其中记 $M=C^\top C$)
%
% $$ \begin{array}{rl}
% \displaystyle Mz^{k}&\hspace{-0.5em}=r^{k}, \\
% \displaystyle\beta_{k}&\hspace{-0.5em}=
% \displaystyle\frac{(r^{k})^\top z^{k}}{(r^{k-1})^\top z^{k-1}}, \\
% \displaystyle p^{k}&\hspace{-0.5em}=z^{k}+\beta_{k} p^{k-1}, \\
% \displaystyle\alpha_k &\hspace{-0.5em}=
% \displaystyle\frac{(r^k)^\top z^{k}}{(p^{k})^\top A p^k},\\
% \displaystyle x^{k+1}&\hspace{-0.5em}=x^k+\alpha_k p^{k}, \\
% \displaystyle r^{k+1}&\hspace{-0.5em}=r^k-\alpha_k Ap^{k}.
% \end{array}$$
%% 初始化和迭代准备
% 输入信息:当前迭代点 $z$,采样信号矩阵 $A$,观测模长 $y$,最大迭代次数 |ite_max|
% 和判断精度的标志 |acu| 。
% 输出信息:返回LM 方程的解 $d$ (记为 |solu| )和包含迭代信息的结构体 |info|,
% |info.ite| 记录迭代次数,
% |info.prod| 记录矩阵向量积的次数。
function [solu, info] = CG_CDP( z, A, y, ite_max, acu )
[n,L]=size(A);
l=norm(z)^2;
m=n*L;
%%%
% 计算信号 $z$的在衍射变换下的结果:
% $M_{(k,l)}=\displaystyle\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi
% (k-1)t/n}$。
% 注意到 MATLAB 函数 |fft| 对于矩阵输入,对其每一列计算一维的离散傅里叶变换。
rsd=fft(conj(A).*(z*ones(1,L)));
%%%
% 计算 $\mu=\displaystyle\sqrt{\frac{1}{2nL}\sum_{k=1}^{n}\sum_{\ell=1}^L
% r_{(k,\ell)}(z)}$。注意到对于编码衍射模型, $r_{k,\ell}(z)=\displaystyle\frac{1}{2}\left(
% \left|\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi kt/n} \right|^2 -
% b_{k,\ell} \right)$。
%
% $\ell=\|z\|_2^2$, $a=\frac{1}{\ell+\mu}$,
% $b=-\frac{3}{2(\ell+\mu)(4\ell+\mu)}$ 作为预条件中的两个参数。
mu=sqrt(sum(sum((abs(rsd).^2-y).^2))/2/m);
a=1/(l+mu);
b=-3/(2*(l+mu)*(4*l+mu));
%%%
% 由 Wirtinger 导数,有
%
% $$ \nabla f(z)=\displaystyle\sum_{k=1}^{n}\sum_{\ell=1}^L
% \left(|\bar{a}_{k,l}^\top z-b_{k,l}|\right)a_{k,l}\bar{a}_{k,l}^\top z. $$
%
% 计算矩阵 |t|,其 $(k,\ell)$ 元素为
% $\displaystyle\left(\left|\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi
% kt/n}\right|^2-b_{(k+1,l)}\right)\left(\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi kt/n}
% \right).$
t=(abs(rsd).^2-y).*rsd;
%%%
% $g(s)=\displaystyle\frac{1}{nL}\sum_{\ell=1}^L\sum_{k=0}^{n-1}
% \left(\left|\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi kt/n}\right|^2-b_{(k+1,\ell)}
% \right)\left(\sum_{t=0}^{n-1}z_t\bar{d}_\ell(t)e^{-i2\pi kt/n}\right)
% d_\ell(s)e^{i2\pi sk/n}.$
%
% 计算梯度 $g=\nabla f(x)$。
g=mean(A.*ifft(t),2);
%%%
% 初始化。这里使用预优矩阵,计算$Mx^0=g^0$,其中 $M^{-1}=aI+2bz\bar{z}^\top$。
xk=a*g+b*(2*real(z'*g))*z;
%%%
% $s=(\Phi(x^0)+\mu I)x^0$,这里的推导和下文迭代主循环中一致,省略。
t1=abs(rsd).^2.*fft(conj(A).*(xk*ones(1,L)));
t2=n*rsd.^2.*ifft(A.*(conj(xk)*ones(1,L)));
s1=mean(A.*ifft(t1),2);
s2=mean(A.*ifft(t2),2);
s=s1+s2+mu*xk;
%%%
% 残差的初始化:$r^0=g^0-(\Phi(x^0)+\mu I)x^0$。
rk=g-s;
%%%
% 在 |acu| 为1的情况下采用更精确的 LM 方法,取 $\eta_k=\min
% \{0.1,\|\nabla f(\mathbf{x}^k)\|\}$; 否则,采取 $\eta_k=0.1$。
if acu == 1
cri = min(0.1,min(0.1*norm(g),norm(g)^2));
else
cri = min(0.1,0.1*norm(g));
end
%%%
% 迭代次数记为 0。以 $\|r^k\|$ 为收敛判断依据。
K=0;
C=norm(rk);
%% 迭代循环
%%%
% 当 $\|r^k\|$ 小于阈值或者迭代次数超过限制时,停止迭代。
while Kcri
%%%
% 从预条件方程中解得 $z_k$,有 $M z_k=r_k$。这里我们取 $M^{-1}=aI+2bz\bar{z}^\top$,
% 可以推出 $z^{k}=ar^k+2b(\bar{z}^\top r^kz)$。注意到这里的 $z$ 不是迭代变量,而是迭代的初始值。
zk=a*rk+b*(2*real(z'*rk))*z;
K=K+1;
%%%
% 初次迭代,取 $p_0=z_0$, $\beta_0=1$。
if K==1
pk=zk;
rho=2*real(rk'*zk);
else
%%%
% 令 $\displaystyle\beta_{k}=\frac{(r^{k})^\top z^{k}}{(r^{k})^\top
% z^{k}}$,
% $\displaystyle p^{k}=z^{k}+\beta_{k} p^{k-1}$。
rho1=rho;
rho=2*real(rk'*zk);
beta=rho/rho1;
pk=zk+beta*pk;
end
%%%
% $$ \begin{array}{rl}
% s_1=&\hspace{-0.5em}\sum_{j=1}^m |\bar{a}_j^\top x|^2 a_j\bar{a_j}^\top
% p^k,\\
% s_2=&\hspace{-0.5em}\sum_{j=1}^m (a_j^\top x)^2a_ja_j^\top \bar{p}_k.
% \end{array}$$
t1=abs(rsd).^2.*fft(conj(A).*(pk*ones(1,L)));
s1=mean(A.*ifft(t1),2);
t2=n*rsd.^2.*ifft(A.*(conj(pk)*ones(1,L)));
s2=mean(A.*ifft(t2),2);
%%%
% 计算高斯-牛顿矩阵
%
% $$ \Phi(\mathbf{x})=\overline{J(\mathbf{x})}^\top J(\mathbf{x})=
% \sum_{j=1}^m\left[ \begin{array}{ll}|\bar{a}_j^\top x|^2a_j\bar{a}_j^\top &
% (\bar{a}_j^\top x)^2a_ja_j^\top\\
% (\overline{\bar{a}_j^\top x})^2\bar{a}_j\bar{a}_j^\top &
% |\bar{a}_j^\top x|^2\bar{a}_ja_j^\top\end{array} \right]
% = \left[ \begin{array}{ll} \Phi_{11} & \Phi_{12} \\
% \bar{\Phi}_{12} & \bar{\Phi_{11}} \end{array} \right].$$
%
% 考虑到共轭,我们只取上半部分,令 $\Psi(x)=\left[ \Phi_{11} \Phi_{12} \right]$,
% $\mathbf{p}=\left[\begin{array}{l} p\\\bar{p} \end{array}\right]$,则有
% $(\Psi(x)+\mu [I,0])\mathbf{p}=s_1+s_2+\mu p$。
%
% 预条件共轭梯度法的步长 $\alpha_k=\frac{(r^k)^\top z^k}{(p^k)^\top (\Phi(x)+\mu
% I)}p^k$。
s=s1+s2+mu*pk;
alpha=rho/(2*real(pk'*s));
%%%
% 共轭梯度法的迭代步, $\displaystyle x^{k+1}=x^k+\alpha_k p^k$,
% $\displaystyle r^{k+1}=r^k-\alpha_k (\Phi(x)+\mu I)p^k$。
xk=xk+alpha*pk;
rk=rk-alpha*s;
% 以 $r^k$ 的模长作为停机判断依据。
C=norm(rk);
end
%%%
% 退出迭代时,记录当前迭代步、矩阵向量积次数。返回 $x^k$ 为解。
info.ite=K;
info.prod=6+4*info.ite;
solu=xk;
end
%% 参考页面
% 此页面被 调用。
%
% 此页面的源代码请见: <../download_code/phase_LM/CG_CDP.m CG_CDP.m>。
%% 版权声明
% 此页面为《最优化:建模、算法与理论》、《最优化计算方法》配套代码。
% 代码作者:文再文、刘浩洋、户将,代码整理与页面制作:杨昊桐。
%
% 著作权所有 (C) 2020 文再文、刘浩洋、户将