Mercurial > hg > pycsalgos
comparison pyCSalgos/NESTA/NESTA.py @ 45:7524d7749456
Began implementing NESTA, not finished
author | nikcleju |
---|---|
date | Tue, 29 Nov 2011 18:13:17 +0000 |
parents | |
children | 88f0ebe1667a |
comparison
equal
deleted
inserted
replaced
44:0b469b7ea552 | 45:7524d7749456 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 """ | |
3 Created on Tue Nov 29 16:55:20 2011 | |
4 | |
5 @author: ncleju | |
6 """ | |
7 | |
8 import numpy | |
9 import math | |
10 | |
11 #function [xk,niter,residuals,outputData,opts] =NESTA(A,At,b,muf,delta,opts) | |
12 def NESTA(A,At,b,muf,delta,opts=None): | |
13 # [xk,niter,residuals,outputData] =NESTA(A,At,b,muf,delta,opts) | |
14 # | |
15 # Solves a L1 minimization problem under a quadratic constraint using the | |
16 # Nesterov algorithm, with continuation: | |
17 # | |
18 # min_x || U x ||_1 s.t. ||y - Ax||_2 <= delta | |
19 # | |
20 # Continuation is performed by sequentially applying Nesterov's algorithm | |
21 # with a decreasing sequence of values of mu0 >= mu >= muf | |
22 # | |
23 # The primal prox-function is also adapted by accounting for a first guess | |
24 # xplug that also tends towards x_muf | |
25 # | |
26 # The observation matrix A is a projector | |
27 # | |
28 # Inputs: A and At - measurement matrix and adjoint (either a matrix, in which | |
29 # case At is unused, or function handles). m x n dimensions. | |
30 # b - Observed data, a m x 1 array | |
31 # muf - The desired value of mu at the last continuation step. | |
32 # A smaller mu leads to higher accuracy. | |
33 # delta - l2 error bound. This enforces how close the variable | |
34 # must fit the observations b, i.e. || y - Ax ||_2 <= delta | |
35 # If delta = 0, enforces y = Ax | |
36 # Common heuristic: delta = sqrt(m + 2*sqrt(2*m))*sigma; | |
37 # where sigma=std(noise). | |
38 # opts - | |
39 # This is a structure that contains additional options, | |
40 # some of which are optional. | |
41 # The fieldnames are case insensitive. Below | |
42 # are the possible fieldnames: | |
43 # | |
44 # opts.xplug - the first guess for the primal prox-function, and | |
45 # also the initial point for xk. By default, xplug = At(b) | |
46 # opts.U and opts.Ut - Analysis/Synthesis operators | |
47 # (either matrices of function handles). | |
48 # opts.normU - if opts.U is provided, this should be norm(U) | |
49 # otherwise it will have to be calculated (potentially | |
50 # expensive) | |
51 # opts.MaxIntIter - number of continuation steps. | |
52 # default is 5 | |
53 # opts.maxiter - max number of iterations in an inner loop. | |
54 # default is 10,000 | |
55 # opts.TolVar - tolerance for the stopping criteria | |
56 # opts.stopTest - which stopping criteria to apply | |
57 # opts.stopTest == 1 : stop when the relative | |
58 # change in the objective function is less than | |
59 # TolVar | |
60 # opts.stopTest == 2 : stop with the l_infinity norm | |
61 # of difference in the xk variable is less | |
62 # than TolVar | |
63 # opts.TypeMin - if this is 'L1' (default), then | |
64 # minimizes a smoothed version of the l_1 norm. | |
65 # If this is 'tv', then minimizes a smoothed | |
66 # version of the total-variation norm. | |
67 # The string is case insensitive. | |
68 # opts.Verbose - if this is 0 or false, then very | |
69 # little output is displayed. If this is 1 or true, | |
70 # then output every iteration is displayed. | |
71 # If this is a number p greater than 1, then | |
72 # output is displayed every pth iteration. | |
73 # opts.fid - if this is 1 (default), the display is | |
74 # the usual Matlab screen. If this is the file-id | |
75 # of a file opened with fopen, then the display | |
76 # will be redirected to this file. | |
77 # opts.errFcn - if this is a function handle, | |
78 # then the program will evaluate opts.errFcn(xk) | |
79 # at every iteration and display the result. | |
80 # ex. opts.errFcn = @(x) norm( x - x_true ) | |
81 # opts.outFcn - if this is a function handle, | |
82 # then then program will evaluate opts.outFcn(xk) | |
83 # at every iteration and save the results in outputData. | |
84 # If the result is a vector (as opposed to a scalar), | |
85 # it should be a row vector and not a column vector. | |
86 # ex. opts.outFcn = @(x) [norm( x - xtrue, 'inf' ),... | |
87 # norm( x - xtrue) / norm(xtrue)] | |
88 # opts.AAtinv - this is an experimental new option. AAtinv | |
89 # is the inverse of AA^*. This allows the use of a | |
90 # matrix A which is not a projection, but only | |
91 # for the noiseless (i.e. delta = 0) case. | |
92 # opts.USV - another experimental option. This supercedes | |
93 # the AAtinv option, so it is recommended that you | |
94 # do not define AAtinv. This allows the use of a matrix | |
95 # A which is not a projection, and works for the | |
96 # noisy ( i.e. delta > 0 ) case. | |
97 # opts.USV should contain three fields: | |
98 # opts.USV.U is the U from [U,S,V] = svd(A) | |
99 # likewise, opts.USV.S and opts.USV.V are S and V | |
100 # from svd(A). S may be a matrix or a vector. | |
101 # | |
102 # Outputs: | |
103 # xk - estimate of the solution x | |
104 # niter - number of iterations | |
105 # residuals - first column is the residual at every step, | |
106 # second column is the value of f_mu at every step | |
107 # outputData - a matrix, where each row r is the output | |
108 # from opts.outFcn, if supplied. | |
109 # opts - the structure containing the options that were used | |
110 # | |
111 # Written by: Jerome Bobin, Caltech | |
112 # Email: bobin@acm.caltech.edu | |
113 # Created: February 2009 | |
114 # Modified (version 1.0): May 2009, Jerome Bobin and Stephen Becker, Caltech | |
115 # Modified (version 1.1): Nov 2009, Stephen Becker, Caltech | |
116 # | |
117 # NESTA Version 1.1 | |
118 # See also Core_Nesterov | |
119 | |
120 #--------------------- | |
121 # Original Matab code: | |
122 # | |
123 #if nargin < 6, opts = []; end | |
124 #if isempty(opts) && isnumeric(opts), opts = struct; end | |
125 # | |
126 ##---- Set defaults | |
127 #fid = setOpts('fid',1); | |
128 #Verbose = setOpts('Verbose',true); | |
129 #function printf(varargin), fprintf(fid,varargin{:}); end | |
130 #MaxIntIter = setOpts('MaxIntIter',5,1); | |
131 #TypeMin = setOpts('TypeMin','L1'); | |
132 #TolVar = setOpts('tolvar',1e-5); | |
133 #[U,U_userSet] = setOpts('U', @(x) x ); | |
134 #if ~isa(U,'function_handle') | |
135 # Ut = setOpts('Ut',[]); | |
136 #else | |
137 # Ut = setOpts('Ut', @(x) x ); | |
138 #end | |
139 #xplug = setOpts('xplug',[]); | |
140 #normU = setOpts('normU',[]); # so we can tell if it's been set | |
141 # | |
142 #residuals = []; outputData = []; | |
143 #AAtinv = setOpts('AAtinv',[]); | |
144 #USV = setOpts('USV',[]); | |
145 #if ~isempty(USV) | |
146 # if isstruct(USV) | |
147 # Q = USV.U; # we can't use "U" as the variable name | |
148 # # since "U" already refers to the analysis operator | |
149 # S = USV.S; | |
150 # if isvector(S), s = S; #S = diag(s); | |
151 # else s = diag(S); end | |
152 # #V = USV.V; | |
153 # else | |
154 # error('opts.USV must be a structure'); | |
155 # end | |
156 #end | |
157 # | |
158 ## -- We can handle non-projections IF a (fast) routine for computing | |
159 ## the psuedo-inverse is available. | |
160 ## We can handle a nonzero delta, but we need the full SVD | |
161 #if isempty(AAtinv) && isempty(USV) | |
162 # # Check if A is a partial isometry, i.e. if AA' = I | |
163 # z = randn(size(b)); | |
164 # if isa(A,'function_handle'), AAtz = A(At(z)); | |
165 # else AAtz = A*(A'*z); end | |
166 # if norm( AAtz - z )/norm(z) > 1e-8 | |
167 # error('Measurement matrix A must be a partial isometry: AA''=I'); | |
168 # end | |
169 #end | |
170 # | |
171 ## -- Find a initial guess if not already provided. | |
172 ## Use least-squares solution: x_ref = A'*inv(A*A')*b | |
173 ## If A is a projection, the least squares solution is trivial | |
174 #if isempty(xplug) || norm(xplug) < 1e-12 | |
175 # if ~isempty(USV) && isempty(AAtinv) | |
176 # AAtinv = Q*diag( s.^(-2) )*Q'; | |
177 # end | |
178 # if ~isempty(AAtinv) | |
179 # if delta > 0 && isempty(USV) | |
180 # error('delta must be zero for non-projections'); | |
181 # end | |
182 # if isa(AAtinv,'function_handle') | |
183 # x_ref = AAtinv(b); | |
184 # else | |
185 # x_ref = AAtinv * b; | |
186 # end | |
187 # else | |
188 # x_ref = b; | |
189 # end | |
190 # | |
191 # if isa(A,'function_handle') | |
192 # x_ref=At(x_ref); | |
193 # else | |
194 # x_ref = A'*x_ref; | |
195 # end | |
196 # | |
197 # if isempty(xplug) | |
198 # xplug = x_ref; | |
199 # end | |
200 # # x_ref itself is used to calculate mu_0 | |
201 # # in the case that xplug has very small norm | |
202 #else | |
203 # x_ref = xplug; | |
204 #end | |
205 # | |
206 ## use x_ref, not xplug, to find mu_0 | |
207 #if isa(U,'function_handle') | |
208 # Ux_ref = U(x_ref); | |
209 #else | |
210 # Ux_ref = U*x_ref; | |
211 #end | |
212 #switch lower(TypeMin) | |
213 # case 'l1' | |
214 # mu0 = 0.9*max(abs(Ux_ref)); | |
215 # case 'tv' | |
216 # mu0 = ValMUTv(Ux_ref); | |
217 #end | |
218 # | |
219 ## -- If U was set by the user and normU not supplied, then calcuate norm(U) | |
220 #if U_userSet && isempty(normU) | |
221 # # simple case: U*U' = I or U'*U = I, in which case norm(U) = 1 | |
222 # z = randn(size(xplug)); | |
223 # if isa(U,'function_handle'), UtUz = Ut(U(z)); else UtUz = U'*(U*z); end | |
224 # if norm( UtUz - z )/norm(z) < 1e-8 | |
225 # normU = 1; | |
226 # else | |
227 # z = randn(size(Ux_ref)); | |
228 # if isa(U,'function_handle') | |
229 # UUtz = U(Ut(z)); | |
230 # else | |
231 # UUtz = U*(U'*z); | |
232 # end | |
233 # if norm( UUtz - z )/norm(z) < 1e-8 | |
234 # normU = 1; | |
235 # end | |
236 # end | |
237 # | |
238 # if isempty(normU) | |
239 # # have to actually calculate the norm | |
240 # if isa(U,'function_handle') | |
241 # [normU,cnt] = my_normest(U,Ut,length(xplug),1e-3,30); | |
242 # if cnt == 30, printf('Warning: norm(U) may be inaccurate\n'); end | |
243 # else | |
244 # [mU,nU] = size(U); | |
245 # if mU < nU, UU = U*U'; else UU = U'*U; end | |
246 # # last resort is to call MATLAB's "norm", which is slow | |
247 # if norm( UU - diag(diag(UU)),'fro') < 100*eps | |
248 # # this means the matrix is diagonal, so norm is easy: | |
249 # normU = sqrt( max(abs(diag(UU))) ); | |
250 # elseif issparse(UU) | |
251 # normU = sqrt( normest(UU) ); | |
252 # else | |
253 # if min(size(U)) > 2000 | |
254 # # norm(randn(2000)) takes about 5 seconds on my PC | |
255 # printf('Warning: calculation of norm(U) may be slow\n'); | |
256 # end | |
257 # normU = sqrt( norm(UU) ); | |
258 # end | |
259 # end | |
260 # end | |
261 # opts.normU = normU; | |
262 #end | |
263 # | |
264 # | |
265 #niter = 0; | |
266 #Gamma = (muf/mu0)^(1/MaxIntIter); | |
267 #mu = mu0; | |
268 #Gammat= (TolVar/0.1)^(1/MaxIntIter); | |
269 #TolVar = 0.1; | |
270 # | |
271 #for nl=1:MaxIntIter | |
272 # | |
273 # mu = mu*Gamma; | |
274 # TolVar=TolVar*Gammat; opts.TolVar = TolVar; | |
275 # opts.xplug = xplug; | |
276 # if Verbose, printf('\tBeginning #s Minimization; mu = #g\n',opts.TypeMin,mu); end | |
277 # [xk,niter_int,res,out,optsOut] = Core_Nesterov(... | |
278 # A,At,b,mu,delta,opts); | |
279 # | |
280 # xplug = xk; | |
281 # niter = niter_int + niter; | |
282 # | |
283 # residuals = [residuals; res]; | |
284 # outputData = [outputData; out]; | |
285 # | |
286 #end | |
287 #opts = optsOut; | |
288 | |
289 # End of original Matab code: | |
290 #--------------------- | |
291 | |
292 | |
293 #if isempty(opts) && isnumeric(opts), opts = struct; end | |
294 | |
295 #---- Set defaults | |
296 #fid = setOpts('fid',1); | |
297 opts,Verbose,userSet = setOpts(opts,'Verbose',True); | |
298 #function printf(varargin), fprintf(fid,varargin{:}); end | |
299 opts,MaxIntIter,userSet = setOpts(opts,'MaxIntIter',5,1); | |
300 opts,TypeMin,userSet = setOpts(opts,'TypeMin','L1'); | |
301 opts,TolVar,userSet = setOpts(opts,'tolvar',1e-5); | |
302 #[U,U_userSet] = setOpts('U', @(x) x ); | |
303 opts,U,U_userSet = setOpts(opts,'U', lambda x: x ); | |
304 #if ~isa(U,'function_handle') | |
305 if hasattr(U, '__call__'): | |
306 opts,Ut,userSet = setOpts(opts,'Ut',None) | |
307 else: | |
308 opts,Ut,userSet = setOpts(opts,'Ut', lambda x: x ) | |
309 #end | |
310 opts,xplug,userSet = setOpts(opts,'xplug',None); | |
311 opts,normU,userSet = setOpts(opts,'normU',None); # so we can tell if it's been set | |
312 | |
313 #residuals = []; outputData = []; | |
314 residuals = numpy.array([]) | |
315 outputData = numpy.array([]) | |
316 opts,AAtinv,userSet = setOpts(opts,'AAtinv',None); | |
317 opts,USV,userSet = setOpts(opts,'USV',None); | |
318 #if ~isempty(USV) | |
319 if len(USV.keys()): | |
320 #if isstruct(USV) | |
321 | |
322 Q = USV['U'] # we can't use "U" as the variable name | |
323 # since "U" already refers to the analysis operator | |
324 S = USV['S'] | |
325 if S.ndim is 1: | |
326 s = S | |
327 else: | |
328 s = numpy.diag(S) | |
329 | |
330 #V = USV.V; | |
331 #else | |
332 # error('opts.USV must be a structure'); | |
333 #end | |
334 #end | |
335 | |
336 # -- We can handle non-projections IF a (fast) routine for computing | |
337 # the psuedo-inverse is available. | |
338 # We can handle a nonzero delta, but we need the full SVD | |
339 #if isempty(AAtinv) && isempty(USV) | |
340 if (AAtinv is None) and (USV is None): | |
341 # Check if A is a partial isometry, i.e. if AA' = I | |
342 #z = randn(size(b)); | |
343 z = numpy.random.randn(b.shape) | |
344 #if isa(A,'function_handle'), AAtz = A(At(z)); | |
345 #else AAtz = A*(A'*z); end | |
346 if hasattr(A, '__call__'): | |
347 AAtz = A(At(z)) | |
348 else: | |
349 #AAtz = A*(A'*z) | |
350 AAtz = numpy.dot(A, numpy.dot(A.T,z)) | |
351 | |
352 #if norm( AAtz - z )/norm(z) > 1e-8 | |
353 if numpy.linalg.norm(AAtz - z) / numpy.linalg.norm(z) > 1e-8: | |
354 #error('Measurement matrix A must be a partial isometry: AA''=I'); | |
355 print 'Measurement matrix A must be a partial isometry: AA''=I' | |
356 raise | |
357 #end | |
358 #end | |
359 | |
360 # -- Find a initial guess if not already provided. | |
361 # Use least-squares solution: x_ref = A'*inv(A*A')*b | |
362 # If A is a projection, the least squares solution is trivial | |
363 #if isempty(xplug) || norm(xplug) < 1e-12 | |
364 if xplug is None or numpy.linalg.norm(xplug) < 1e-12: | |
365 #if ~isempty(USV) && isempty(AAtinv) | |
366 if USV is not None and AAtinv is None: | |
367 #AAtinv = Q*diag( s.^(-2) )*Q'; | |
368 AAtinv = numpy.dot(Q, numpy.dot(numpy.diag(s ** -2), Q.T)) | |
369 #end | |
370 #if ~isempty(AAtinv) | |
371 if AAtinv is not None: | |
372 #if delta > 0 && isempty(USV) | |
373 if delta > 0 and USV is None: | |
374 #error('delta must be zero for non-projections'); | |
375 print 'delta must be zero for non-projections' | |
376 raise | |
377 #end | |
378 #if isa(AAtinv,'function_handle') | |
379 if hasattr(AAtinv,'__call__'): | |
380 x_ref = AAtinv(b) | |
381 else: | |
382 x_ref = numpy.dot(AAtinv , b) | |
383 #end | |
384 else: | |
385 x_ref = b | |
386 #end | |
387 | |
388 #if isa(A,'function_handle') | |
389 if hasattr(A,'__call__'): | |
390 x_ref=At(x_ref); | |
391 else: | |
392 #x_ref = A'*x_ref; | |
393 x_ref = numpy.dot(A.T, x_ref) | |
394 #end | |
395 | |
396 #if isempty(xplug) | |
397 if xplug is None: | |
398 xplug = x_ref; | |
399 #end | |
400 # x_ref itself is used to calculate mu_0 | |
401 # in the case that xplug has very small norm | |
402 else: | |
403 x_ref = xplug; | |
404 #end | |
405 | |
406 # use x_ref, not xplug, to find mu_0 | |
407 #if isa(U,'function_handle') | |
408 if hasattr(U,'__call__'): | |
409 Ux_ref = U(x_ref); | |
410 else: | |
411 Ux_ref = numpy.dot(U,x_ref) | |
412 #end | |
413 #switch lower(TypeMin) | |
414 # case 'l1' | |
415 # mu0 = 0.9*max(abs(Ux_ref)); | |
416 # case 'tv' | |
417 # mu0 = ValMUTv(Ux_ref); | |
418 #end | |
419 if TypeMin.lower() == 'l1': | |
420 mu0 = 0.9*max(abs(Ux_ref)) | |
421 elif TypeMin.lower() == 'tv': | |
422 #mu0 = ValMUTv(Ux_ref); | |
423 print 'Nic: TODO: not implemented yet' | |
424 raise | |
425 | |
426 # -- If U was set by the user and normU not supplied, then calcuate norm(U) | |
427 #if U_userSet && isempty(normU) | |
428 if U_userSet and normU is None: | |
429 # simple case: U*U' = I or U'*U = I, in which case norm(U) = 1 | |
430 #z = randn(size(xplug)); | |
431 z = numpy.random.randn(xplug.shape) | |
432 #if isa(U,'function_handle'), UtUz = Ut(U(z)); else UtUz = U'*(U*z); end | |
433 if hasattr(U,'__call__'): | |
434 UtUz = Ut(U(z)) | |
435 else: | |
436 UtUz = numpy.dot(U.T, numpy.dot(U,z)) | |
437 | |
438 if numpy.linalg.norm( UtUz - z )/numpy.linalg.norm(z) < 1e-8: | |
439 normU = 1; | |
440 else: | |
441 z = numpy.random.randn(Ux_ref.shape) | |
442 #if isa(U,'function_handle'): | |
443 if hasattr(U,'__call__'): | |
444 UUtz = U(Ut(z)); | |
445 else: | |
446 #UUtz = U*(U'*z); | |
447 UUtz = numpy.dot(U, numpy.dot(U.T,z)) | |
448 #end | |
449 if numpy.linalg.norm( UUtz - z )/numpy.linalg.norm(z) < 1e-8: | |
450 normU = 1; | |
451 #end | |
452 #end | |
453 | |
454 #if isempty(normU) | |
455 if normU is None: | |
456 # have to actually calculate the norm | |
457 #if isa(U,'function_handle') | |
458 if hasattr(U,'__call__'): | |
459 #[normU,cnt] = my_normest(U,Ut,length(xplug),1e-3,30); | |
460 normU,cnt = my_normest(U,Ut,xplug.size,1e-3,30) | |
461 #if cnt == 30, printf('Warning: norm(U) may be inaccurate\n'); end | |
462 if cnt == 30: | |
463 print 'Warning: norm(U) may be inaccurate' | |
464 else: | |
465 mU,nU = U.shape | |
466 if mU < nU: | |
467 UU = numpy.dot(U,U.T) | |
468 else: | |
469 UU = numpy.dot(U.T,U) | |
470 # last resort is to call MATLAB's "norm", which is slow | |
471 #if norm( UU - diag(diag(UU)),'fro') < 100*eps | |
472 if numpy.linalg.norm( UU - numpy.diag(numpy.diag(UU)),'fro') < 100*numpy.finfo(float).eps: | |
473 # this means the matrix is diagonal, so norm is easy: | |
474 #normU = sqrt( max(abs(diag(UU))) ); | |
475 normU = math.sqrt( max(abs(numpy.diag(UU))) ) | |
476 | |
477 # Nic: TODO: sparse not implemented | |
478 #elif issparse(UU) | |
479 # normU = sqrt( normest(UU) ); | |
480 else: | |
481 if min(U.shape) > 2000: | |
482 # norm(randn(2000)) takes about 5 seconds on my PC | |
483 #printf('Warning: calculation of norm(U) may be slow\n'); | |
484 print 'Warning: calculation of norm(U) may be slow' | |
485 #end | |
486 normU = math.sqrt( numpy.linalg.norm(UU) ); | |
487 #end | |
488 #end | |
489 #end | |
490 #opts.normU = normU; | |
491 opts['normU'] = normU | |
492 #end | |
493 | |
494 niter = 0; | |
495 Gamma = (muf/mu0)**(1.0/MaxIntIter); | |
496 mu = mu0; | |
497 Gammat = (TolVar/0.1)**(1.0/MaxIntIter); | |
498 TolVar = 0.1; | |
499 | |
500 #for nl=1:MaxIntIter | |
501 for n1 in numpy.arange(MaxIntIter): | |
502 | |
503 mu = mu*Gamma; | |
504 TolVar=TolVar*Gammat; | |
505 opts['TolVar'] = TolVar; | |
506 opts['xplug'] = xplug; | |
507 #if Verbose, printf('\tBeginning #s Minimization; mu = #g\n',opts.TypeMin,mu); end | |
508 if Verbose: | |
509 #printf('\tBeginning #s Minimization; mu = #g\n',opts.TypeMin,mu) | |
510 print ' Beginning', opts['TypeMin'],'Minimization; mu =',mu | |
511 | |
512 #[xk,niter_int,res,out,optsOut] = Core_Nesterov(A,At,b,mu,delta,opts); | |
513 xk,niter_int,res,out,optsOut = Core_Nesterov(A,At,b,mu,delta,opts) | |
514 | |
515 xplug = xk.copy(); | |
516 niter = niter_int + niter; | |
517 | |
518 #residuals = [residuals; res]; | |
519 residuals = numpy.hstack((residuals,res)) | |
520 #outputData = [outputData; out]; | |
521 outputData = numpy.hstack((outputData, out)) | |
522 | |
523 #end | |
524 opts = optsOut.copy() | |
525 | |
526 return xk,niter,residuals,outputData,opts | |
527 | |
528 | |
529 | |
530 #---- internal routine for setting defaults | |
531 #function [var,userSet] = setOpts(field,default,mn,mx) | |
532 def setOpts(opts,field,default,mn=None,mx=None): | |
533 | |
534 var = default | |
535 # has the option already been set? | |
536 #if ~isfield(opts,field) | |
537 if field in opts.keys(): | |
538 # see if there is a capitalization problem: | |
539 #names = fieldnames(opts); | |
540 #for i = 1:length(names) | |
541 for key in opts.keys(): | |
542 #if strcmpi(names{i},field) | |
543 if key.lower() == field.lower(): | |
544 #opts.(field) = opts.(names{i}); | |
545 opts[field] = opts[key] | |
546 #opts = rmfield(opts,names{i}); | |
547 del opts[key] | |
548 break | |
549 #end | |
550 #end | |
551 #end | |
552 | |
553 #if isfield(opts,field) && ~isempty(opts.(field)) | |
554 if field in opts.keys() and (opts[field] is not None): | |
555 #var = opts.(field); # override the default | |
556 var = opts[field] | |
557 userSet = True | |
558 else: | |
559 userSet = False | |
560 #end | |
561 # perform error checking, if desired | |
562 #if nargin >= 3 && ~isempty(mn) | |
563 if mn is not None: | |
564 if var < mn: | |
565 #printf('Variable #s is #f, should be at least #f\n',... | |
566 # field,var,mn); error('variable out-of-bounds'); | |
567 print 'Variable',field,'is',var,', should be at least',mn | |
568 raise | |
569 #end | |
570 #end | |
571 #if nargin >= 4 && ~isempty(mx) | |
572 if mx is not None: | |
573 if var > mx: | |
574 #printf('Variable #s is #f, should be at least #f\n',... | |
575 # field,var,mn); error('variable out-of-bounds'); | |
576 print 'Variable',field,'is',var,', should be at most',mx | |
577 raise | |
578 #end | |
579 #end | |
580 #opts.(field) = var; | |
581 opts[field] = var | |
582 | |
583 return opts,var,userSet | |
584 | |
585 # Nic: TODO: implement TV | |
586 #---- internal routine for setting mu0 in the tv minimization case | |
587 #function th=ValMUTv(x) | |
588 # #N = length(x);n = floor(sqrt(N)); | |
589 # N = b.size | |
590 # n = floor(sqrt(N)) | |
591 # Dv = spdiags([reshape([-ones(n-1,n); zeros(1,n)],N,1) ... | |
592 # reshape([zeros(1,n); ones(n-1,n)],N,1)], [0 1], N, N); | |
593 # Dh = spdiags([reshape([-ones(n,n-1) zeros(n,1)],N,1) ... | |
594 # reshape([zeros(n,1) ones(n,n-1)],N,1)], [0 n], N, N); | |
595 # D = sparse([Dh;Dv]); | |
596 # | |
597 # | |
598 # Dhx = Dh*x; | |
599 # Dvx = Dv*x; | |
600 # | |
601 # sk = sqrt(abs(Dhx).^2 + abs(Dvx).^2); | |
602 # th = max(sk); | |
603 # | |
604 #end | |
605 | |
606 #end #-- end of NESTA function | |
607 | |
608 ############ POWER METHOD TO ESTIMATE NORM ############### | |
609 # Copied from MATLAB's "normest" function, but allows function handles, not just sparse matrices | |
610 #function [e,cnt] = my_normest(S,St,n,tol, maxiter) | |
611 def my_normest(S,St,n,tol=1e-6, maxiter=20): | |
612 #MY_NORMEST Estimate the matrix 2-norm via power method. | |
613 #if nargin < 4, tol = 1.e-6; end | |
614 #if nargin < 5, maxiter = 20; end | |
615 #if isempty(St) | |
616 if S is None: | |
617 St = S # we assume the matrix is symmetric; | |
618 #end | |
619 x = numpy.ones(n); | |
620 cnt = 0; | |
621 e = numpy.linalg.norm(x); | |
622 #if e == 0, return, end | |
623 if e == 0: | |
624 return e,cnt | |
625 x = x/e; | |
626 e0 = 0; | |
627 while abs(e-e0) > tol*e and cnt < maxiter: | |
628 e0 = e; | |
629 Sx = S(x); | |
630 #if nnz(Sx) == 0 | |
631 if (Sx!=0).sum() == 0: | |
632 Sx = numpy.random.rand(Sx.size); | |
633 #end | |
634 e = numpy.linalg.norm(Sx); | |
635 x = St(Sx); | |
636 x = x/numpy.linalg.norm(x); | |
637 cnt = cnt+1; | |
638 #end | |
639 #end |