天天看點

利用matlab采用ADMM算法對稀疏信号進行複原

在這篇文章中中,我将給出如何實作稀疏信号恢複的ADMM方法的細節。具體代碼如下:

clear; close all; clc;
rng(0);  % for reproducibility, do not change it!
m = 50;  % num samples
n = 200; % num variables, note that n > m

A = rand(m, n);  % simulate matrix A 模拟矩陣A
x = zeros(n, 1); % simulate true sparse signal x: line 13-16 模拟稀疏信号
nz = 10;         % 
nz_idx = randperm(n);
x(nz_idx(1:nz)) = 2 * rand(nz, 1);
y = A*x;         % simulate a degraded signal
y = y + 0.1 * rand(m, 1); % add some noise to the degraded signal




[m, n] = size(A);


b = zeros(n,1);  %n行1列
b1 = zeros(m,1);
b2 = zeros(n,1);

beta1 = 1e-1;  % The para. in Algrithm 1
beta2 = 1e-2;
lambda = 1e-2;

k=0;
ReErr=1;
maxitr = 500;
tol  = 1e-8;
b_old = b;
b1_old = b1;
b2_old = b2;

while ReErr> tol && k<maxitr

u_old = sign(y-A*b_old-b1_old).*max(abs(y-A*b_old-b1_old)-1/beta1,0) ;%第一次計算u



v_old = sign(b_old-b2_old).*max(abs(b_old-b2_old)-lambda /beta2,0) ;%第一次計算v




I = eye(n,n);
b_new = (inv(beta1*((A.')*A)+beta2.*I))*(beta2*(v_old+b2_old)-beta1*(A.')*(u_old-y +b1_old));%更新b的值







b1_new = b1_old+1.618*(u_old-(y-A*b_new));
b2_new = b2_old+1.618*(v_old-b_new);
b1_old = b1_new;
b2_old = b2_new;


ReErr = norm((b_new-b_old),2)./ norm(b_new,2);
b_old = b_new;



k=k+1;
    
end


figure,
subplot(1, 3, 1);
plot(x,'b-','Linewidth',2), axis tight;
title('Original signal: b');

subplot(1, 3, 2);
plot(y,'r-','Linewidth',2), axis tight;
title('Noisy signal: y=Ab');

subplot(1, 3, 3);
plot(b_old,'g-','Linewidth',2), axis tight;
title('recoverd signal: b by the solution of (1)');


`
           

繼續閱讀