-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is an example of low rank matrix completion by pure ADMM. More explanation can be found in the code comments.
- Loading branch information
1 parent
f65b188
commit cfe7a64
Showing
2 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
function out = lrmcADMM(Y,I,P,opts) | ||
|
||
|
||
%Created on 31/12/2019 by Tarmizi Adam (Email: [email protected]). | ||
% This code solves the noisy matrix completion problem with ADMM. The original | ||
% problem is the following: | ||
% | ||
% minimize_X F(X) = 0.5*||Y_omega - X_omega||^2_2 + lambda||X||_* | ||
% | ||
% We re-write the problem as the follows(used in this code) | ||
% | ||
% minimize_X F(X) = 0.5*||M_omega||^2_2 + lambda||X||_* | ||
% subject to, M_omega + X_omega = Y_omega, | ||
% | ||
% and solve using ADMM. | ||
% | ||
% Input: Y: The noisy and corrupted matrix (observation) | ||
% I: Original matrix | ||
% P: The mask, location of zero pixels/entries. | ||
% opts: Options, see "lrmcADMM_Demo" file. | ||
% | ||
% Output: Xk: Estimated low rank matrix. | ||
|
||
|
||
lam = opts.lam; % Regularization parameter | ||
Nit = opts.Nit; % Number of iteration for algorithm termination | ||
tol = opts.tol; % Tolerance for algorithm stopping criteria. | ||
|
||
relError = zeros(Nit,1); | ||
|
||
Xk = zeros(size(I)); % Initialize Xk | ||
mu = zeros(size(I)); % Lagrange multiplier | ||
M = Xk; % Initialize M (see objective function being solved) | ||
|
||
beta = 0.5; %Parameter related to the augmented Lagrange term. | ||
|
||
|
||
%% ***** Main Loop ***** | ||
|
||
for k =1:Nit | ||
|
||
X_old = Xk; | ||
|
||
%***** X Subproblem **** | ||
|
||
V = Xk - (P.*M + P.*Xk - Y - mu/beta); | ||
|
||
Xk = svt(V,lam/beta); | ||
|
||
%***** M subproblem ***** | ||
RHS = beta*Y - beta*(P.*Xk) + mu; | ||
|
||
M = RHS./(beta + 1); | ||
|
||
%***** Update Lagrange multipliers ***** | ||
|
||
mu = mu - beta*(P.*M - Y + P.*Xk); | ||
|
||
Err = Xk - X_old; | ||
relError(k) = norm(Err,'fro')/norm(Xk,'fro'); | ||
|
||
if relError(k) < tol | ||
break; | ||
end | ||
|
||
end | ||
|
||
%% ***** End Main Loop ***** | ||
|
||
out.sol = Xk; | ||
out.err = relError(1:k); | ||
|
||
|
||
end | ||
|
||
function Z = shrink(X,r) %Shrinkage operator | ||
Z = sign(X).*max(abs(X)- r,0); | ||
end | ||
|
||
function Z = svt(X, r) %Singular value thresholding | ||
|
||
[U, S, V] = svd(X); | ||
s = shrink(S,r); | ||
|
||
Z = U*s*V'; | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
% This demo files solve the low rank matrix completion problem applied to | ||
% image inpainting. In this demo, we apply the Alternating Direction Method | ||
% of Multipliers (ADMM) to do so. | ||
|
||
% Created by Tarmizi Adam on 31/12/2019. For furter assistance on the ADMM | ||
% algorithm used for the matrix completion problem, refer to the file | ||
% "lrmcADMM.m" file. | ||
% | ||
|
||
clc; | ||
clear all; | ||
close all; | ||
|
||
%% For image inpainting %% | ||
|
||
X = imread('peppers.bmp'); | ||
X = double(X); | ||
|
||
[n1,n2] =size(X); | ||
|
||
%% Create projection matrix %% | ||
MisLvl = 0.2; % percentage of missing pixels/entries, change here. | ||
|
||
J = randperm(n1*n2); | ||
J = J(1:round(MisLvl*n1*n2)); | ||
P = ones(n1*n2,1); | ||
P(J) = 0; | ||
P = reshape(P,[n1,n2]); % our projection matrix | ||
|
||
%% Simulate our corrupted original matrix %% | ||
Y = X(:); | ||
sigma = 30; %noise level | ||
noise = sigma*randn(n1*n2,1); | ||
|
||
Y = Y + noise; | ||
Y = reshape(Y,[n1,n2]); | ||
Y = P.*Y; % Our final noisy + missing entry matrix (Observation) | ||
|
||
opts.lam = 800; % Regularization parameter. Play with this and see effects. | ||
opts.Nit = 500; % Number of iteration for algorithm termination | ||
opts.tol = 1e-3; | ||
|
||
out = lrmcADMM(Y,X,P,opts); % Call ADMM solver for matrix completion. | ||
|
||
figure; | ||
imshow(out.sol,[]); | ||
|
||
figure; | ||
imshow(X,[]); | ||
|
||
figure; | ||
imshow(Y,[]); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|