forked from barbosaaob/lrr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
inexact_alm_lrr_l21.py
64 lines (56 loc) · 1.7 KB
/
inexact_alm_lrr_l21.py
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
import numpy as np
from solve_l1l2 import solve_l1l2
def inexact_alm_lrr_l21(X, A, lamb, display=False):
tol = 1e-8
maxIter = 1e6
d, n = X.shape
m = A.shape[1]
rho = 1.1
max_mu = 1e10
mu = 1e-6
atx = A.T.dot(X)
inv_a = np.linalg.inv(A.T.dot(A) + np.eye(m))
# Initializing optimization variables
# intialize
J = np.zeros((m, n))
Z = np.zeros((m, n))
E = np.zeros((d, n)) # sparse
Y1 = np.zeros((d, n))
Y2 = np.zeros((m, n))
# Start main loop
iter = 0
if display:
print "initial,rank=%f" % np.linalg.matrix_rank(Z)
while iter < maxIter:
iter += 1
# update J
temp = Z + Y2 / mu
U, sigma, V = np.linalg.svd(temp, 'econ')
V = V.T
svp = len(np.flatnonzero(sigma > 1.0 / mu))
if svp >= 1:
sigma = sigma[0:svp] - 1.0 / mu
else:
svp = 1
sigma = np.array([0])
J = U[:, 0:svp].dot(np.diag(sigma).dot(V[:, 0:svp].T))
# udpate Z
Z = inv_a.dot(atx - A.T.dot(E) + J + (A.T.dot(Y1) - Y2) / mu)
# update E
xmaz = X - A.dot(Z)
temp = xmaz + Y1 / mu
E = solve_l1l2(temp, lamb / mu)
leq1 = xmaz - E
leq2 = Z - J
stopC = max(np.max(np.abs(leq1)), np.max(np.abs(leq2)))
if display and (iter == 1 or np.mod(iter, 50) == 0 or stopC < tol):
print "iter", iter, ",mu=", mu, ",rank=", \
np.linalg.matrix_rank(Z, tol=1e-3*np.linalg.norm(Z, 2)), \
",stopALM=", stopC
if stopC < tol:
break
else:
Y1 += mu * leq1
Y2 += mu * leq2
mu = min(max_mu, mu * rho)
return (Z, E)