-
Notifications
You must be signed in to change notification settings - Fork 62
/
NormL12.m
58 lines (49 loc) · 1.5 KB
/
NormL12.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
classdef NormL12 < NormObj
properties
blocksize = 1
end
methods
function obj = NormL12(blocksize, weights)
obj = obj@NormObj();
obj.blocksize = blocksize;
if (nargin == 2)
obj.weights = weights;
end
end
function p = primal(obj, x)
m = round(length(x) / obj.blocksize); n = obj.blocksize;
if isreal(x)
p = sum(obj.weights.*sqrt(sum(reshape(x,m,n).^2,2)));
else
p = sum(obj.weights.*sqrt(sum(abs(reshape(x,m,n)).^2,2)));
end
end
function d = dual(obj, y)
m = round(length(y) / obj.blocksize); n = obj.blocksize;
if isreal(y)
d = norm(sqrt(sum(reshape(y,m,n).^2,2))./obj.weights,inf);
else
d = norm(sqrt(sum(abs(reshape(y,m,n)).^2,2))./obj.weights,inf);
end
end
function p = project(obj, x, tau)
% Convert to matrix
m = round(length(x) / obj.blocksize); n = obj.blocksize;
x = reshape(x,m,n);
% Compute two-norms of rows
if isreal(x)
xa = sqrt(sum(x.^2,2));
else
xa = sqrt(sum(abs(x).^2,2));
end
% Project one one-norm ball
idx = xa < eps;
xc = oneProjector(xa,obj.weights,tau);
% Scale original
xc = xc ./ xa; xc(idx) = 0;
p = spdiags(xc,0,m,m)*x;
% Vectorize result
p = p(:);
end
end
end