comparison BP/l1qc_newton.m @ 0:8346c92b698f

Initial import
author nikcleju
date Thu, 20 Oct 2011 19:36:24 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8346c92b698f
1 % l1qc_newton.m
2 %
3 % Newton algorithm for log-barrier subproblems for l1 minimization
4 % with quadratic constraints.
5 %
6 % Usage:
7 % [xp,up,niter] = l1qc_newton(x0, u0, A, At, b, epsilon, tau,
8 % newtontol, newtonmaxiter, cgtol, cgmaxiter)
9 %
10 % x0,u0 - starting points
11 %
12 % A - Either a handle to a function that takes a N vector and returns a K
13 % vector , or a KxN matrix. If A is a function handle, the algorithm
14 % operates in "largescale" mode, solving the Newton systems via the
15 % Conjugate Gradients algorithm.
16 %
17 % At - Handle to a function that takes a K vector and returns an N vector.
18 % If A is a KxN matrix, At is ignored.
19 %
20 % b - Kx1 vector of observations.
21 %
22 % epsilon - scalar, constraint relaxation parameter
23 %
24 % tau - Log barrier parameter.
25 %
26 % newtontol - Terminate when the Newton decrement is <= newtontol.
27 % Default = 1e-3.
28 %
29 % newtonmaxiter - Maximum number of iterations.
30 % Default = 50.
31 %
32 % cgtol - Tolerance for Conjugate Gradients; ignored if A is a matrix.
33 % Default = 1e-8.
34 %
35 % cgmaxiter - Maximum number of iterations for Conjugate Gradients; ignored
36 % if A is a matrix.
37 % Default = 200.
38 %
39 % Written by: Justin Romberg, Caltech
40 % Email: jrom@acm.caltech.edu
41 % Created: October 2005
42 %
43
44
45 function [xp, up, niter] = l1qc_newton(x0, u0, A, At, b, epsilon, tau, newtontol, newtonmaxiter, cgtol, cgmaxiter)
46
47 % check if the matrix A is implicit or explicit
48 largescale = isa(A,'function_handle');
49
50 % line search parameters
51 alpha = 0.01;
52 beta = 0.5;
53
54 if (~largescale), AtA = A'*A; end
55
56 % initial point
57 x = x0;
58 u = u0;
59 if (largescale), r = A(x) - b; else r = A*x - b; end
60 fu1 = x - u;
61 fu2 = -x - u;
62 fe = 1/2*(r'*r - epsilon^2);
63 f = sum(u) - (1/tau)*(sum(log(-fu1)) + sum(log(-fu2)) + log(-fe));
64
65 niter = 0;
66 done = 0;
67 while (~done)
68
69 if (largescale), atr = At(r); else atr = A'*r; end
70
71 ntgz = 1./fu1 - 1./fu2 + 1/fe*atr;
72 ntgu = -tau - 1./fu1 - 1./fu2;
73 gradf = -(1/tau)*[ntgz; ntgu];
74
75 sig11 = 1./fu1.^2 + 1./fu2.^2;
76 sig12 = -1./fu1.^2 + 1./fu2.^2;
77 sigx = sig11 - sig12.^2./sig11;
78
79 w1p = ntgz - sig12./sig11.*ntgu;
80 if (largescale)
81 h11pfun = @(z) sigx.*z - (1/fe)*At(A(z)) + 1/fe^2*(atr'*z)*atr;
82 [dx, cgres, cgiter] = cgsolve(h11pfun, w1p, cgtol, cgmaxiter, 0);
83 if (cgres > 1/2)
84 disp('Cannot solve system. Returning previous iterate. (See Section 4 of notes for more information.)');
85 xp = x; up = u;
86 return
87 end
88 Adx = A(dx);
89 else
90 H11p = diag(sigx) - (1/fe)*AtA + (1/fe)^2*atr*atr';
91 opts.POSDEF = true; opts.SYM = true;
92 [dx,hcond] = linsolve(H11p, w1p, opts);
93 if (hcond < 1e-14)
94 disp('Matrix ill-conditioned. Returning previous iterate. (See Section 4 of notes for more information.)');
95 xp = x; up = u;
96 return
97 end
98 Adx = A*dx;
99 end
100 du = (1./sig11).*ntgu - (sig12./sig11).*dx;
101
102 % minimum step size that stays in the interior
103 ifu1 = find((dx-du) > 0); ifu2 = find((-dx-du) > 0);
104 aqe = Adx'*Adx; bqe = 2*r'*Adx; cqe = r'*r - epsilon^2;
105 smax = min(1,min([...
106 -fu1(ifu1)./(dx(ifu1)-du(ifu1)); -fu2(ifu2)./(-dx(ifu2)-du(ifu2)); ...
107 (-bqe+sqrt(bqe^2-4*aqe*cqe))/(2*aqe)
108 ]));
109 s = (0.99)*smax;
110
111 % backtracking line search
112 suffdec = 0;
113 backiter = 0;
114 while (~suffdec)
115 xp = x + s*dx; up = u + s*du; rp = r + s*Adx;
116 fu1p = xp - up; fu2p = -xp - up; fep = 1/2*(rp'*rp - epsilon^2);
117 fp = sum(up) - (1/tau)*(sum(log(-fu1p)) + sum(log(-fu2p)) + log(-fep));
118 flin = f + alpha*s*(gradf'*[dx; du]);
119 suffdec = (fp <= flin);
120 s = beta*s;
121 backiter = backiter + 1;
122 if (backiter > 32)
123 disp('Stuck on backtracking line search, returning previous iterate. (See Section 4 of notes for more information.)');
124 xp = x; up = u;
125 return
126 end
127 end
128
129 % set up for next iteration
130 x = xp; u = up; r = rp;
131 fu1 = fu1p; fu2 = fu2p; fe = fep; f = fp;
132
133 lambda2 = -(gradf'*[dx; du]);
134 stepsize = s*norm([dx; du]);
135 niter = niter + 1;
136 done = (lambda2/2 < newtontol) | (niter >= newtonmaxiter);
137
138 disp(sprintf('Newton iter = %d, Functional = %8.3f, Newton decrement = %8.3f, Stepsize = %8.3e', ...
139 niter, f, lambda2/2, stepsize));
140 if (largescale)
141 disp(sprintf(' CG Res = %8.3e, CG Iter = %d', cgres, cgiter));
142 else
143 disp(sprintf(' H11p condition number = %8.3e', hcond));
144 end
145
146 end
147
148
149
150