comparison matlab/NESTA/fastProjection.m @ 46:88f0ebe1667a

Finished NESTA implementation. Not tested yet
author nikcleju
date Tue, 29 Nov 2011 22:06:20 +0000
parents
children
comparison
equal deleted inserted replaced
45:7524d7749456 46:88f0ebe1667a
1 function [x,k,l] = fastProjection( U, S, V, y, b, epsilon, lambda0, DISP )
2 % [x,niter,lambda] = fastProjection(U, S, V, y, b, epsilon, [lambda0], [DISP] )
3 %
4 % minimizes || x - y ||
5 % such that || Ax - b || <= epsilon
6 %
7 % where USV' = A (i.e the SVD of A)
8 %
9 % The optional input "lambda0" is a guess for the Lagrange parameter
10 %
11 % Warning: for speed, does not calculate A(y) to see if x = y is feasible
12 %
13 % NESTA Version 1.1
14 % See also Core_Nesterov
15
16 % Written by Stephen Becker, September 2009, srbecker@caltech.edu
17
18 DEBUG = true;
19 if nargin < 8
20 DISP = false;
21 end
22 % -- Parameters for Newton's method --
23 MAXIT = 70;
24 TOL = 1e-8 * epsilon;
25 % TOL = max( TOL, 10*eps ); % we can't do better than machine precision
26
27 m = size(U,1);
28 n = size(V,1);
29 mn = min([m,n]);
30 if numel(S) > mn^2, S = diag(diag(S)); end % S should be a small square matrix
31 r = size(S);
32 if size(U,2) > r, U = U(:,1:r); end
33 if size(V,2) > r, V = V(:,1:r); end
34
35 s = diag(S);
36 s2 = s.^2;
37
38 % What we want to do:
39 % b = b - A*y;
40 % bb = U'*b;
41
42 % if A doesn't have full row rank, then b may not be in the range
43 if size(U,1) > size(U,2)
44 bRange = U*(U'*b);
45 bNull = b - bRange;
46 epsilon = sqrt( epsilon^2 - norm(bNull)^2 );
47 end
48 b = U'*b - S*(V'*y); % parenthesis is very important! This is expensive.
49
50 % b2 = b.^2;
51 b2 = abs(b).^2; % for complex data
52 bs2 = b2.*s2;
53 epsilon2 = epsilon^2;
54
55 % The following routine need to be fast
56 % For efficiency (at cost of transparency), we are writing the calculations
57 % in a way that minimize number of operations. The functions "f"
58 % and "fp" represent f and its derivative.
59
60 % f = @(lambda) sum( b2 .*(1-lambda*s2).^(-2) ) - epsilon^2;
61 % fp = @(lambda) 2*sum( bs2 .*(1-lambda*s2).^(-3) );
62 if nargin < 7, lambda0 = 0; end
63 l = lambda0; oldff = 0;
64 one = ones(m,1);
65 alpha = 1; % take full Newton steps
66 for k = 1:MAXIT
67 % make f(l) and fp(l) as efficient as possible:
68 ls = one./(one-l*s2);
69 ls2 = ls.^2;
70 ls3 = ls2.*ls;
71 ff = b2.'*ls2; % should be .', not ', even for complex data
72 ff = ff - epsilon2;
73 fpl = 2*( bs2.'*ls3 ); % should be .', not ', even for complex data
74 % ff = f(l); % this is a little slower
75 % fpl = fp(l); % this is a little slower
76 d = -ff/fpl;
77 if DISP, fprintf('%2d, lambda is %5.2f, f(lambda) is %.2e, f''(lambda) is %.2e\n',...
78 k,l,ff,fpl ); end
79 if abs(ff) < TOL, break; end % stopping criteria
80 l_old = l;
81 if k>2 && ( abs(ff) > 10*abs(oldff+100) ) %|| abs(d) > 1e13 )
82 l = 0; alpha = 1/2;
83 % oldff = f(0);
84 oldff = sum(b2); oldff = oldff - epsilon2;
85 if DISP, disp('restarting'); end
86 else
87 if alpha < 1, alpha = (alpha+1)/2; end
88 l = l + alpha*d;
89 oldff = ff;
90 if l > 0
91 l = 0; % shouldn't be positive
92 oldff = sum(b2); oldff = oldff - epsilon2;
93 end
94 end
95 if l_old == l && l == 0
96 if DISP, disp('Making no progress; x = y is probably feasible'); end
97 break;
98 end
99 end
100 % if k == MAXIT && DEBUG, disp('maxed out iterations'); end
101 if l < 0
102 xhat = -l*s.*b./( 1 - l*s2 );
103 x = V*xhat + y;
104 else
105 % y is already feasible, so no need to project
106 l = 0;
107 x = y;
108 end