nikcleju@37
|
1 # -*- coding: utf-8 -*-
|
nikcleju@37
|
2 """
|
nikcleju@37
|
3 Created on Thu Nov 17 15:47:36 2011
|
nikcleju@37
|
4
|
nikcleju@37
|
5 Solve l1 minimization with quadratic AND equality constraints
|
nikcleju@37
|
6
|
nikcleju@37
|
7 @author: ncleju
|
nikcleju@37
|
8 """
|
nikcleju@37
|
9
|
nikcleju@37
|
10
|
nikcleju@37
|
11 import numpy as np
|
nikcleju@37
|
12 import scipy.linalg
|
nikcleju@37
|
13 import math
|
nikcleju@37
|
14
|
nikcleju@37
|
15 class l1qecInputValueError(Exception):
|
nikcleju@37
|
16 pass
|
nikcleju@37
|
17
|
nikcleju@37
|
18 # This is not normally used, so it is not tested, probably doesn't work
|
nikcleju@37
|
19 def cgsolve(A, b, tol, maxiter, verbose=1):
|
nikcleju@37
|
20 raise Exception('Shouldn\'t run cgsolve(), as this is absolutely not tested. Comment this if you really want to proceed.')
|
nikcleju@37
|
21
|
nikcleju@37
|
22
|
nikcleju@37
|
23 #if (nargin < 5), verbose = 1; end
|
nikcleju@37
|
24 # Optional argument
|
nikcleju@37
|
25
|
nikcleju@37
|
26 #implicit = isa(A,'function_handle');
|
nikcleju@37
|
27 if hasattr(A, '__call__'):
|
nikcleju@37
|
28 implicit = True
|
nikcleju@37
|
29 else:
|
nikcleju@37
|
30 implicit = False
|
nikcleju@37
|
31
|
nikcleju@37
|
32 x = np.zeros(b.size)
|
nikcleju@37
|
33 r = b.copy()
|
nikcleju@37
|
34 d = r.copy()
|
nikcleju@37
|
35 delta = np.vdot(r,r)
|
nikcleju@37
|
36 delta0 = np.vdot(b,b)
|
nikcleju@37
|
37 numiter = 0
|
nikcleju@37
|
38 bestx = x.copy()
|
nikcleju@37
|
39 bestres = math.sqrt(delta/delta0)
|
nikcleju@37
|
40 while (numiter < maxiter) and (delta > tol**2*delta0):
|
nikcleju@37
|
41
|
nikcleju@37
|
42 # q = A*d
|
nikcleju@37
|
43 #if (implicit), q = A(d); else q = A*d; end
|
nikcleju@37
|
44 if implicit:
|
nikcleju@37
|
45 q = A(d)
|
nikcleju@37
|
46 else:
|
nikcleju@37
|
47 q = np.dot(A,d)
|
nikcleju@37
|
48
|
nikcleju@37
|
49 alpha = delta/np.vdot(d,q)
|
nikcleju@37
|
50 x = x + alpha*d
|
nikcleju@37
|
51
|
nikcleju@37
|
52 if divmod(numiter+1,50)[1] == 0:
|
nikcleju@37
|
53 # r = b - Aux*x
|
nikcleju@37
|
54 #if (implicit), r = b - A(x); else r = b - A*x; end
|
nikcleju@37
|
55 if implicit:
|
nikcleju@37
|
56 r = b - A(x)
|
nikcleju@37
|
57 else:
|
nikcleju@37
|
58 r = b - np.dot(A,x)
|
nikcleju@37
|
59 else:
|
nikcleju@37
|
60 r = r - alpha*q
|
nikcleju@37
|
61 #end
|
nikcleju@37
|
62
|
nikcleju@37
|
63 deltaold = delta;
|
nikcleju@37
|
64 delta = np.vdot(r,r)
|
nikcleju@37
|
65 beta = delta/deltaold;
|
nikcleju@37
|
66 d = r + beta*d
|
nikcleju@37
|
67 numiter = numiter + 1
|
nikcleju@37
|
68 if (math.sqrt(delta/delta0) < bestres):
|
nikcleju@37
|
69 bestx = x.copy()
|
nikcleju@37
|
70 bestres = math.sqrt(delta/delta0)
|
nikcleju@37
|
71 #end
|
nikcleju@37
|
72
|
nikcleju@37
|
73 if ((verbose) and (divmod(numiter,verbose)[1]==0)):
|
nikcleju@37
|
74 #disp(sprintf('cg: Iter = #d, Best residual = #8.3e, Current residual = #8.3e', ...
|
nikcleju@37
|
75 # numiter, bestres, sqrt(delta/delta0)));
|
nikcleju@37
|
76 print 'cg: Iter = ',numiter,', Best residual = ',bestres,', Current residual = ',math.sqrt(delta/delta0)
|
nikcleju@37
|
77 #end
|
nikcleju@37
|
78
|
nikcleju@37
|
79 #end
|
nikcleju@37
|
80
|
nikcleju@37
|
81 if (verbose):
|
nikcleju@37
|
82 #disp(sprintf('cg: Iterations = #d, best residual = #14.8e', numiter, bestres));
|
nikcleju@37
|
83 print 'cg: Iterations = ',numiter,', best residual = ',bestres
|
nikcleju@37
|
84 #end
|
nikcleju@37
|
85 x = bestx.copy()
|
nikcleju@37
|
86 res = bestres
|
nikcleju@37
|
87 iter = numiter
|
nikcleju@37
|
88
|
nikcleju@37
|
89 return x,res,iter
|
nikcleju@37
|
90
|
nikcleju@37
|
91
|
nikcleju@37
|
92
|
nikcleju@37
|
93 def l1qec_newton(x0, u0, A, At, b, epsilon, Aexact, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter, verbose=False):
|
nikcleju@37
|
94
|
nikcleju@37
|
95 # check if the matrix A is implicit or explicit
|
nikcleju@37
|
96 #largescale = isa(A,'function_handle');
|
nikcleju@37
|
97 if hasattr(A, '__call__'):
|
nikcleju@37
|
98 largescale = True
|
nikcleju@37
|
99 else:
|
nikcleju@37
|
100 largescale = False
|
nikcleju@37
|
101
|
nikcleju@37
|
102 # line search parameters
|
nikcleju@37
|
103 alpha = 0.01
|
nikcleju@37
|
104 beta = 0.5
|
nikcleju@37
|
105
|
nikcleju@37
|
106 #if (~largescale), AtA = A'*A; end
|
nikcleju@37
|
107 if not largescale:
|
nikcleju@37
|
108 AtA = np.dot(A.T,A)
|
nikcleju@37
|
109
|
nikcleju@37
|
110 # initial point
|
nikcleju@37
|
111 x = x0.copy()
|
nikcleju@37
|
112 u = u0.copy()
|
nikcleju@37
|
113 #if (largescale), r = A(x) - b; else r = A*x - b; end
|
nikcleju@37
|
114 if largescale:
|
nikcleju@37
|
115 r = A(x) - b
|
nikcleju@37
|
116 else:
|
nikcleju@37
|
117 r = np.dot(A,x) - b
|
nikcleju@37
|
118
|
nikcleju@37
|
119 fu1 = x - u
|
nikcleju@37
|
120 fu2 = -x - u
|
nikcleju@37
|
121 fe = 1.0/2*(np.vdot(r,r) - epsilon**2)
|
nikcleju@37
|
122 f = u.sum() - (1.0/tau)*(np.log(-fu1).sum() + np.log(-fu2).sum() + math.log(-fe))
|
nikcleju@37
|
123
|
nikcleju@37
|
124 niter = 0
|
nikcleju@37
|
125 done = 0
|
nikcleju@37
|
126 while not done:
|
nikcleju@37
|
127
|
nikcleju@37
|
128 #if (largescale), atr = At(r); else atr = A'*r; end
|
nikcleju@37
|
129 if largescale:
|
nikcleju@37
|
130 atr = At(r)
|
nikcleju@37
|
131 else:
|
nikcleju@37
|
132 atr = np.dot(A.T,r)
|
nikcleju@37
|
133
|
nikcleju@37
|
134 #ntgz = 1./fu1 - 1./fu2 + 1/fe*atr;
|
nikcleju@37
|
135 ntgz = 1.0/fu1 - 1.0/fu2 + 1.0/fe*atr
|
nikcleju@37
|
136 #ntgu = -tau - 1./fu1 - 1./fu2;
|
nikcleju@37
|
137 ntgu = -tau - 1.0/fu1 - 1.0/fu2
|
nikcleju@37
|
138 #gradf = -(1/tau)*[ntgz; ntgu];
|
nikcleju@37
|
139 gradf = -(1.0/tau)*np.concatenate((ntgz, ntgu),0)
|
nikcleju@37
|
140
|
nikcleju@37
|
141 #sig11 = 1./fu1.^2 + 1./fu2.^2;
|
nikcleju@37
|
142 sig11 = 1.0/(fu1**2) + 1.0/(fu2**2)
|
nikcleju@37
|
143 #sig12 = -1./fu1.^2 + 1./fu2.^2;
|
nikcleju@37
|
144 sig12 = -1.0/(fu1**2) + 1.0/(fu2**2)
|
nikcleju@37
|
145 #sigx = sig11 - sig12.^2./sig11;
|
nikcleju@37
|
146 sigx = sig11 - (sig12**2)/sig11
|
nikcleju@37
|
147
|
nikcleju@37
|
148 #w1p = ntgz - sig12./sig11.*ntgu;
|
nikcleju@37
|
149 w1p = ntgz - sig12/sig11*ntgu
|
nikcleju@37
|
150 if largescale:
|
nikcleju@37
|
151 #h11pfun = @(z) sigx.*z - (1/fe)*At(A(z)) + 1/fe^2*(atr'*z)*atr;
|
nikcleju@37
|
152 h11pfun = lambda z: sigx*z - (1.0/fe)*At(A(z)) + 1.0/(fe**2)*np.dot(np.dot(atr.T,z),atr)
|
nikcleju@37
|
153 dx,cgres,cgiter = cgsolve(h11pfun, w1p, cgtol, cgmaxiter, 0)
|
nikcleju@37
|
154 if (cgres > 1.0/2):
|
nikcleju@37
|
155 if verbose:
|
nikcleju@37
|
156 print 'Cannot solve system. Returning previous iterate. (See Section 4 of notes for more information.)'
|
nikcleju@37
|
157 xp = x.copy()
|
nikcleju@37
|
158 up = u.copy()
|
nikcleju@37
|
159 return xp,up,niter
|
nikcleju@37
|
160 #end
|
nikcleju@37
|
161 Adx = A(dx)
|
nikcleju@37
|
162 else:
|
nikcleju@37
|
163 #H11p = diag(sigx) - (1/fe)*AtA + (1/fe)^2*atr*atr';
|
nikcleju@37
|
164 # Attention: atr is column vector, so atr*atr' means outer(atr,atr)
|
nikcleju@37
|
165 H11p = np.diag(sigx) - (1.0/fe)*AtA + (1.0/fe)**2*np.outer(atr,atr)
|
nikcleju@37
|
166 #opts.POSDEF = true; opts.SYM = true;
|
nikcleju@37
|
167 #[dx,hcond] = linsolve(H11p, w1p, opts);
|
nikcleju@37
|
168 #if (hcond < 1e-14)
|
nikcleju@37
|
169 # disp('Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)');
|
nikcleju@37
|
170 # xp = x; up = u;
|
nikcleju@37
|
171 # return
|
nikcleju@37
|
172 #end
|
nikcleju@37
|
173
|
nikcleju@37
|
174 # Nic says: from tveq_newton.m
|
nikcleju@37
|
175 K = Aexact.shape[0]
|
nikcleju@37
|
176 afac = (np.diag(H11p)).max()
|
nikcleju@37
|
177 #Hp = [H11p afac*A'; afac*A zeros(K)])
|
nikcleju@37
|
178 Hp = np.vstack(( np.hstack((H11p,afac*Aexact.T)) , np.hstack((afac*Aexact,np.zeros((K,K)))) ))
|
nikcleju@37
|
179 wp = np.concatenate((w1p , np.zeros(K)))
|
nikcleju@37
|
180 try:
|
nikcleju@37
|
181 #dx = scipy.linalg.solve(H11p, w1p, sym_pos=True)
|
nikcleju@37
|
182 #hcond = 1.0/np.linalg.cond(H11p)
|
nikcleju@37
|
183 dxv = scipy.linalg.solve(Hp, wp, sym_pos=False) # Only symmetric, not posdef
|
nikcleju@37
|
184 dx = dxv[:x0.size]
|
nikcleju@37
|
185 hcond = 1.0/np.linalg.cond(Hp)
|
nikcleju@37
|
186 except scipy.linalg.LinAlgError:
|
nikcleju@37
|
187 if verbose:
|
nikcleju@37
|
188 print 'Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)'
|
nikcleju@37
|
189 xp = x.copy()
|
nikcleju@37
|
190 up = u.copy()
|
nikcleju@37
|
191 return xp,up,niter
|
nikcleju@37
|
192 if hcond < 1e-14:
|
nikcleju@37
|
193 if verbose:
|
nikcleju@37
|
194 print 'Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)'
|
nikcleju@37
|
195 xp = x.copy()
|
nikcleju@37
|
196 up = u.copy()
|
nikcleju@37
|
197 return xp,up,niter
|
nikcleju@37
|
198
|
nikcleju@37
|
199 #Adx = A*dx;
|
nikcleju@37
|
200 Adx = np.dot(A,dx)
|
nikcleju@37
|
201 #end
|
nikcleju@37
|
202 #du = (1./sig11).*ntgu - (sig12./sig11).*dx;
|
nikcleju@37
|
203 du = (1.0/sig11)*ntgu - (sig12/sig11)*dx;
|
nikcleju@37
|
204
|
nikcleju@37
|
205 # minimum step size that stays in the interior
|
nikcleju@37
|
206 #ifu1 = find((dx-du) > 0); ifu2 = find((-dx-du) > 0);
|
nikcleju@37
|
207 ifu1 = np.nonzero((dx-du)>0)
|
nikcleju@37
|
208 ifu2 = np.nonzero((-dx-du)>0)
|
nikcleju@37
|
209 #aqe = Adx'*Adx; bqe = 2*r'*Adx; cqe = r'*r - epsilon^2;
|
nikcleju@37
|
210 aqe = np.dot(Adx.T,Adx)
|
nikcleju@37
|
211 bqe = 2*np.dot(r.T,Adx)
|
nikcleju@37
|
212 cqe = np.vdot(r,r) - epsilon**2
|
nikcleju@37
|
213 #smax = min(1,min([...
|
nikcleju@37
|
214 # -fu1(ifu1)./(dx(ifu1)-du(ifu1)); -fu2(ifu2)./(-dx(ifu2)-du(ifu2)); ...
|
nikcleju@37
|
215 # (-bqe+sqrt(bqe^2-4*aqe*cqe))/(2*aqe)
|
nikcleju@37
|
216 # ]));
|
nikcleju@37
|
217 smax = min(1,np.concatenate( (-fu1[ifu1]/(dx[ifu1]-du[ifu1]) , -fu2[ifu2]/(-dx[ifu2]-du[ifu2]) , np.array([ (-bqe + math.sqrt(bqe**2-4*aqe*cqe))/(2*aqe) ]) ) , 0).min())
|
nikcleju@37
|
218
|
nikcleju@37
|
219 s = 0.99 * smax
|
nikcleju@37
|
220
|
nikcleju@37
|
221 # backtracking line search
|
nikcleju@37
|
222 suffdec = 0
|
nikcleju@37
|
223 backiter = 0
|
nikcleju@37
|
224 while not suffdec:
|
nikcleju@37
|
225 #xp = x + s*dx; up = u + s*du; rp = r + s*Adx;
|
nikcleju@37
|
226 xp = x + s*dx
|
nikcleju@37
|
227 up = u + s*du
|
nikcleju@37
|
228 rp = r + s*Adx
|
nikcleju@37
|
229 #fu1p = xp - up; fu2p = -xp - up; fep = 1/2*(rp'*rp - epsilon^2);
|
nikcleju@37
|
230 fu1p = xp - up
|
nikcleju@37
|
231 fu2p = -xp - up
|
nikcleju@37
|
232 fep = 0.5*(np.vdot(rp,rp) - epsilon**2)
|
nikcleju@37
|
233 #fp = sum(up) - (1/tau)*(sum(log(-fu1p)) + sum(log(-fu2p)) + log(-fep));
|
nikcleju@37
|
234 fp = up.sum() - (1.0/tau)*(np.log(-fu1p).sum() + np.log(-fu2p).sum() + math.log(-fep))
|
nikcleju@37
|
235 #flin = f + alpha*s*(gradf'*[dx; du]);
|
nikcleju@37
|
236 flin = f + alpha*s*np.dot(gradf.T , np.concatenate((dx,du),0))
|
nikcleju@37
|
237 #suffdec = (fp <= flin);
|
nikcleju@37
|
238 if fp <= flin:
|
nikcleju@37
|
239 suffdec = True
|
nikcleju@37
|
240 else:
|
nikcleju@37
|
241 suffdec = False
|
nikcleju@37
|
242
|
nikcleju@37
|
243 s = beta*s
|
nikcleju@37
|
244 backiter = backiter + 1
|
nikcleju@37
|
245 if (backiter > 32):
|
nikcleju@37
|
246 if verbose:
|
nikcleju@37
|
247 print 'Stuck on backtracking line search, returning previous iterate. (See Section 4 of notes for more information.)'
|
nikcleju@37
|
248 xp = x.copy()
|
nikcleju@37
|
249 up = u.copy()
|
nikcleju@37
|
250 return xp,up,niter
|
nikcleju@37
|
251 #end
|
nikcleju@37
|
252 #end
|
nikcleju@37
|
253
|
nikcleju@37
|
254 # set up for next iteration
|
nikcleju@37
|
255 #x = xp; u = up; r = rp;
|
nikcleju@37
|
256 x = xp.copy()
|
nikcleju@37
|
257 u = up.copy()
|
nikcleju@37
|
258 r = rp.copy()
|
nikcleju@37
|
259 #fu1 = fu1p; fu2 = fu2p; fe = fep; f = fp;
|
nikcleju@37
|
260 fu1 = fu1p.copy()
|
nikcleju@37
|
261 fu2 = fu2p.copy()
|
nikcleju@37
|
262 fe = fep
|
nikcleju@37
|
263 f = fp
|
nikcleju@37
|
264
|
nikcleju@37
|
265 #lambda2 = -(gradf'*[dx; du]);
|
nikcleju@37
|
266 lambda2 = -np.dot(gradf.T , np.concatenate((dx,du),0))
|
nikcleju@37
|
267 #stepsize = s*norm([dx; du]);
|
nikcleju@37
|
268 stepsize = s * np.linalg.norm(np.concatenate((dx,du),0))
|
nikcleju@37
|
269 niter = niter + 1
|
nikcleju@37
|
270 #done = (lambda2/2 < newtontol) | (niter >= newtonmaxiter);
|
nikcleju@37
|
271 if lambda2/2.0 < newtontol or niter >= newtonmaxiter:
|
nikcleju@37
|
272 done = 1
|
nikcleju@37
|
273 else:
|
nikcleju@37
|
274 done = 0
|
nikcleju@37
|
275
|
nikcleju@37
|
276 #disp(sprintf('Newton iter = #d, Functional = #8.3f, Newton decrement = #8.3f, Stepsize = #8.3e', ...
|
nikcleju@37
|
277 if verbose:
|
nikcleju@37
|
278 print 'Newton iter = ',niter,', Functional = ',f,', Newton decrement = ',lambda2/2.0,', Stepsize = ',stepsize
|
nikcleju@37
|
279
|
nikcleju@37
|
280 if verbose:
|
nikcleju@37
|
281 if largescale:
|
nikcleju@37
|
282 print ' CG Res = ',cgres,', CG Iter = ',cgiter
|
nikcleju@37
|
283 else:
|
nikcleju@37
|
284 print ' H11p condition number = ',hcond
|
nikcleju@37
|
285 #end
|
nikcleju@37
|
286
|
nikcleju@37
|
287 #end
|
nikcleju@37
|
288 return xp,up,niter
|
nikcleju@37
|
289
|
nikcleju@37
|
290 def l1qec_logbarrier(x0, A, At, b, epsilon, Aexact, Atexact, bexact, lbtol=1e-3, mu=10, cgtol=1e-8, cgmaxiter=200, verbose=False):
|
nikcleju@37
|
291
|
nikcleju@37
|
292 # Check if epsilon > 0. If epsilon is 0, the algorithm fails. You should run the algo with equality constraint instead
|
nikcleju@37
|
293 if epsilon == 0:
|
nikcleju@37
|
294 raise l1qecInputValueError('Epsilon should be > 0!')
|
nikcleju@37
|
295
|
nikcleju@37
|
296 #largescale = isa(A,'function_handle');
|
nikcleju@37
|
297 if hasattr(A, '__call__'):
|
nikcleju@37
|
298 largescale = True
|
nikcleju@37
|
299 else:
|
nikcleju@37
|
300 largescale = False
|
nikcleju@37
|
301
|
nikcleju@37
|
302 # if (nargin < 6), lbtol = 1e-3; end
|
nikcleju@37
|
303 # if (nargin < 7), mu = 10; end
|
nikcleju@37
|
304 # if (nargin < 8), cgtol = 1e-8; end
|
nikcleju@37
|
305 # if (nargin < 9), cgmaxiter = 200; end
|
nikcleju@37
|
306 # Nic: added them as optional parameteres
|
nikcleju@37
|
307
|
nikcleju@37
|
308 newtontol = lbtol
|
nikcleju@37
|
309 newtonmaxiter = 50
|
nikcleju@37
|
310
|
nikcleju@37
|
311 #N = length(x0);
|
nikcleju@37
|
312 N = x0.size
|
nikcleju@37
|
313
|
nikcleju@37
|
314 # starting point --- make sure that it is feasible
|
nikcleju@37
|
315 if largescale:
|
nikcleju@37
|
316 if np.linalg.norm(A(x0) - b) > epsilon or np.linalg.norm( np.dot(Aexact,x0) - bexact ) > 1e-15:
|
nikcleju@37
|
317 if verbose:
|
nikcleju@37
|
318 print 'Starting point infeasible; using x0 = At*inv(AAt)*y.'
|
nikcleju@37
|
319 #AAt = @(z) A(At(z));
|
nikcleju@37
|
320 AAt = lambda z: A(At(z))
|
nikcleju@37
|
321 # TODO: implement cgsolve
|
nikcleju@37
|
322 w,cgres,cgiter = cgsolve(AAt, b, cgtol, cgmaxiter, 0)
|
nikcleju@37
|
323 if (cgres > 1.0/2):
|
nikcleju@37
|
324 if verbose:
|
nikcleju@37
|
325 print 'A*At is ill-conditioned: cannot find starting point'
|
nikcleju@37
|
326 xp = x0.copy()
|
nikcleju@37
|
327 return xp
|
nikcleju@37
|
328 #end
|
nikcleju@37
|
329 x0 = At(w)
|
nikcleju@37
|
330 #end
|
nikcleju@37
|
331 else:
|
nikcleju@37
|
332 # Nic: add test for np.dot(Aexact,x0) - bexact ) > 1e-15
|
nikcleju@37
|
333 if np.linalg.norm( np.dot(A,x0) - b ) > epsilon or np.linalg.norm( np.dot(Aexact,x0) - bexact ) > 1e-15:
|
nikcleju@37
|
334 if verbose:
|
nikcleju@37
|
335 print 'Starting point infeasible; using x0 = At*inv(AAt)*y.'
|
nikcleju@37
|
336
|
nikcleju@37
|
337 #Nic: stack A and Aexact, b and bexact, and use them instead of A and b
|
nikcleju@37
|
338 Abig = np.vstack((A,Aexact))
|
nikcleju@37
|
339 bbig = np.concatenate((b,bexact))
|
nikcleju@37
|
340 try:
|
nikcleju@37
|
341 w = scipy.linalg.solve(np.dot(Abig,Abig.T), bbig, sym_pos=True)
|
nikcleju@37
|
342 #w = np.linalg.solve(np.dot(A,A.T), b)
|
nikcleju@37
|
343 hcond = 1.0/np.linalg.cond(np.dot(Abig,Abig.T))
|
nikcleju@37
|
344 except scipy.linalg.LinAlgError:
|
nikcleju@37
|
345 if verbose:
|
nikcleju@37
|
346 print 'A*At is ill-conditioned: cannot find starting point'
|
nikcleju@37
|
347 xp = x0.copy()
|
nikcleju@37
|
348 return xp
|
nikcleju@37
|
349 if hcond < 1e-14:
|
nikcleju@37
|
350 if verbose:
|
nikcleju@37
|
351 print 'A*At is ill-conditioned: cannot find starting point'
|
nikcleju@37
|
352 xp = x0.copy()
|
nikcleju@37
|
353 return xp
|
nikcleju@37
|
354 x0 = np.dot(Abig.T, w)
|
nikcleju@37
|
355 # try:
|
nikcleju@37
|
356 # w = scipy.linalg.solve(np.dot(A,A.T), b, sym_pos=True)
|
nikcleju@37
|
357 # #w = np.linalg.solve(np.dot(A,A.T), b)
|
nikcleju@37
|
358 # hcond = 1.0/scipy.linalg.cond(np.dot(A,A.T))
|
nikcleju@37
|
359 # except scipy.linalg.LinAlgError:
|
nikcleju@37
|
360 # print 'A*At is ill-conditioned: cannot find starting point'
|
nikcleju@37
|
361 # xp = x0.copy()
|
nikcleju@37
|
362 # return xp
|
nikcleju@37
|
363 # if hcond < 1e-14:
|
nikcleju@37
|
364 # print 'A*At is ill-conditioned: cannot find starting point'
|
nikcleju@37
|
365 # xp = x0.copy()
|
nikcleju@37
|
366 # return xp
|
nikcleju@37
|
367 # #x0 = A'*w;
|
nikcleju@37
|
368 # x0 = np.dot(A.T, w)
|
nikcleju@37
|
369 #end
|
nikcleju@37
|
370 #end
|
nikcleju@37
|
371 x = x0.copy()
|
nikcleju@37
|
372 u = (0.95)*np.abs(x0) + (0.10)*np.abs(x0).max()
|
nikcleju@37
|
373
|
nikcleju@37
|
374 #disp(sprintf('Original l1 norm = #.3f, original functional = #.3f', sum(abs(x0)), sum(u)));
|
nikcleju@37
|
375 if verbose:
|
nikcleju@37
|
376 print 'Original l1 norm = ',np.abs(x0).sum(),'original functional = ',u.sum()
|
nikcleju@37
|
377
|
nikcleju@37
|
378 # choose initial value of tau so that the duality gap after the first
|
nikcleju@37
|
379 # step will be about the origial norm
|
nikcleju@37
|
380 tau = max(((2*N+1.0)/np.abs(x0).sum()), 1)
|
nikcleju@37
|
381
|
nikcleju@37
|
382 lbiter = math.ceil((math.log(2*N+1)-math.log(lbtol)-math.log(tau))/math.log(mu))
|
nikcleju@37
|
383 #disp(sprintf('Number of log barrier iterations = #d\n', lbiter));
|
nikcleju@37
|
384 if verbose:
|
nikcleju@37
|
385 print 'Number of log barrier iterations = ',lbiter
|
nikcleju@37
|
386
|
nikcleju@37
|
387 totaliter = 0
|
nikcleju@37
|
388
|
nikcleju@37
|
389 # Added by Nic, to fix some crashing
|
nikcleju@37
|
390 if lbiter == 0:
|
nikcleju@37
|
391 xp = np.zeros(x0.size)
|
nikcleju@37
|
392 #end
|
nikcleju@37
|
393
|
nikcleju@37
|
394 #for ii = 1:lbiter
|
nikcleju@37
|
395 for ii in np.arange(lbiter):
|
nikcleju@37
|
396
|
nikcleju@37
|
397 xp,up,ntiter = l1qec_newton(x, u, A, At, b, epsilon, Aexact, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter)
|
nikcleju@37
|
398 totaliter = totaliter + ntiter
|
nikcleju@37
|
399
|
nikcleju@37
|
400 #disp(sprintf('\nLog barrier iter = #d, l1 = #.3f, functional = #8.3f, tau = #8.3e, total newton iter = #d\n', ...
|
nikcleju@37
|
401 # ii, sum(abs(xp)), sum(up), tau, totaliter));
|
nikcleju@37
|
402 if verbose:
|
nikcleju@37
|
403 print 'Log barrier iter = ',ii,', l1 = ',np.abs(xp).sum(),', functional = ',up.sum(),', tau = ',tau,', total newton iter = ',totaliter
|
nikcleju@37
|
404 x = xp.copy()
|
nikcleju@37
|
405 u = up.copy()
|
nikcleju@37
|
406
|
nikcleju@37
|
407 tau = mu*tau
|
nikcleju@37
|
408
|
nikcleju@37
|
409 #end
|
nikcleju@37
|
410 return xp
|
nikcleju@37
|
411
|