Mercurial > hg > pycsalgos
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 |