-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAAproxblock.jl
81 lines (71 loc) · 1.81 KB
/
AAproxblock.jl
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
using LinearAlgebra, TSVD
function AAproxblock(X,H,A, B, lambda, ell, max_iter, tol)
_,a2,_ = tsvd(X)
a2 = a2[1]
LAMBDA = 2*lambda*a2.^2
f = zeros(max_iter,1)
f[1] = R(X, H, A, B,lambda )
counter = 1
diff = f[1]
k,n = size(H)
m, k = size(A)
while (diff >= f[1]*tol && counter < max_iter)
_,a2,_ = tsvd(A')
a2 = a2[1]
step = 1 / (2*a2^2 + 2*lambda)
pi = H - step*(-2*transpose(A)*((X-A*H)) + 2*lambda*(H-B*X))
I = pi.<= 0
pi[I] = zeros(sum(I),1)
H = pi
if ell < k*n
hh = H[:]
I = sortperm( hh[:])
hh[I[1:n*k - ell]] = zeros(size(I[1:n*k - ell]))
H = reshape(hh,(k,n))
end
_,a2,_ = tsvd(H)
a2 = a2[1]
step = 1 / (2*a2^2);
A = A - 2*step*(-((X - A*H))*transpose(H))
for jj=1:m
A[jj,:] = transpose(projsplx(A[jj,:]))
end
if (lambda != 0)
step = 1/LAMBDA
B = B - 2*step*(-lambda*((H - B*X))*X')
for jj = 1:k
B[jj,:] = transpose(projsplx(B[jj,:]))
end
end
counter = counter + 1;
f[counter] = R(X,H,A,B, lambda)
diff = f[counter-1] - f[counter]
end
f = f[1:counter]
return H, A, B, f
end
function projsplx(b)
τ = 1
n = length(b)
bget = false
idx = sortperm(b, rev=true)
tsum = 0
@inbounds for i = 1:n-1
tsum += b[idx[i]]
tmax = (tsum - τ)/i
if tmax ≥ b[idx[i+1]]
bget = true
break
end
end
if !bget
tmax = (tsum + b[idx[n]] - τ) / n
end
@inbounds for i = 1:n
b[i] = max(b[i] - tmax, 0)
end
return b
end
function R(X, H, A, B, lambda)
return norm(X - A*H)^2 + lambda*norm(H - B*X)^2
end