annotate scripts/ABSapprox.py @ 31:829bf04c92af

Enabled fine step of 0.05 for delta and rho
author nikcleju
date Thu, 10 Nov 2011 22:48:39 +0000
parents 5f46ff51c7ff
children e1da5140c9a5
rev   line source
nikcleju@10 1 # -*- coding: utf-8 -*-
nikcleju@10 2 """
nikcleju@10 3 Created on Sat Nov 05 18:08:40 2011
nikcleju@10 4
nikcleju@10 5 @author: Nic
nikcleju@10 6 """
nikcleju@10 7
nikcleju@19 8 import numpy as np
nikcleju@22 9 import scipy.io
nikcleju@22 10 import math
nikcleju@29 11
nikcleju@10 12 import pyCSalgos
nikcleju@19 13 import pyCSalgos.GAP.GAP
nikcleju@19 14 import pyCSalgos.SL0.SL0_approx
nikcleju@30 15 import pyCSalgos.OMP.omp_QR
nikcleju@30 16 import pyCSalgos.RecomTST.RecommendedTST
nikcleju@10 17
nikcleju@29 18 #==========================
nikcleju@29 19 # Algorithm functions
nikcleju@29 20 #==========================
nikcleju@22 21 def run_gap(y,M,Omega,epsilon):
nikcleju@19 22 gapparams = {"num_iteration" : 1000,\
nikcleju@19 23 "greedy_level" : 0.9,\
nikcleju@19 24 "stopping_coefficient_size" : 1e-4,\
nikcleju@19 25 "l2solver" : 'pseudoinverse',\
nikcleju@19 26 "noise_level": epsilon}
nikcleju@22 27 return pyCSalgos.GAP.GAP.GAP(y,M,M.T,Omega,Omega.T,gapparams,np.zeros(Omega.shape[1]))[0]
nikcleju@29 28
nikcleju@22 29 def run_sl0(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@19 30
nikcleju@19 31 N,n = Omega.shape
nikcleju@22 32 #D = np.linalg.pinv(Omega)
nikcleju@22 33 #U,S,Vt = np.linalg.svd(D)
nikcleju@19 34 aggDupper = np.dot(M,D)
nikcleju@19 35 aggDlower = Vt[-(N-n):,:]
nikcleju@19 36 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@19 37 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@19 38
nikcleju@22 39 sigmamin = 0.001
nikcleju@22 40 sigma_decrease_factor = 0.5
nikcleju@20 41 mu_0 = 2
nikcleju@20 42 L = 10
nikcleju@22 43 return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
nikcleju@10 44
nikcleju@27 45 def run_bp(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@27 46
nikcleju@27 47 N,n = Omega.shape
nikcleju@27 48 #D = np.linalg.pinv(Omega)
nikcleju@27 49 #U,S,Vt = np.linalg.svd(D)
nikcleju@27 50 aggDupper = np.dot(M,D)
nikcleju@27 51 aggDlower = Vt[-(N-n):,:]
nikcleju@27 52 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@27 53 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@27 54
nikcleju@27 55 sigmamin = 0.001
nikcleju@27 56 sigma_decrease_factor = 0.5
nikcleju@27 57 mu_0 = 2
nikcleju@27 58 L = 10
nikcleju@27 59 return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
nikcleju@27 60
nikcleju@30 61 def run_ompeps(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@30 62
nikcleju@30 63 N,n = Omega.shape
nikcleju@30 64 #D = np.linalg.pinv(Omega)
nikcleju@30 65 #U,S,Vt = np.linalg.svd(D)
nikcleju@30 66 aggDupper = np.dot(M,D)
nikcleju@30 67 aggDlower = Vt[-(N-n):,:]
nikcleju@30 68 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@30 69 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@30 70
nikcleju@30 71 opts = dict()
nikcleju@30 72 opts['stopCrit'] = 'mse'
nikcleju@30 73 opts['stopTol'] = epsilon**2 / aggy.size
nikcleju@30 74 return pyCSalgos.OMP.omp_QR.greed_omp_qr(aggy,aggD,aggD.shape[1],opts)[0]
nikcleju@30 75
nikcleju@30 76 def run_tst(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@30 77
nikcleju@30 78 N,n = Omega.shape
nikcleju@30 79 #D = np.linalg.pinv(Omega)
nikcleju@30 80 #U,S,Vt = np.linalg.svd(D)
nikcleju@30 81 aggDupper = np.dot(M,D)
nikcleju@30 82 aggDlower = Vt[-(N-n):,:]
nikcleju@30 83 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@30 84 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@30 85
nikcleju@30 86 return pyCSalgos.RecomTST.RecommendedTST.RecommendedTST(aggD, aggy, nsweep=3000, tol=epsilon / np.linalg.norm(aggy))
nikcleju@30 87
nikcleju@29 88 #==========================
nikcleju@29 89 # Define tuples (algorithm function, name)
nikcleju@29 90 #==========================
nikcleju@22 91 gap = (run_gap, 'GAP')
nikcleju@30 92 sl0 = (run_sl0, 'SL0a')
nikcleju@29 93 bp = (run_bp, 'BP')
nikcleju@30 94 ompeps = (run_ompeps, 'OMPeps')
nikcleju@30 95 tst = (run_tst, 'TST')
nikcleju@10 96
nikcleju@22 97 # Define which algorithms to run
nikcleju@22 98 # 1. Algorithms not depending on lambda
nikcleju@22 99 algosN = gap, # tuple
nikcleju@22 100 # 2. Algorithms depending on lambda (our ABS approach)
nikcleju@30 101 algosL = sl0,bp,ompeps,tst # tuple
nikcleju@29 102
nikcleju@29 103 #==========================
nikcleju@29 104 # Interface functions
nikcleju@29 105 #==========================
nikcleju@29 106 def run_multiproc(ncpus=None):
nikcleju@30 107 d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,doshowplot,dosaveplot,saveplotbase,saveplotexts = standard_params()
nikcleju@29 108 run_multi(algosN, algosL, d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata=dosavedata,savedataname=savedataname,\
nikcleju@30 109 doparallel=True, ncpus=ncpus,\
nikcleju@30 110 doshowplot=doshowplot,dosaveplot=dosaveplot,saveplotbase=saveplotbase,saveplotexts=saveplotexts)
nikcleju@22 111
nikcleju@29 112 def run():
nikcleju@30 113 d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,doshowplot,dosaveplot,saveplotbase,saveplotexts = standard_params()
nikcleju@29 114 run_multi(algosN, algosL, d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata=dosavedata,savedataname=savedataname,\
nikcleju@30 115 doparallel=False,\
nikcleju@30 116 doshowplot=doshowplot,dosaveplot=dosaveplot,saveplotbase=saveplotbase,saveplotexts=saveplotexts)
nikcleju@19 117
nikcleju@29 118 def standard_params():
nikcleju@29 119 #Set up standard experiment parameters
nikcleju@25 120 d = 50.0;
nikcleju@22 121 sigma = 2.0
nikcleju@31 122 deltas = np.arange(0.05,1.,0.05)
nikcleju@31 123 rhos = np.arange(0.05,1.,0.05)
nikcleju@30 124 #deltas = np.array([0.05, 0.45, 0.95])
nikcleju@30 125 #rhos = np.array([0.05, 0.45, 0.95])
nikcleju@31 126 #deltas = np.array([0.05])
nikcleju@31 127 #rhos = np.array([0.05])
nikcleju@22 128 #delta = 0.8;
nikcleju@22 129 #rho = 0.15;
nikcleju@27 130 numvects = 100; # Number of vectors to generate
nikcleju@20 131 SNRdb = 20.; # This is norm(signal)/norm(noise), so power, not energy
nikcleju@22 132 # Values for lambda
nikcleju@22 133 #lambdas = [0 10.^linspace(-5, 4, 10)];
nikcleju@25 134 #lambdas = np.concatenate((np.array([0]), 10**np.linspace(-5, 4, 10)))
nikcleju@25 135 lambdas = np.array([0., 0.0001, 0.01, 1, 100, 10000])
nikcleju@29 136
nikcleju@29 137 dosavedata = True
nikcleju@30 138 savedataname = 'approx_pt_std1.mat'
nikcleju@30 139
nikcleju@30 140 doshowplot = False
nikcleju@30 141 dosaveplot = True
nikcleju@30 142 saveplotbase = 'approx_pt_std1_'
nikcleju@30 143 saveplotexts = ('png','pdf','eps')
nikcleju@29 144
nikcleju@29 145
nikcleju@30 146 return d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
nikcleju@30 147 doshowplot,dosaveplot,saveplotbase,saveplotexts
nikcleju@29 148
nikcleju@29 149 #==========================
nikcleju@29 150 # Main functions
nikcleju@29 151 #==========================
nikcleju@29 152 def run_multi(algosN, algosL, d, sigma, deltas, rhos, lambdas, numvects, SNRdb,
nikcleju@29 153 doparallel=False, ncpus=None,\
nikcleju@29 154 doshowplot=False, dosaveplot=False, saveplotbase=None, saveplotexts=None,\
nikcleju@29 155 dosavedata=False, savedataname=None):
nikcleju@30 156
nikcleju@30 157 print "This is analysis recovery ABS approximation script by Nic"
nikcleju@30 158 print "Running phase transition ( run_multi() )"
nikcleju@29 159
nikcleju@29 160 if doparallel:
nikcleju@29 161 from multiprocessing import Pool
nikcleju@29 162
nikcleju@30 163 if dosaveplot or doshowplot:
nikcleju@30 164 try:
nikcleju@30 165 import matplotlib
nikcleju@30 166 if doshowplot:
nikcleju@30 167 print "Importing matplotlib with default (GUI) backend... ",
nikcleju@30 168 else:
nikcleju@30 169 print "Importing matplotlib with \"Cairo\" backend... ",
nikcleju@30 170 matplotlib.use('Cairo')
nikcleju@30 171 import matplotlib.pyplot as plt
nikcleju@30 172 import matplotlib.cm as cm
nikcleju@30 173 print "OK"
nikcleju@30 174 except:
nikcleju@30 175 print "FAIL"
nikcleju@30 176 print "Importing matplotlib.pyplot failed. No figures at all"
nikcleju@30 177 print "Try selecting a different backend"
nikcleju@30 178 doshowplot = False
nikcleju@30 179 dosaveplot = False
nikcleju@30 180
nikcleju@30 181 # Print summary of parameters
nikcleju@30 182 print "Parameters:"
nikcleju@30 183 if doparallel:
nikcleju@30 184 if ncpus is None:
nikcleju@30 185 print " Running in parallel with default threads using \"multiprocessing\" package"
nikcleju@30 186 else:
nikcleju@30 187 print " Running in parallel with",ncpus,"threads using \"multiprocessing\" package"
nikcleju@30 188 else:
nikcleju@30 189 print "Running single thread"
nikcleju@30 190 if doshowplot:
nikcleju@30 191 print " Showing figures"
nikcleju@30 192 else:
nikcleju@30 193 print " Not showing figures"
nikcleju@30 194 if dosaveplot:
nikcleju@30 195 print " Saving figures as "+saveplotbase+"* with extensions ",saveplotexts
nikcleju@30 196 else:
nikcleju@30 197 print " Not saving figures"
nikcleju@30 198 print " Running algorithms",[algotuple[1] for algotuple in algosN],[algotuple[1] for algotuple in algosL]
nikcleju@29 199
nikcleju@29 200 nalgosN = len(algosN)
nikcleju@29 201 nalgosL = len(algosL)
nikcleju@29 202
nikcleju@22 203 meanmatrix = dict()
nikcleju@22 204 for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 205 meanmatrix[algo[1]] = np.zeros((rhos.size, deltas.size))
nikcleju@22 206 for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 207 meanmatrix[algo[1]] = np.zeros((lambdas.size, rhos.size, deltas.size))
nikcleju@22 208
nikcleju@29 209 # Prepare parameters
nikcleju@29 210 jobparams = []
nikcleju@30 211 print " (delta, rho) pairs to be run:"
nikcleju@22 212 for idelta,delta in zip(np.arange(deltas.size),deltas):
nikcleju@22 213 for irho,rho in zip(np.arange(rhos.size),rhos):
nikcleju@22 214
nikcleju@22 215 # Generate data and operator
nikcleju@29 216 Omega,x0,y,M,realnoise = generateData(d,sigma,delta,rho,numvects,SNRdb)
nikcleju@22 217
nikcleju@29 218 #Save the parameters, and run after
nikcleju@30 219 print " delta = ",delta," rho = ",rho
nikcleju@29 220 jobparams.append((algosN,algosL, Omega,y,lambdas,realnoise,M,x0))
nikcleju@29 221
nikcleju@30 222 print "End of parameters"
nikcleju@30 223
nikcleju@29 224 # Run
nikcleju@29 225 jobresults = []
nikcleju@29 226 if doparallel:
nikcleju@29 227 pool = Pool(4)
nikcleju@29 228 jobresults = pool.map(run_once_tuple,jobparams)
nikcleju@29 229 else:
nikcleju@29 230 for jobparam in jobparams:
nikcleju@29 231 jobresults.append(run_once(algosN,algosL,Omega,y,lambdas,realnoise,M,x0))
nikcleju@29 232
nikcleju@29 233 # Read results
nikcleju@29 234 idx = 0
nikcleju@29 235 for idelta,delta in zip(np.arange(deltas.size),deltas):
nikcleju@29 236 for irho,rho in zip(np.arange(rhos.size),rhos):
nikcleju@29 237 mrelerrN,mrelerrL = jobresults[idx]
nikcleju@29 238 idx = idx+1
nikcleju@22 239 for algotuple in algosN:
nikcleju@22 240 meanmatrix[algotuple[1]][irho,idelta] = 1 - mrelerrN[algotuple[1]]
nikcleju@22 241 if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]):
nikcleju@22 242 meanmatrix[algotuple[1]][irho,idelta] = 0
nikcleju@22 243 for algotuple in algosL:
nikcleju@22 244 for ilbd in np.arange(lambdas.size):
nikcleju@22 245 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 1 - mrelerrL[algotuple[1]][ilbd]
nikcleju@22 246 if meanmatrix[algotuple[1]][ilbd,irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][ilbd,irho,idelta]):
nikcleju@22 247 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 0
nikcleju@22 248
nikcleju@22 249 # # Prepare matrices to show
nikcleju@22 250 # showmats = dict()
nikcleju@22 251 # for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 252 # showmats[algo[1]] = np.zeros(rhos.size, deltas.size)
nikcleju@22 253 # for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 254 # showmats[algo[1]] = np.zeros(lambdas.size, rhos.size, deltas.size)
nikcleju@22 255
nikcleju@22 256 # Save
nikcleju@29 257 if dosavedata:
nikcleju@29 258 tosave = dict()
nikcleju@29 259 tosave['meanmatrix'] = meanmatrix
nikcleju@29 260 tosave['d'] = d
nikcleju@29 261 tosave['sigma'] = sigma
nikcleju@29 262 tosave['deltas'] = deltas
nikcleju@29 263 tosave['rhos'] = rhos
nikcleju@29 264 tosave['numvects'] = numvects
nikcleju@29 265 tosave['SNRdb'] = SNRdb
nikcleju@29 266 tosave['lambdas'] = lambdas
nikcleju@29 267 try:
nikcleju@29 268 scipy.io.savemat(savedataname, tosave)
nikcleju@29 269 except:
nikcleju@29 270 print "Save error"
nikcleju@22 271 # Show
nikcleju@29 272 if doshowplot or dosaveplot:
nikcleju@27 273 for algotuple in algosN:
nikcleju@29 274 algoname = algotuple[1]
nikcleju@27 275 plt.figure()
nikcleju@29 276 plt.imshow(meanmatrix[algoname], cmap=cm.gray, interpolation='nearest',origin='lower')
nikcleju@29 277 if dosaveplot:
nikcleju@29 278 for ext in saveplotexts:
nikcleju@29 279 plt.savefig(saveplotbase + algoname + '.' + ext)
nikcleju@27 280 for algotuple in algosL:
nikcleju@29 281 algoname = algotuple[1]
nikcleju@27 282 for ilbd in np.arange(lambdas.size):
nikcleju@27 283 plt.figure()
nikcleju@29 284 plt.imshow(meanmatrix[algoname][ilbd], cmap=cm.gray, interpolation='nearest',origin='lower')
nikcleju@29 285 if dosaveplot:
nikcleju@29 286 for ext in saveplotexts:
nikcleju@30 287 plt.savefig(saveplotbase + algoname + ('_lbd%.0e' % lambdas[ilbd]) + '.' + ext)
nikcleju@29 288 if doshowplot:
nikcleju@29 289 plt.show()
nikcleju@29 290
nikcleju@22 291 print "Finished."
nikcleju@22 292
nikcleju@29 293 def run_once_tuple(t):
nikcleju@29 294 return run_once(*t)
nikcleju@10 295
nikcleju@29 296 def run_once(algosN,algosL,Omega,y,lambdas,realnoise,M,x0):
nikcleju@22 297
nikcleju@22 298 d = Omega.shape[1]
nikcleju@22 299
nikcleju@22 300 nalgosN = len(algosN)
nikcleju@22 301 nalgosL = len(algosL)
nikcleju@10 302
nikcleju@19 303 xrec = dict()
nikcleju@19 304 err = dict()
nikcleju@19 305 relerr = dict()
nikcleju@22 306
nikcleju@22 307 # Prepare storage variables for algorithms non-Lambda
nikcleju@22 308 for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 309 xrec[algo[1]] = np.zeros((d, y.shape[1]))
nikcleju@22 310 err[algo[1]] = np.zeros(y.shape[1])
nikcleju@22 311 relerr[algo[1]] = np.zeros(y.shape[1])
nikcleju@22 312 # Prepare storage variables for algorithms with Lambda
nikcleju@22 313 for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 314 xrec[algo[1]] = np.zeros((lambdas.size, d, y.shape[1]))
nikcleju@22 315 err[algo[1]] = np.zeros((lambdas.size, y.shape[1]))
nikcleju@22 316 relerr[algo[1]] = np.zeros((lambdas.size, y.shape[1]))
nikcleju@19 317
nikcleju@22 318 # Run algorithms non-Lambda
nikcleju@22 319 for iy in np.arange(y.shape[1]):
nikcleju@22 320 for algofunc,strname in algosN:
nikcleju@22 321 epsilon = 1.1 * np.linalg.norm(realnoise[:,iy])
nikcleju@22 322 xrec[strname][:,iy] = algofunc(y[:,iy],M,Omega,epsilon)
nikcleju@22 323 err[strname][iy] = np.linalg.norm(x0[:,iy] - xrec[strname][:,iy])
nikcleju@22 324 relerr[strname][iy] = err[strname][iy] / np.linalg.norm(x0[:,iy])
nikcleju@22 325 for algotuple in algosN:
nikcleju@22 326 print algotuple[1],' : avg relative error = ',np.mean(relerr[strname])
nikcleju@22 327
nikcleju@22 328 # Run algorithms with Lambda
nikcleju@19 329 for ilbd,lbd in zip(np.arange(lambdas.size),lambdas):
nikcleju@19 330 for iy in np.arange(y.shape[1]):
nikcleju@22 331 D = np.linalg.pinv(Omega)
nikcleju@22 332 U,S,Vt = np.linalg.svd(D)
nikcleju@22 333 for algofunc,strname in algosL:
nikcleju@19 334 epsilon = 1.1 * np.linalg.norm(realnoise[:,iy])
nikcleju@22 335 gamma = algofunc(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd)
nikcleju@22 336 xrec[strname][ilbd,:,iy] = np.dot(D,gamma)
nikcleju@19 337 err[strname][ilbd,iy] = np.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy])
nikcleju@19 338 relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / np.linalg.norm(x0[:,iy])
nikcleju@19 339 print 'Lambda = ',lbd,' :'
nikcleju@22 340 for algotuple in algosL:
nikcleju@22 341 print ' ',algotuple[1],' : avg relative error = ',np.mean(relerr[strname][ilbd,:])
nikcleju@10 342
nikcleju@22 343 # Prepare results
nikcleju@22 344 mrelerrN = dict()
nikcleju@22 345 for algotuple in algosN:
nikcleju@22 346 mrelerrN[algotuple[1]] = np.mean(relerr[algotuple[1]])
nikcleju@22 347 mrelerrL = dict()
nikcleju@22 348 for algotuple in algosL:
nikcleju@22 349 mrelerrL[algotuple[1]] = np.mean(relerr[algotuple[1]],1)
nikcleju@22 350
nikcleju@22 351 return mrelerrN,mrelerrL
nikcleju@29 352
nikcleju@29 353 def generateData(d,sigma,delta,rho,numvects,SNRdb):
nikcleju@29 354
nikcleju@29 355 # Process parameters
nikcleju@29 356 noiselevel = 1.0 / (10.0**(SNRdb/10.0));
nikcleju@29 357 p = round(sigma*d);
nikcleju@29 358 m = round(delta*d);
nikcleju@29 359 l = round(d - rho*m);
nikcleju@29 360
nikcleju@29 361 # Generate Omega and data based on parameters
nikcleju@29 362 Omega = pyCSalgos.GAP.GAP.Generate_Analysis_Operator(d, p);
nikcleju@29 363 # Optionally make Omega more coherent
nikcleju@29 364 U,S,Vt = np.linalg.svd(Omega);
nikcleju@29 365 Sdnew = S * (1+np.arange(S.size)) # Make D coherent, not Omega!
nikcleju@29 366 Snew = np.vstack((np.diag(Sdnew), np.zeros((Omega.shape[0] - Omega.shape[1], Omega.shape[1]))))
nikcleju@29 367 Omega = np.dot(U , np.dot(Snew,Vt))
nikcleju@29 368
nikcleju@29 369 # Generate data
nikcleju@29 370 x0,y,M,Lambda,realnoise = pyCSalgos.GAP.GAP.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0');
nikcleju@29 371
nikcleju@29 372 return Omega,x0,y,M,realnoise
nikcleju@22 373
nikcleju@19 374 # Script main
nikcleju@19 375 if __name__ == "__main__":
nikcleju@27 376 #import cProfile
nikcleju@27 377 #cProfile.run('mainrun()', 'profile')
nikcleju@29 378 run()