164 lines
3.5 KiB
Matlab
164 lines
3.5 KiB
Matlab
function [yhat,a] = bsplineSmoothDecompauto(y,B,Ba,lambda,gamma,maxIter,errtol)
|
|
%% Smooth decomposition methods
|
|
%
|
|
%
|
|
% Parameters:
|
|
% -----------------
|
|
% y : Signal/image to be decomposed
|
|
% B : Basis for mean
|
|
% Ba : Basis for anomalies
|
|
% lambda : Smoothing Parameter, the algorithm will decide if empty
|
|
% gamma : Sparsity Parameter, the algorithm will decide if empty
|
|
% -----------------
|
|
% Output:
|
|
% -----------------
|
|
% yhat : mean
|
|
% a : Anomalies
|
|
% This code is created by Hao Yan? June 8th, 2017
|
|
% If you have any questions, please contact HaoYan@asu.edu
|
|
% Paper: Yan, Hao, Kamran Paynabar, and Jianjun Shi. "Anomaly detection in images with smooth background via smooth-sparse decomposition." Technometrics 59.1 (2017): 102-114.
|
|
|
|
%% Test & prepare the variables
|
|
%---
|
|
|
|
plus0 = @(x) (x>0).*x;
|
|
|
|
% default parameters setup
|
|
if nargin<7
|
|
errtol = 1e-6;
|
|
if nargin<6
|
|
maxIter = 20;
|
|
end
|
|
end
|
|
|
|
isAutoLambda = isempty(lambda);
|
|
isAutoGamma = isempty(gamma);
|
|
|
|
sizey = size(y);
|
|
ndim = sum(sizey~=1);
|
|
|
|
if ndim == 1
|
|
Lbs = 2*norm(Ba{1})^2;
|
|
X = zeros(size(Ba{1},2),1);
|
|
BetaA = zeros(size(Ba{1},2),1);
|
|
|
|
elseif ndim == 2
|
|
Lbs = 2*norm(Ba{1})^2*norm(Ba{2})^2;
|
|
X = zeros(size(Ba{1},2),size(Ba{2},2));
|
|
BetaA = zeros(size(Ba{1},2),size(Ba{2},2));
|
|
end
|
|
|
|
if numel(lambda) == 1
|
|
lambda = ones(ndim,1)*lambda;
|
|
end
|
|
|
|
|
|
SChange = 1e10;
|
|
H = cell(ndim,1);
|
|
a = zeros(size(y));
|
|
C = cell(ndim,1);
|
|
Z = cell(ndim,1);
|
|
|
|
for idim = 1:ndim
|
|
Li = sqrtm(B{idim}'*B{idim});
|
|
Li = Li + 1e-8*eye(size(Li));
|
|
Di = diff(eye(size(B{idim},2)),1);
|
|
[Ui,C{idim},~] = svd((Li')\(Di'*Di)/(Li));
|
|
Z{idim} = B{idim}/(Li')*Ui;
|
|
end
|
|
|
|
iIter = 0;
|
|
t = 1;
|
|
|
|
%
|
|
|
|
while SChange > errtol && iIter < maxIter
|
|
|
|
iIter = iIter + 1;
|
|
Sold = a;
|
|
BetaSold = BetaA;
|
|
told = t;
|
|
gcv = @(x) splinegcv(x,y,C,Z,0,[]);
|
|
|
|
if isAutoLambda && iIter==1
|
|
lambda = fminbnd(gcv,1e-2,1e3);
|
|
lambda = ones(ndim,1)*lambda;
|
|
end
|
|
% %
|
|
|
|
for idim = 1:ndim
|
|
H{idim} = Z{idim}*diag(1./(ones(size(C{idim},1),1) + lambda(idim)*diag(C{idim})))*Z{idim}';
|
|
end
|
|
if ndim == 1
|
|
yhat = H{1}*(y-a);
|
|
BetaSe = X + 2/Lbs*Ba{1}'*(y -Ba{1}*X - yhat);
|
|
elseif ndim == 2
|
|
yhat = H{1}*(y-a)*H{2};
|
|
BetaSe = X + 2/Lbs*Ba{1}'*(y -Ba{1}*X*Ba{2}' - yhat)*Ba{2};
|
|
end
|
|
|
|
maxYe = max(abs(BetaSe(:)));
|
|
%
|
|
if isAutoGamma && mod(iIter,5)==1
|
|
gamma = graythresh(abs(BetaSe)/maxYe)*maxYe*Lbs;
|
|
end
|
|
|
|
BetaA = wthresh(BetaSe,'h',gamma/Lbs); % change 'h' to 's' for softthresholding
|
|
if ndim == 1
|
|
a = Ba{1} *BetaA;
|
|
elseif ndim==2
|
|
a = Ba{1} *BetaA* Ba{2}';
|
|
end
|
|
t = (1+sqrt(1+4*told^2))/2;
|
|
if iIter==1
|
|
X = BetaA;
|
|
else
|
|
X = BetaA+(told-1)/t*(BetaA-BetaSold);
|
|
end
|
|
SChange = sum(sum(sum((a - Sold).^2)));
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function [ GCVscore ] = splinegcv( lambda,Y,C,Z,nmiss,W )
|
|
% Estimate Generalized Cross-validation value
|
|
|
|
ndim = sum(size(Y)~=1);
|
|
H = cell(ndim,1);
|
|
dfi = zeros(ndim,1);
|
|
for idim = 1:ndim
|
|
%%
|
|
H{idim} = Z{idim}*diag(1./(ones(size(C{idim},1),1) + lambda*diag(C{idim})))*Z{idim}';
|
|
dfi(idim) = sum(1./(1+lambda*diag(C{idim})));
|
|
end
|
|
|
|
|
|
df = prod(dfi);
|
|
if ndim == 1
|
|
Yhat = H{1}*Y;
|
|
elseif ndim == 2
|
|
Yhat = H{1}*Y*H{2};
|
|
elseif ndim >= 3
|
|
Yhat = double(ttm(tensor(Y),H));
|
|
end
|
|
|
|
if(isempty(W))
|
|
RSS = sum(sum(sum((Y-Yhat).^2)));
|
|
else
|
|
RSS = sum(sum(sum((Y-Yhat).*W.*(Y-Yhat))));
|
|
end
|
|
|
|
n = numel(Y);
|
|
GCVscore = RSS/(n-nmiss)/(1-df/n)^2;
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|