-
Notifications
You must be signed in to change notification settings - Fork 0
/
PTDfromInit.m
85 lines (70 loc) · 2.23 KB
/
PTDfromInit.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
function [w,obj] = PTDfromInit(X,c,wInit,param)
maxIter = param.maxIter;
eps = param.eps;
M = numel(X);
w = cellfun(@(wm) projectL2(wm,1),wInit,'UniformOutput',false);
Xw = cell2mat(cellfun(@mtimes,X,w,'UniformOutput',false)');
%obj = sum(prod(Xw,2));
obj = 0;
iter = 0;
improvement = 42;
while improvement>eps && iter<maxIter
for m=1:M
Xwom = Xw; Xwom(:,m) = [];
w{m} = projectL1L2(X{m}'*prod(Xwom,2),c(m));
Xw(:,m) = X{m}*w{m};
end
objNew = sum(prod(Xw,2));
improvement = (objNew-obj)/abs(obj);
obj = objNew;
iter = iter + 1;
end
if iter==maxIter
%warning('PTDfromInit reached maximum number of iterations')
end
function xProj = projectL2(x,c)
xProj = c*x/norm(x,2);
end
function xProj = projectL1L2(x,c)
% PROJECTL1L2 L_1-L_2-projection from Witten et al. 2009
% xProj = projectL1L2(x,c)
%
% EXAMPLE
% x = rand(10,1);
% xProj = projectL1L2(x,2);
% Witten, Daniela M., Robert Tibshirani, and Trevor Hastie.
% "A penalized matrix decomposition, with applications to sparse
% principal components and canonical correlation analysis."
% Biostatistics 10.3 (2009): 515-534.
convergenceCrit = 1e-5;
maxIterSub = 100;
nMax = sum(max(abs(x))==abs(x));
if sqrt(nMax)>=c % c<=1 or pathological duplicate max values
[~,i] = max(abs(x));
xProj = zeros(numel(x),1);
xProj(i) = c*sign(x(i));
else
xProj = projectL2(x,1);
end
cont = norm(xProj,1) > c;
deltaRange = [0 max(abs(x))];
iterSub = 0;
while cont
delta = mean(deltaRange);
xProj = projectL2(softThresh(x,delta),1);
diff = norm(xProj,1) - c;
if diff>0
deltaRange(1) = delta;
else
deltaRange(2) = delta;
end
cont = abs(diff) > convergenceCrit && iterSub<=maxIterSub;
iterSub = iterSub+1;
end
function y = softThresh(x,c)
y = abs(x)-c;
y(y<0) = 0;
y = sign(x) .* y;
end
end
end