-
Notifications
You must be signed in to change notification settings - Fork 51
/
l1.py
57 lines (46 loc) · 1.69 KB
/
l1.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
#Sources: http://cvxopt.org/examples/mlbook/l1.html?highlight=l1
from cvxopt import blas, lapack, solvers
from cvxopt import matrix, spdiag, mul, div, sparse
from cvxopt import spmatrix, sqrt, base
def l1(P, q):
m, n = P.size
c = matrix(n*[0.0] + m*[1.0])
h = matrix([q, -q])
def Fi(x, y, alpha = 1.0, beta = 0.0, trans = 'N'):
if trans == 'N':
u = P*x[:n]
y[:m] = alpha * ( u - x[n:]) + beta*y[:m]
y[m:] = alpha * (-u - x[n:]) + beta*y[m:]
else:
y[:n] = alpha * P.T * (x[:m] - x[m:]) + beta*y[:n]
y[n:] = -alpha * (x[:m] + x[m:]) + beta*y[n:]
def Fkkt(W):
d1, d2 = W['d'][:m], W['d'][m:]
D = 4*(d1**2 + d2**2)**-1
A = P.T * spdiag(D) * P
lapack.potrf(A)
def f(x, y, z):
x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:])
+ mul( .5*D, z[:m]-z[m:] ) )
lapack.potrs(A, x)
u = P*x[:n]
x[n:] = div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) +
mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 )
z[:m] = div(u-x[n:]-z[:m], d1)
z[m:] = div(-u-x[n:]-z[m:], d2)
return f
uls = +q
lapack.gels(+P, uls)
rls = P*uls[:n] - q
x0 = matrix( [uls[:n], 1.1*abs(rls)] )
s0 = +h
Fi(x0, s0, alpha=-1, beta=1)
if max(abs(rls)) > 1e-10:
w = .9/max(abs(rls)) * rls
else:
w = matrix(0.0, (m,1))
z0 = matrix([.5*(1+w), .5*(1-w)])
dims = {'l': 2*m, 'q': [], 's': []}
sol = solvers.conelp(c, Fi, h, dims, kktsolver = Fkkt,
primalstart={'x': x0, 's': s0}, dualstart={'z': z0})
return sol['x'][:n]