annotate scripts/ABSapprox.py @ 29:bc2a96a03b0a

2011 nov 10. Rewrote a single ABSapprox file, reorganized functions
author nikcleju
date Thu, 10 Nov 2011 18:49:38 +0000
parents 1a88766113a9
children 5f46ff51c7ff
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@10 15
nikcleju@29 16 #==========================
nikcleju@29 17 # Algorithm functions
nikcleju@29 18 #==========================
nikcleju@22 19 def run_gap(y,M,Omega,epsilon):
nikcleju@19 20 gapparams = {"num_iteration" : 1000,\
nikcleju@19 21 "greedy_level" : 0.9,\
nikcleju@19 22 "stopping_coefficient_size" : 1e-4,\
nikcleju@19 23 "l2solver" : 'pseudoinverse',\
nikcleju@19 24 "noise_level": epsilon}
nikcleju@22 25 return pyCSalgos.GAP.GAP.GAP(y,M,M.T,Omega,Omega.T,gapparams,np.zeros(Omega.shape[1]))[0]
nikcleju@29 26
nikcleju@22 27 def run_sl0(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@19 28
nikcleju@19 29 N,n = Omega.shape
nikcleju@22 30 #D = np.linalg.pinv(Omega)
nikcleju@22 31 #U,S,Vt = np.linalg.svd(D)
nikcleju@19 32 aggDupper = np.dot(M,D)
nikcleju@19 33 aggDlower = Vt[-(N-n):,:]
nikcleju@19 34 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@19 35 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@19 36
nikcleju@22 37 sigmamin = 0.001
nikcleju@22 38 sigma_decrease_factor = 0.5
nikcleju@20 39 mu_0 = 2
nikcleju@20 40 L = 10
nikcleju@22 41 return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
nikcleju@10 42
nikcleju@27 43 def run_bp(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@27 44
nikcleju@27 45 N,n = Omega.shape
nikcleju@27 46 #D = np.linalg.pinv(Omega)
nikcleju@27 47 #U,S,Vt = np.linalg.svd(D)
nikcleju@27 48 aggDupper = np.dot(M,D)
nikcleju@27 49 aggDlower = Vt[-(N-n):,:]
nikcleju@27 50 aggD = np.concatenate((aggDupper, lbd * aggDlower))
nikcleju@27 51 aggy = np.concatenate((y, np.zeros(N-n)))
nikcleju@27 52
nikcleju@27 53 sigmamin = 0.001
nikcleju@27 54 sigma_decrease_factor = 0.5
nikcleju@27 55 mu_0 = 2
nikcleju@27 56 L = 10
nikcleju@27 57 return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
nikcleju@27 58
nikcleju@29 59 #==========================
nikcleju@29 60 # Define tuples (algorithm function, name)
nikcleju@29 61 #==========================
nikcleju@22 62 gap = (run_gap, 'GAP')
nikcleju@22 63 sl0 = (run_sl0, 'SL0_approx')
nikcleju@29 64 bp = (run_bp, 'BP')
nikcleju@10 65
nikcleju@22 66 # Define which algorithms to run
nikcleju@22 67 # 1. Algorithms not depending on lambda
nikcleju@22 68 algosN = gap, # tuple
nikcleju@22 69 # 2. Algorithms depending on lambda (our ABS approach)
nikcleju@22 70 algosL = sl0, # tuple
nikcleju@29 71
nikcleju@29 72 #==========================
nikcleju@29 73 # Interface functions
nikcleju@29 74 #==========================
nikcleju@29 75 def run_multiproc(ncpus=None):
nikcleju@29 76 d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname = standard_params()
nikcleju@29 77 run_multi(algosN, algosL, d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata=dosavedata,savedataname=savedataname,\
nikcleju@29 78 doparallel=True, ncpus=ncpus)
nikcleju@22 79
nikcleju@29 80 def run():
nikcleju@29 81 d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname = standard_params()
nikcleju@29 82 run_multi(algosN, algosL, d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata=dosavedata,savedataname=savedataname,\
nikcleju@29 83 doparallel=False)
nikcleju@19 84
nikcleju@29 85 def standard_params():
nikcleju@29 86 #Set up standard experiment parameters
nikcleju@25 87 d = 50.0;
nikcleju@22 88 sigma = 2.0
nikcleju@27 89 #deltas = np.arange(0.05,1.,0.05)
nikcleju@27 90 #rhos = np.arange(0.05,1.,0.05)
nikcleju@27 91 deltas = np.array([0.05, 0.45, 0.95])
nikcleju@27 92 rhos = np.array([0.05, 0.45, 0.95])
nikcleju@22 93 #deltas = np.array([0.05])
nikcleju@22 94 #rhos = np.array([0.05])
nikcleju@22 95 #delta = 0.8;
nikcleju@22 96 #rho = 0.15;
nikcleju@27 97 numvects = 100; # Number of vectors to generate
nikcleju@20 98 SNRdb = 20.; # This is norm(signal)/norm(noise), so power, not energy
nikcleju@22 99 # Values for lambda
nikcleju@22 100 #lambdas = [0 10.^linspace(-5, 4, 10)];
nikcleju@25 101 #lambdas = np.concatenate((np.array([0]), 10**np.linspace(-5, 4, 10)))
nikcleju@25 102 lambdas = np.array([0., 0.0001, 0.01, 1, 100, 10000])
nikcleju@29 103
nikcleju@29 104 dosavedata = True
nikcleju@29 105 savedataname = 'ABSapprox.mat'
nikcleju@29 106
nikcleju@29 107
nikcleju@29 108 return d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname
nikcleju@29 109
nikcleju@29 110 #==========================
nikcleju@29 111 # Main functions
nikcleju@29 112 #==========================
nikcleju@29 113 def run_multi(algosN, algosL, d, sigma, deltas, rhos, lambdas, numvects, SNRdb,
nikcleju@29 114 doparallel=False, ncpus=None,\
nikcleju@29 115 doshowplot=False, dosaveplot=False, saveplotbase=None, saveplotexts=None,\
nikcleju@29 116 dosavedata=False, savedataname=None):
nikcleju@29 117
nikcleju@29 118 if doparallel:
nikcleju@29 119 from multiprocessing import Pool
nikcleju@29 120
nikcleju@29 121 # TODO: load different engine for matplotlib that allows saving without showing
nikcleju@29 122 try:
nikcleju@29 123 import matplotlib.pyplot as plt
nikcleju@29 124 except:
nikcleju@29 125 dosaveplot = False
nikcleju@29 126 doshowplot = False
nikcleju@29 127 if dosaveplot and doshowplot:
nikcleju@29 128 import matplotlib.cm as cm
nikcleju@29 129
nikcleju@29 130 nalgosN = len(algosN)
nikcleju@29 131 nalgosL = len(algosL)
nikcleju@29 132
nikcleju@22 133 meanmatrix = dict()
nikcleju@22 134 for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 135 meanmatrix[algo[1]] = np.zeros((rhos.size, deltas.size))
nikcleju@22 136 for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 137 meanmatrix[algo[1]] = np.zeros((lambdas.size, rhos.size, deltas.size))
nikcleju@22 138
nikcleju@29 139 # Prepare parameters
nikcleju@29 140 jobparams = []
nikcleju@22 141 for idelta,delta in zip(np.arange(deltas.size),deltas):
nikcleju@22 142 for irho,rho in zip(np.arange(rhos.size),rhos):
nikcleju@22 143
nikcleju@22 144 # Generate data and operator
nikcleju@29 145 Omega,x0,y,M,realnoise = generateData(d,sigma,delta,rho,numvects,SNRdb)
nikcleju@22 146
nikcleju@29 147 #Save the parameters, and run after
nikcleju@24 148 print "***** delta = ",delta," rho = ",rho
nikcleju@29 149 jobparams.append((algosN,algosL, Omega,y,lambdas,realnoise,M,x0))
nikcleju@29 150
nikcleju@29 151 # Run
nikcleju@29 152 jobresults = []
nikcleju@29 153 if doparallel:
nikcleju@29 154 pool = Pool(4)
nikcleju@29 155 jobresults = pool.map(run_once_tuple,jobparams)
nikcleju@29 156 else:
nikcleju@29 157 for jobparam in jobparams:
nikcleju@29 158 jobresults.append(run_once(algosN,algosL,Omega,y,lambdas,realnoise,M,x0))
nikcleju@29 159
nikcleju@29 160 # Read results
nikcleju@29 161 idx = 0
nikcleju@29 162 for idelta,delta in zip(np.arange(deltas.size),deltas):
nikcleju@29 163 for irho,rho in zip(np.arange(rhos.size),rhos):
nikcleju@29 164 mrelerrN,mrelerrL = jobresults[idx]
nikcleju@29 165 idx = idx+1
nikcleju@22 166 for algotuple in algosN:
nikcleju@22 167 meanmatrix[algotuple[1]][irho,idelta] = 1 - mrelerrN[algotuple[1]]
nikcleju@22 168 if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]):
nikcleju@22 169 meanmatrix[algotuple[1]][irho,idelta] = 0
nikcleju@22 170 for algotuple in algosL:
nikcleju@22 171 for ilbd in np.arange(lambdas.size):
nikcleju@22 172 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 1 - mrelerrL[algotuple[1]][ilbd]
nikcleju@22 173 if meanmatrix[algotuple[1]][ilbd,irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][ilbd,irho,idelta]):
nikcleju@22 174 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 0
nikcleju@22 175
nikcleju@22 176 # # Prepare matrices to show
nikcleju@22 177 # showmats = dict()
nikcleju@22 178 # for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 179 # showmats[algo[1]] = np.zeros(rhos.size, deltas.size)
nikcleju@22 180 # for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 181 # showmats[algo[1]] = np.zeros(lambdas.size, rhos.size, deltas.size)
nikcleju@22 182
nikcleju@22 183 # Save
nikcleju@29 184 if dosavedata:
nikcleju@29 185 tosave = dict()
nikcleju@29 186 tosave['meanmatrix'] = meanmatrix
nikcleju@29 187 tosave['d'] = d
nikcleju@29 188 tosave['sigma'] = sigma
nikcleju@29 189 tosave['deltas'] = deltas
nikcleju@29 190 tosave['rhos'] = rhos
nikcleju@29 191 tosave['numvects'] = numvects
nikcleju@29 192 tosave['SNRdb'] = SNRdb
nikcleju@29 193 tosave['lambdas'] = lambdas
nikcleju@29 194 try:
nikcleju@29 195 scipy.io.savemat(savedataname, tosave)
nikcleju@29 196 except:
nikcleju@29 197 print "Save error"
nikcleju@22 198 # Show
nikcleju@29 199 if doshowplot or dosaveplot:
nikcleju@27 200 for algotuple in algosN:
nikcleju@29 201 algoname = algotuple[1]
nikcleju@27 202 plt.figure()
nikcleju@29 203 plt.imshow(meanmatrix[algoname], cmap=cm.gray, interpolation='nearest',origin='lower')
nikcleju@29 204 if dosaveplot:
nikcleju@29 205 for ext in saveplotexts:
nikcleju@29 206 plt.savefig(saveplotbase + algoname + '.' + ext)
nikcleju@27 207 for algotuple in algosL:
nikcleju@29 208 algoname = algotuple[1]
nikcleju@27 209 for ilbd in np.arange(lambdas.size):
nikcleju@27 210 plt.figure()
nikcleju@29 211 plt.imshow(meanmatrix[algoname][ilbd], cmap=cm.gray, interpolation='nearest',origin='lower')
nikcleju@29 212 if dosaveplot:
nikcleju@29 213 for ext in saveplotexts:
nikcleju@29 214 plt.savefig(saveplotbase + algoname + lambdas[ilbd] + '.' + ext)
nikcleju@29 215 if doshowplot:
nikcleju@29 216 plt.show()
nikcleju@29 217
nikcleju@22 218 print "Finished."
nikcleju@22 219
nikcleju@29 220 def run_once_tuple(t):
nikcleju@29 221 return run_once(*t)
nikcleju@10 222
nikcleju@29 223 def run_once(algosN,algosL,Omega,y,lambdas,realnoise,M,x0):
nikcleju@22 224
nikcleju@22 225 d = Omega.shape[1]
nikcleju@22 226
nikcleju@22 227 nalgosN = len(algosN)
nikcleju@22 228 nalgosL = len(algosL)
nikcleju@10 229
nikcleju@19 230 xrec = dict()
nikcleju@19 231 err = dict()
nikcleju@19 232 relerr = dict()
nikcleju@22 233
nikcleju@22 234 # Prepare storage variables for algorithms non-Lambda
nikcleju@22 235 for i,algo in zip(np.arange(nalgosN),algosN):
nikcleju@22 236 xrec[algo[1]] = np.zeros((d, y.shape[1]))
nikcleju@22 237 err[algo[1]] = np.zeros(y.shape[1])
nikcleju@22 238 relerr[algo[1]] = np.zeros(y.shape[1])
nikcleju@22 239 # Prepare storage variables for algorithms with Lambda
nikcleju@22 240 for i,algo in zip(np.arange(nalgosL),algosL):
nikcleju@22 241 xrec[algo[1]] = np.zeros((lambdas.size, d, y.shape[1]))
nikcleju@22 242 err[algo[1]] = np.zeros((lambdas.size, y.shape[1]))
nikcleju@22 243 relerr[algo[1]] = np.zeros((lambdas.size, y.shape[1]))
nikcleju@19 244
nikcleju@22 245 # Run algorithms non-Lambda
nikcleju@22 246 for iy in np.arange(y.shape[1]):
nikcleju@22 247 for algofunc,strname in algosN:
nikcleju@22 248 epsilon = 1.1 * np.linalg.norm(realnoise[:,iy])
nikcleju@22 249 xrec[strname][:,iy] = algofunc(y[:,iy],M,Omega,epsilon)
nikcleju@22 250 err[strname][iy] = np.linalg.norm(x0[:,iy] - xrec[strname][:,iy])
nikcleju@22 251 relerr[strname][iy] = err[strname][iy] / np.linalg.norm(x0[:,iy])
nikcleju@22 252 for algotuple in algosN:
nikcleju@22 253 print algotuple[1],' : avg relative error = ',np.mean(relerr[strname])
nikcleju@22 254
nikcleju@22 255 # Run algorithms with Lambda
nikcleju@19 256 for ilbd,lbd in zip(np.arange(lambdas.size),lambdas):
nikcleju@19 257 for iy in np.arange(y.shape[1]):
nikcleju@22 258 D = np.linalg.pinv(Omega)
nikcleju@22 259 U,S,Vt = np.linalg.svd(D)
nikcleju@22 260 for algofunc,strname in algosL:
nikcleju@19 261 epsilon = 1.1 * np.linalg.norm(realnoise[:,iy])
nikcleju@22 262 gamma = algofunc(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd)
nikcleju@22 263 xrec[strname][ilbd,:,iy] = np.dot(D,gamma)
nikcleju@19 264 err[strname][ilbd,iy] = np.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy])
nikcleju@19 265 relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / np.linalg.norm(x0[:,iy])
nikcleju@19 266 print 'Lambda = ',lbd,' :'
nikcleju@22 267 for algotuple in algosL:
nikcleju@22 268 print ' ',algotuple[1],' : avg relative error = ',np.mean(relerr[strname][ilbd,:])
nikcleju@10 269
nikcleju@22 270 # Prepare results
nikcleju@22 271 mrelerrN = dict()
nikcleju@22 272 for algotuple in algosN:
nikcleju@22 273 mrelerrN[algotuple[1]] = np.mean(relerr[algotuple[1]])
nikcleju@22 274 mrelerrL = dict()
nikcleju@22 275 for algotuple in algosL:
nikcleju@22 276 mrelerrL[algotuple[1]] = np.mean(relerr[algotuple[1]],1)
nikcleju@22 277
nikcleju@22 278 return mrelerrN,mrelerrL
nikcleju@29 279
nikcleju@29 280 def generateData(d,sigma,delta,rho,numvects,SNRdb):
nikcleju@29 281
nikcleju@29 282 # Process parameters
nikcleju@29 283 noiselevel = 1.0 / (10.0**(SNRdb/10.0));
nikcleju@29 284 p = round(sigma*d);
nikcleju@29 285 m = round(delta*d);
nikcleju@29 286 l = round(d - rho*m);
nikcleju@29 287
nikcleju@29 288 # Generate Omega and data based on parameters
nikcleju@29 289 Omega = pyCSalgos.GAP.GAP.Generate_Analysis_Operator(d, p);
nikcleju@29 290 # Optionally make Omega more coherent
nikcleju@29 291 U,S,Vt = np.linalg.svd(Omega);
nikcleju@29 292 Sdnew = S * (1+np.arange(S.size)) # Make D coherent, not Omega!
nikcleju@29 293 Snew = np.vstack((np.diag(Sdnew), np.zeros((Omega.shape[0] - Omega.shape[1], Omega.shape[1]))))
nikcleju@29 294 Omega = np.dot(U , np.dot(Snew,Vt))
nikcleju@29 295
nikcleju@29 296 # Generate data
nikcleju@29 297 x0,y,M,Lambda,realnoise = pyCSalgos.GAP.GAP.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0');
nikcleju@29 298
nikcleju@29 299 return Omega,x0,y,M,realnoise
nikcleju@22 300
nikcleju@19 301 # Script main
nikcleju@19 302 if __name__ == "__main__":
nikcleju@27 303 #import cProfile
nikcleju@27 304 #cProfile.run('mainrun()', 'profile')
nikcleju@29 305 run()