comparison pyCSalgos/BP/l1qc.py @ 2:735a0e24575c

Organized folders: added tests, apps, matlab, docs folders. Added __init__.py files
author nikcleju
date Fri, 21 Oct 2011 13:53:49 +0000
parents
children 537f7798e186
comparison
equal deleted inserted replaced
1:2a2abf5092f8 2:735a0e24575c
1
2 import numpy as np
3 import scipy.linalg
4 import math
5
6
7 #function [x, res, iter] = cgsolve(A, b, tol, maxiter, verbose)
8 def cgsolve(A, b, tol, maxiter, verbose=1):
9 # Solve a symmetric positive definite system Ax = b via conjugate gradients.
10 #
11 # Usage: [x, res, iter] = cgsolve(A, b, tol, maxiter, verbose)
12 #
13 # A - Either an NxN matrix, or a function handle.
14 #
15 # b - N vector
16 #
17 # tol - Desired precision. Algorithm terminates when
18 # norm(Ax-b)/norm(b) < tol .
19 #
20 # maxiter - Maximum number of iterations.
21 #
22 # verbose - If 0, do not print out progress messages.
23 # If and integer greater than 0, print out progress every 'verbose' iters.
24 #
25 # Written by: Justin Romberg, Caltech
26 # Email: jrom@acm.caltech.edu
27 # Created: October 2005
28 #
29
30 #---------------------
31 # Original Matab code:
32 #
33 #if (nargin < 5), verbose = 1; end
34 #
35 #implicit = isa(A,'function_handle');
36 #
37 #x = zeros(length(b),1);
38 #r = b;
39 #d = r;
40 #delta = r'*r;
41 #delta0 = b'*b;
42 #numiter = 0;
43 #bestx = x;
44 #bestres = sqrt(delta/delta0);
45 #while ((numiter < maxiter) && (delta > tol^2*delta0))
46 #
47 # # q = A*d
48 # if (implicit), q = A(d); else q = A*d; end
49 #
50 # alpha = delta/(d'*q);
51 # x = x + alpha*d;
52 #
53 # if (mod(numiter+1,50) == 0)
54 # # r = b - Aux*x
55 # if (implicit), r = b - A(x); else r = b - A*x; end
56 # else
57 # r = r - alpha*q;
58 # end
59 #
60 # deltaold = delta;
61 # delta = r'*r;
62 # beta = delta/deltaold;
63 # d = r + beta*d;
64 # numiter = numiter + 1;
65 # if (sqrt(delta/delta0) < bestres)
66 # bestx = x;
67 # bestres = sqrt(delta/delta0);
68 # end
69 #
70 # if ((verbose) && (mod(numiter,verbose)==0))
71 # disp(sprintf('cg: Iter = #d, Best residual = #8.3e, Current residual = #8.3e', ...
72 # numiter, bestres, sqrt(delta/delta0)));
73 # end
74 #
75 #end
76 #
77 #if (verbose)
78 # disp(sprintf('cg: Iterations = #d, best residual = #14.8e', numiter, bestres));
79 #end
80 #x = bestx;
81 #res = bestres;
82 #iter = numiter;
83
84 # End of original Matab code
85 #----------------------------
86
87 #if (nargin < 5), verbose = 1; end
88 # Optional argument
89
90 #implicit = isa(A,'function_handle');
91 if hasattr(A, '__call__'):
92 implicit = True
93 else:
94 implicit = False
95
96 x = np.zeros(b.size)
97 r = b.copy()
98 d = r.copy()
99 delta = np.vdot(r,r)
100 delta0 = np.vdot(b,b)
101 numiter = 0
102 bestx = x.copy()
103 bestres = math.sqrt(delta/delta0)
104 while (numiter < maxiter) and (delta > tol**2*delta0):
105
106 # q = A*d
107 #if (implicit), q = A(d); else q = A*d; end
108 if implicit:
109 q = A(d)
110 else:
111 q = np.dot(A,d)
112
113 alpha = delta/np.vdot(d,q)
114 x = x + alpha*d
115
116 if divmod(numiter+1,50)[1] == 0:
117 # r = b - Aux*x
118 #if (implicit), r = b - A(x); else r = b - A*x; end
119 if implicit:
120 r = b - A(x)
121 else:
122 r = b - np.dot(A,x)
123 else:
124 r = r - alpha*q
125 #end
126
127 deltaold = delta;
128 delta = np.vdot(r,r)
129 beta = delta/deltaold;
130 d = r + beta*d
131 numiter = numiter + 1
132 if (math.sqrt(delta/delta0) < bestres):
133 bestx = x.copy()
134 bestres = math.sqrt(delta/delta0)
135 #end
136
137 if ((verbose) and (divmod(numiter,verbose)[1]==0)):
138 #disp(sprintf('cg: Iter = #d, Best residual = #8.3e, Current residual = #8.3e', ...
139 # numiter, bestres, sqrt(delta/delta0)));
140 print 'cg: Iter = ',numiter,', Best residual = ',bestres,', Current residual = ',math.sqrt(delta/delta0)
141 #end
142
143 #end
144
145 if (verbose):
146 #disp(sprintf('cg: Iterations = #d, best residual = #14.8e', numiter, bestres));
147 print 'cg: Iterations = ',numiter,', best residual = ',bestres
148 #end
149 x = bestx.copy()
150 res = bestres
151 iter = numiter
152
153 return x,res,iter
154
155
156
157 #function [xp, up, niter] = l1qc_newton(x0, u0, A, At, b, epsilon, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter)
158 def l1qc_newton(x0, u0, A, At, b, epsilon, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter):
159 # Newton algorithm for log-barrier subproblems for l1 minimization
160 # with quadratic constraints.
161 #
162 # Usage:
163 # [xp,up,niter] = l1qc_newton(x0, u0, A, At, b, epsilon, tau,
164 # newtontol, newtonmaxiter, cgtol, cgmaxiter)
165 #
166 # x0,u0 - starting points
167 #
168 # A - Either a handle to a function that takes a N vector and returns a K
169 # vector , or a KxN matrix. If A is a function handle, the algorithm
170 # operates in "largescale" mode, solving the Newton systems via the
171 # Conjugate Gradients algorithm.
172 #
173 # At - Handle to a function that takes a K vector and returns an N vector.
174 # If A is a KxN matrix, At is ignored.
175 #
176 # b - Kx1 vector of observations.
177 #
178 # epsilon - scalar, constraint relaxation parameter
179 #
180 # tau - Log barrier parameter.
181 #
182 # newtontol - Terminate when the Newton decrement is <= newtontol.
183 # Default = 1e-3.
184 #
185 # newtonmaxiter - Maximum number of iterations.
186 # Default = 50.
187 #
188 # cgtol - Tolerance for Conjugate Gradients; ignored if A is a matrix.
189 # Default = 1e-8.
190 #
191 # cgmaxiter - Maximum number of iterations for Conjugate Gradients; ignored
192 # if A is a matrix.
193 # Default = 200.
194 #
195 # Written by: Justin Romberg, Caltech
196 # Email: jrom@acm.caltech.edu
197 # Created: October 2005
198 #
199
200 #---------------------
201 # Original Matab code:
202
203 ## check if the matrix A is implicit or explicit
204 #largescale = isa(A,'function_handle');
205 #
206 ## line search parameters
207 #alpha = 0.01;
208 #beta = 0.5;
209 #
210 #if (~largescale), AtA = A'*A; end
211 #
212 ## initial point
213 #x = x0;
214 #u = u0;
215 #if (largescale), r = A(x) - b; else r = A*x - b; end
216 #fu1 = x - u;
217 #fu2 = -x - u;
218 #fe = 1/2*(r'*r - epsilon^2);
219 #f = sum(u) - (1/tau)*(sum(log(-fu1)) + sum(log(-fu2)) + log(-fe));
220 #
221 #niter = 0;
222 #done = 0;
223 #while (~done)
224 #
225 # if (largescale), atr = At(r); else atr = A'*r; end
226 #
227 # ntgz = 1./fu1 - 1./fu2 + 1/fe*atr;
228 # ntgu = -tau - 1./fu1 - 1./fu2;
229 # gradf = -(1/tau)*[ntgz; ntgu];
230 #
231 # sig11 = 1./fu1.^2 + 1./fu2.^2;
232 # sig12 = -1./fu1.^2 + 1./fu2.^2;
233 # sigx = sig11 - sig12.^2./sig11;
234 #
235 # w1p = ntgz - sig12./sig11.*ntgu;
236 # if (largescale)
237 # h11pfun = @(z) sigx.*z - (1/fe)*At(A(z)) + 1/fe^2*(atr'*z)*atr;
238 # [dx, cgres, cgiter] = cgsolve(h11pfun, w1p, cgtol, cgmaxiter, 0);
239 # if (cgres > 1/2)
240 # disp('Cannot solve system. Returning previous iterate. (See Section 4 of notes for more information.)');
241 # xp = x; up = u;
242 # return
243 # end
244 # Adx = A(dx);
245 # else
246 # H11p = diag(sigx) - (1/fe)*AtA + (1/fe)^2*atr*atr';
247 # opts.POSDEF = true; opts.SYM = true;
248 # [dx,hcond] = linsolve(H11p, w1p, opts);
249 # if (hcond < 1e-14)
250 # disp('Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)');
251 # xp = x; up = u;
252 # return
253 # end
254 # Adx = A*dx;
255 # end
256 # du = (1./sig11).*ntgu - (sig12./sig11).*dx;
257 #
258 # # minimum step size that stays in the interior
259 # ifu1 = find((dx-du) > 0); ifu2 = find((-dx-du) > 0);
260 # aqe = Adx'*Adx; bqe = 2*r'*Adx; cqe = r'*r - epsilon^2;
261 # smax = min(1,min([...
262 # -fu1(ifu1)./(dx(ifu1)-du(ifu1)); -fu2(ifu2)./(-dx(ifu2)-du(ifu2)); ...
263 # (-bqe+sqrt(bqe^2-4*aqe*cqe))/(2*aqe)
264 # ]));
265 # s = (0.99)*smax;
266 #
267 # # backtracking line search
268 # suffdec = 0;
269 # backiter = 0;
270 # while (~suffdec)
271 # xp = x + s*dx; up = u + s*du; rp = r + s*Adx;
272 # fu1p = xp - up; fu2p = -xp - up; fep = 1/2*(rp'*rp - epsilon^2);
273 # fp = sum(up) - (1/tau)*(sum(log(-fu1p)) + sum(log(-fu2p)) + log(-fep));
274 # flin = f + alpha*s*(gradf'*[dx; du]);
275 # suffdec = (fp <= flin);
276 # s = beta*s;
277 # backiter = backiter + 1;
278 # if (backiter > 32)
279 # disp('Stuck on backtracking line search, returning previous iterate. (See Section 4 of notes for more information.)');
280 # xp = x; up = u;
281 # return
282 # end
283 # end
284 #
285 # # set up for next iteration
286 # x = xp; u = up; r = rp;
287 # fu1 = fu1p; fu2 = fu2p; fe = fep; f = fp;
288 #
289 # lambda2 = -(gradf'*[dx; du]);
290 # stepsize = s*norm([dx; du]);
291 # niter = niter + 1;
292 # done = (lambda2/2 < newtontol) | (niter >= newtonmaxiter);
293 #
294 # disp(sprintf('Newton iter = #d, Functional = #8.3f, Newton decrement = #8.3f, Stepsize = #8.3e', ...
295 # niter, f, lambda2/2, stepsize));
296 # if (largescale)
297 # disp(sprintf(' CG Res = #8.3e, CG Iter = #d', cgres, cgiter));
298 # else
299 # disp(sprintf(' H11p condition number = #8.3e', hcond));
300 # end
301 #
302 #end
303
304 # End of original Matab code
305 #----------------------------
306
307 # check if the matrix A is implicit or explicit
308 #largescale = isa(A,'function_handle');
309 if hasattr(A, '__call__'):
310 largescale = True
311 else:
312 largescale = False
313
314 # line search parameters
315 alpha = 0.01
316 beta = 0.5
317
318 #if (~largescale), AtA = A'*A; end
319 if not largescale:
320 AtA = np.dot(A.T,A)
321
322 # initial point
323 x = x0.copy()
324 u = u0.copy()
325 #if (largescale), r = A(x) - b; else r = A*x - b; end
326 if largescale:
327 r = A(x) - b
328 else:
329 r = np.dot(A,x) - b
330
331 fu1 = x - u
332 fu2 = -x - u
333 fe = 1/2*(np.vdot(r,r) - epsilon**2)
334 f = u.sum() - (1/tau)*(np.log(-fu1).sum() + np.log(-fu2).sum() + math.log(-fe))
335
336 niter = 0
337 done = 0
338 while not done:
339
340 #if (largescale), atr = At(r); else atr = A'*r; end
341 if largescale:
342 atr = At(r)
343 else:
344 atr = np.dot(A.T,r)
345
346 #ntgz = 1./fu1 - 1./fu2 + 1/fe*atr;
347 ntgz = 1.0/fu1 - 1.0/fu2 + 1.0/fe*atr
348 #ntgu = -tau - 1./fu1 - 1./fu2;
349 ntgu = -tau - 1.0/fu1 - 1.0/fu2
350 #gradf = -(1/tau)*[ntgz; ntgu];
351 gradf = -(1.0/tau)*np.concatenate((ntgz, ntgu),0)
352
353 #sig11 = 1./fu1.^2 + 1./fu2.^2;
354 sig11 = 1.0/(fu1**2) + 1.0/(fu2**2)
355 #sig12 = -1./fu1.^2 + 1./fu2.^2;
356 sig12 = -1.0/(fu1**2) + 1.0/(fu2**2)
357 #sigx = sig11 - sig12.^2./sig11;
358 sigx = sig11 - (sig12**2)/sig11
359
360 #w1p = ntgz - sig12./sig11.*ntgu;
361 w1p = ntgz - sig12/sig11*ntgu
362 if largescale:
363 #h11pfun = @(z) sigx.*z - (1/fe)*At(A(z)) + 1/fe^2*(atr'*z)*atr;
364 h11pfun = lambda z: sigx*z - (1.0/fe)*At(A(z)) + 1.0/(fe**2)*np.dot(np.dot(atr.T,z),atr)
365 dx,cgres,cgiter = cgsolve(h11pfun, w1p, cgtol, cgmaxiter, 0)
366 if (cgres > 1/2):
367 print 'Cannot solve system. Returning previous iterate. (See Section 4 of notes for more information.)'
368 xp = x.copy()
369 up = u.copy()
370 return xp,up,niter
371 #end
372 Adx = A(dx)
373 else:
374 #H11p = diag(sigx) - (1/fe)*AtA + (1/fe)^2*atr*atr';
375 H11p = np.diag(sigx) - (1/fe)*AtA + (1/fe)**2*np.dot(atr,atr.T)
376 #opts.POSDEF = true; opts.SYM = true;
377 #[dx,hcond] = linsolve(H11p, w1p, opts);
378 #if (hcond < 1e-14)
379 # disp('Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)');
380 # xp = x; up = u;
381 # return
382 #end
383 try:
384 dx = scipy.linalg.solve(H11p, w1p, sym_pos=True)
385 hcond = 1.0/scipy.linalg.cond(H11p)
386 except scipy.linalg.LinAlgError:
387 print 'Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)'
388 xp = x.copy()
389 up = u.copy()
390 return xp,up,niter
391 if hcond < 1e-14:
392 print 'Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)'
393 xp = x.copy()
394 up = u.copy()
395 return xp,up,niter
396
397 #Adx = A*dx;
398 Adx = np.dot(A,dx)
399 #end
400 #du = (1./sig11).*ntgu - (sig12./sig11).*dx;
401 du = (1.0/sig11)*ntgu - (sig12/sig11)*dx;
402
403 # minimum step size that stays in the interior
404 #ifu1 = find((dx-du) > 0); ifu2 = find((-dx-du) > 0);
405 ifu1 = np.nonzero((dx-du)>0)
406 ifu2 = np.nonzero((-dx-du)>0)
407 #aqe = Adx'*Adx; bqe = 2*r'*Adx; cqe = r'*r - epsilon^2;
408 aqe = np.dot(Adx.T,Adx)
409 bqe = 2*np.dot(r.T,Adx)
410 cqe = np.vdot(r,r) - epsilon**2
411 #smax = min(1,min([...
412 # -fu1(ifu1)./(dx(ifu1)-du(ifu1)); -fu2(ifu2)./(-dx(ifu2)-du(ifu2)); ...
413 # (-bqe+sqrt(bqe^2-4*aqe*cqe))/(2*aqe)
414 # ]));
415 smax = min(1,np.concatenate((-fu1[ifu1]/(dx[ifu1]-du[ifu1]) , -fu2[ifu2]/(-dx[ifu2]-du[ifu2]) , (-bqe + math.sqrt(bqe**2-4*aqe*cqe))/(2*aqe)),0).min())
416
417 s = (0.99)*smax
418
419 # backtracking line search
420 suffdec = 0
421 backiter = 0
422 while not suffdec:
423 #xp = x + s*dx; up = u + s*du; rp = r + s*Adx;
424 xp = x + s*dx
425 up = u + s*du
426 rp = r + s*Adx
427 #fu1p = xp - up; fu2p = -xp - up; fep = 1/2*(rp'*rp - epsilon^2);
428 fu1p = xp - up
429 fu2p = -xp - up
430 fep = 0.5*(np.vdot(r,r) - epsilon**2)
431 #fp = sum(up) - (1/tau)*(sum(log(-fu1p)) + sum(log(-fu2p)) + log(-fep));
432 fp = up.sum() - (1.0/tau)*(np.log(-fu1p).sum() + np.log(-fu2p).sum() + log(-fep))
433 #flin = f + alpha*s*(gradf'*[dx; du]);
434 flin = f + alpha*s*np.dot(gradf.T , np.concatenate((dx,du),0))
435 #suffdec = (fp <= flin);
436 if fp <= flin:
437 suffdec = True
438 else:
439 suffdec = False
440
441 s = beta*s
442 backiter = backiter + 1
443 if (backiter > 32):
444 print 'Stuck on backtracking line search, returning previous iterate. (See Section 4 of notes for more information.)'
445 xp = x.copy()
446 up = u.copy()
447 return xp,up,niter
448 #end
449 #end
450
451 # set up for next iteration
452 #x = xp; u = up; r = rp;
453 x = xp.copy()
454 u = up.copy()
455 r = rp.copy()
456 #fu1 = fu1p; fu2 = fu2p; fe = fep; f = fp;
457 fu1 = fu1p.copy()
458 fu2 = fu2p.copy()
459 fe = fep
460 f = fp
461
462 #lambda2 = -(gradf'*[dx; du]);
463 lambda2 = -np.dot(gradf , np.concatenate((dx,du),0))
464 #stepsize = s*norm([dx; du]);
465 stepsize = s * np.linalg.norm(np.concatenate((dx,du),0))
466 niter = niter + 1
467 #done = (lambda2/2 < newtontol) | (niter >= newtonmaxiter);
468 if lambda2/2.0 < newtontol or niter >= newtonmaxiter:
469 done = 1
470 else:
471 done = 0
472
473 #disp(sprintf('Newton iter = #d, Functional = #8.3f, Newton decrement = #8.3f, Stepsize = #8.3e', ...
474 print 'Newton iter = ',niter,', Functional = ',f,', Newton decrement = ',lambda2/2.0,', Stepsize = ',stepsize
475
476 if largescale:
477 print ' CG Res = ',cgres,', CG Iter = ',cgiter
478 else:
479 print ' H11p condition number = ',hcond
480 #end
481
482 #end
483 return xp,up,niter
484
485 #function xp = l1qc_logbarrier(x0, A, At, b, epsilon, lbtol, mu, cgtol, cgmaxiter)
486 def l1qc_logbarrier(x0, A, At, b, epsilon, lbtol=1e-3, mu=10, cgtol=1e-8, cgmaxiter=200):
487 # Solve quadratically constrained l1 minimization:
488 # min ||x||_1 s.t. ||Ax - b||_2 <= \epsilon
489 #
490 # Reformulate as the second-order cone program
491 # min_{x,u} sum(u) s.t. x - u <= 0,
492 # -x - u <= 0,
493 # 1/2(||Ax-b||^2 - \epsilon^2) <= 0
494 # and use a log barrier algorithm.
495 #
496 # Usage: xp = l1qc_logbarrier(x0, A, At, b, epsilon, lbtol, mu, cgtol, cgmaxiter)
497 #
498 # x0 - Nx1 vector, initial point.
499 #
500 # A - Either a handle to a function that takes a N vector and returns a K
501 # vector , or a KxN matrix. If A is a function handle, the algorithm
502 # operates in "largescale" mode, solving the Newton systems via the
503 # Conjugate Gradients algorithm.
504 #
505 # At - Handle to a function that takes a K vector and returns an N vector.
506 # If A is a KxN matrix, At is ignored.
507 #
508 # b - Kx1 vector of observations.
509 #
510 # epsilon - scalar, constraint relaxation parameter
511 #
512 # lbtol - The log barrier algorithm terminates when the duality gap <= lbtol.
513 # Also, the number of log barrier iterations is completely
514 # determined by lbtol.
515 # Default = 1e-3.
516 #
517 # mu - Factor by which to increase the barrier constant at each iteration.
518 # Default = 10.
519 #
520 # cgtol - Tolerance for Conjugate Gradients; ignored if A is a matrix.
521 # Default = 1e-8.
522 #
523 # cgmaxiter - Maximum number of iterations for Conjugate Gradients; ignored
524 # if A is a matrix.
525 # Default = 200.
526 #
527 # Written by: Justin Romberg, Caltech
528 # Email: jrom@acm.caltech.edu
529 # Created: October 2005
530 #
531
532 #---------------------
533 # Original Matab code:
534
535 #largescale = isa(A,'function_handle');
536 #
537 #if (nargin < 6), lbtol = 1e-3; end
538 #if (nargin < 7), mu = 10; end
539 #if (nargin < 8), cgtol = 1e-8; end
540 #if (nargin < 9), cgmaxiter = 200; end
541 #
542 #newtontol = lbtol;
543 #newtonmaxiter = 50;
544 #
545 #N = length(x0);
546 #
547 ## starting point --- make sure that it is feasible
548 #if (largescale)
549 # if (norm(A(x0)-b) > epsilon)
550 # disp('Starting point infeasible; using x0 = At*inv(AAt)*y.');
551 # AAt = @(z) A(At(z));
552 # w = cgsolve(AAt, b, cgtol, cgmaxiter, 0);
553 # if (cgres > 1/2)
554 # disp('A*At is ill-conditioned: cannot find starting point');
555 # xp = x0;
556 # return;
557 # end
558 # x0 = At(w);
559 # end
560 #else
561 # if (norm(A*x0-b) > epsilon)
562 # disp('Starting point infeasible; using x0 = At*inv(AAt)*y.');
563 # opts.POSDEF = true; opts.SYM = true;
564 # [w, hcond] = linsolve(A*A', b, opts);
565 # if (hcond < 1e-14)
566 # disp('A*At is ill-conditioned: cannot find starting point');
567 # xp = x0;
568 # return;
569 # end
570 # x0 = A'*w;
571 # end
572 #end
573 #x = x0;
574 #u = (0.95)*abs(x0) + (0.10)*max(abs(x0));
575 #
576 #disp(sprintf('Original l1 norm = #.3f, original functional = #.3f', sum(abs(x0)), sum(u)));
577 #
578 ## choose initial value of tau so that the duality gap after the first
579 ## step will be about the origial norm
580 #tau = max((2*N+1)/sum(abs(x0)), 1);
581 #
582 #lbiter = ceil((log(2*N+1)-log(lbtol)-log(tau))/log(mu));
583 #disp(sprintf('Number of log barrier iterations = #d\n', lbiter));
584 #
585 #totaliter = 0;
586 #
587 ## Added by Nic
588 #if lbiter == 0
589 # xp = zeros(size(x0));
590 #end
591 #
592 #for ii = 1:lbiter
593 #
594 # [xp, up, ntiter] = l1qc_newton(x, u, A, At, b, epsilon, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter);
595 # totaliter = totaliter + ntiter;
596 #
597 # disp(sprintf('\nLog barrier iter = #d, l1 = #.3f, functional = #8.3f, tau = #8.3e, total newton iter = #d\n', ...
598 # ii, sum(abs(xp)), sum(up), tau, totaliter));
599 #
600 # x = xp;
601 # u = up;
602 #
603 # tau = mu*tau;
604 #
605 #end
606 #
607 # End of original Matab code
608 #----------------------------
609
610 #largescale = isa(A,'function_handle');
611 if hasattr(A, '__call__'):
612 largescale = True
613 else:
614 largescale = False
615
616 # if (nargin < 6), lbtol = 1e-3; end
617 # if (nargin < 7), mu = 10; end
618 # if (nargin < 8), cgtol = 1e-8; end
619 # if (nargin < 9), cgmaxiter = 200; end
620 # Nic: added them as optional parameteres
621
622 newtontol = lbtol
623 newtonmaxiter = 50
624
625 #N = length(x0);
626 N = x0.size()
627
628 # starting point --- make sure that it is feasible
629 if largescale:
630 if np.linalg.norm(A(x0) - b) > epsilon:
631 print 'Starting point infeasible; using x0 = At*inv(AAt)*y.'
632 #AAt = @(z) A(At(z));
633 AAt = lambda z: A(At(z))
634 # TODO: implement cgsolve
635 w,cgres,cgiter = cgsolve(AAt, b, cgtol, cgmaxiter, 0)
636 if (cgres > 1/2):
637 print 'A*At is ill-conditioned: cannot find starting point'
638 xp = x0.copy()
639 return xp
640 #end
641 x0 = At(w)
642 #end
643 else:
644 if np.linalg.norm( np.dot(A,x0) - b ) > epsilon:
645 print 'Starting point infeasible; using x0 = At*inv(AAt)*y.'
646 #opts.POSDEF = true; opts.SYM = true;
647 #[w, hcond] = linsolve(A*A', b, opts);
648 #if (hcond < 1e-14)
649 # disp('A*At is ill-conditioned: cannot find starting point');
650 # xp = x0;
651 # return;
652 #end
653 try:
654 w = scipy.linalg.solve(np.dot(A,A.T), b, sym_pos=True)
655 hcond = 1.0/scipy.linalg.cond(np.dot(A,A.T))
656 except scipy.linalg.LinAlgError:
657 print 'A*At is ill-conditioned: cannot find starting point'
658 xp = x0.copy()
659 return xp
660 if hcond < 1e-14:
661 print 'A*At is ill-conditioned: cannot find starting point'
662 xp = x0.copy()
663 return xp
664 #x0 = A'*w;
665 x0 = np.dot(A.T, w)
666 #end
667 #end
668 x = x0.copy()
669 u = (0.95)*np.abs(x0) + (0.10)*np.abs(x0).max()
670
671 #disp(sprintf('Original l1 norm = #.3f, original functional = #.3f', sum(abs(x0)), sum(u)));
672 print 'Original l1 norm = ',np.abs(x0).sum(),'original functional = ',u.sum()
673
674 # choose initial value of tau so that the duality gap after the first
675 # step will be about the origial norm
676 tau = max(((2*N+1)/np.abs(x0).sum()), 1)
677
678 lbiter = math.ceil((math.log(2*N+1)-math.log(lbtol)-math.log(tau))/math.log(mu))
679 #disp(sprintf('Number of log barrier iterations = #d\n', lbiter));
680 print 'Number of log barrier iterations = ',lbiter
681
682 totaliter = 0
683
684 # Added by Nic, to fix some crashing
685 if lbiter == 0:
686 xp = np.zeros(x0.size)
687 #end
688
689 #for ii = 1:lbiter
690 for ii in np.arange(lbiter):
691
692 xp,up,ntiter = l1qc_newton(x, u, A, At, b, epsilon, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter)
693 totaliter = totaliter + ntiter
694
695 #disp(sprintf('\nLog barrier iter = #d, l1 = #.3f, functional = #8.3f, tau = #8.3e, total newton iter = #d\n', ...
696 # ii, sum(abs(xp)), sum(up), tau, totaliter));
697 print 'Log barrier iter = ',ii,', l1 = ',np.abs(xp).sum(),', functional = ',up.sum(),', tau = ',tau,', total newton iter = ',totaliter
698 x = xp.copy()
699 u = up.copy()
700
701 tau = mu*tau
702
703 #end
704 return xp
705