annotate scripts/ABSapproxPP.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
rev   line source
nikcleju@22 1 # -*- coding: utf-8 -*-
nikcleju@22 2 """
nikcleju@22 3 Created on Sat Nov 05 18:08:40 2011
nikcleju@22 4
nikcleju@22 5 @author: Nic
nikcleju@22 6 """
nikcleju@22 7
nikcleju@27 8 import numpy
nikcleju@22 9 import scipy.io
nikcleju@22 10 import math
nikcleju@27 11 #import matplotlib.pyplot as plt
nikcleju@27 12 #import matplotlib.cm as cm
nikcleju@22 13 import pp
nikcleju@22 14 import pyCSalgos
nikcleju@22 15 import pyCSalgos.GAP.GAP
nikcleju@22 16 import pyCSalgos.SL0.SL0_approx
nikcleju@22 17
nikcleju@22 18 # Define functions that prepare arguments for each algorithm call
nikcleju@22 19 def run_gap(y,M,Omega,epsilon):
nikcleju@22 20 gapparams = {"num_iteration" : 1000,\
nikcleju@22 21 "greedy_level" : 0.9,\
nikcleju@22 22 "stopping_coefficient_size" : 1e-4,\
nikcleju@22 23 "l2solver" : 'pseudoinverse',\
nikcleju@22 24 "noise_level": epsilon}
nikcleju@27 25 return pyCSalgos.GAP.GAP.GAP(y,M,M.T,Omega,Omega.T,gapparams,numpy.zeros(Omega.shape[1]))[0]
nikcleju@22 26
nikcleju@22 27 def run_sl0(y,M,Omega,D,U,S,Vt,epsilon,lbd):
nikcleju@22 28
nikcleju@22 29 N,n = Omega.shape
nikcleju@27 30 #D = numpy.linalg.pinv(Omega)
nikcleju@27 31 #U,S,Vt = numpy.linalg.svd(D)
nikcleju@27 32 aggDupper = numpy.dot(M,D)
nikcleju@22 33 aggDlower = Vt[-(N-n):,:]
nikcleju@27 34 aggD = numpy.concatenate((aggDupper, lbd * aggDlower))
nikcleju@27 35 aggy = numpy.concatenate((y, numpy.zeros(N-n)))
nikcleju@22 36
nikcleju@22 37 sigmamin = 0.001
nikcleju@22 38 sigma_decrease_factor = 0.5
nikcleju@22 39 mu_0 = 2
nikcleju@22 40 L = 10
nikcleju@22 41 return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
nikcleju@22 42
nikcleju@22 43 # Define tuples (algorithm setup function, algorithm function, name)
nikcleju@22 44 gap = (run_gap, 'GAP')
nikcleju@22 45 sl0 = (run_sl0, 'SL0_approx')
nikcleju@22 46
nikcleju@22 47 # Define which algorithms to run
nikcleju@22 48 # 1. Algorithms not depending on lambda
nikcleju@22 49 algosN = gap, # tuple
nikcleju@22 50 # 2. Algorithms depending on lambda (our ABS approach)
nikcleju@22 51 algosL = sl0, # tuple
nikcleju@22 52
nikcleju@22 53 def mainrun():
nikcleju@22 54
nikcleju@22 55 nalgosN = len(algosN)
nikcleju@22 56 nalgosL = len(algosL)
nikcleju@22 57
nikcleju@22 58 #Set up experiment parameters
nikcleju@22 59 d = 50;
nikcleju@22 60 sigma = 2.0
nikcleju@27 61 #deltas = numpy.arange(0.05,0.95,0.05)
nikcleju@27 62 #rhos = numpy.arange(0.05,0.95,0.05)
nikcleju@27 63 deltas = numpy.array([0.05, 0.45, 0.95])
nikcleju@27 64 rhos = numpy.array([0.05, 0.45, 0.95])
nikcleju@27 65 #deltas = numpy.array([0.05])
nikcleju@27 66 #rhos = numpy.array([0.05])
nikcleju@22 67 #delta = 0.8;
nikcleju@22 68 #rho = 0.15;
nikcleju@22 69 numvects = 10; # Number of vectors to generate
nikcleju@22 70 SNRdb = 20.; # This is norm(signal)/norm(noise), so power, not energy
nikcleju@22 71 # Values for lambda
nikcleju@22 72 #lambdas = [0 10.^linspace(-5, 4, 10)];
nikcleju@27 73 lambdas = numpy.concatenate((numpy.array([0]), 10**numpy.linspace(-5, 4, 10)))
nikcleju@22 74
nikcleju@22 75 meanmatrix = dict()
nikcleju@27 76 for i,algo in zip(numpy.arange(nalgosN),algosN):
nikcleju@27 77 meanmatrix[algo[1]] = numpy.zeros((rhos.size, deltas.size))
nikcleju@27 78 for i,algo in zip(numpy.arange(nalgosL),algosL):
nikcleju@27 79 meanmatrix[algo[1]] = numpy.zeros((lambdas.size, rhos.size, deltas.size))
nikcleju@22 80
nikcleju@22 81 # PP: start job server
nikcleju@27 82 job_server = pp.Server(ncpus = 4)
nikcleju@22 83 idx = 0
nikcleju@22 84 jobparams = []
nikcleju@27 85 for idelta,delta in zip(numpy.arange(deltas.size),deltas):
nikcleju@27 86 for irho,rho in zip(numpy.arange(rhos.size),rhos):
nikcleju@22 87
nikcleju@22 88 # Generate data and operator
nikcleju@22 89 Omega,x0,y,M,realnoise = genData(d,sigma,delta,rho,numvects,SNRdb)
nikcleju@22 90
nikcleju@22 91 jobparams.append((algosN,algosL, Omega,y,lambdas,realnoise,M,x0))
nikcleju@22 92
nikcleju@22 93 idx = idx + 1
nikcleju@22 94
nikcleju@22 95 # Run algorithms
nikcleju@27 96 modules = ('numpy','pyCSalgos','pyCSalgos.GAP.GAP','pyCSalgos.SL0.SL0_approx')
nikcleju@27 97 depfuncs = ()
nikcleju@27 98 jobs = [job_server.submit(runonce, jobparam, (run_gap,run_sl0), modules, depfuncs) for jobparam in jobparams]
nikcleju@22 99 #funcarray[idelta,irho] = job_server.submit(runonce,(algosN,algosL, Omega,y,lambdas,realnoise,M,x0), (run_gap,run_sl0))
nikcleju@22 100 #mrelerrN,mrelerrL = runonce(algosN,algosL,Omega,y,lambdas,realnoise,M,x0)
nikcleju@22 101
nikcleju@22 102 # Get data from jobs
nikcleju@22 103 idx = 0
nikcleju@27 104 for idelta,delta in zip(numpy.arange(deltas.size),deltas):
nikcleju@27 105 for irho,rho in zip(numpy.arange(rhos.size),rhos):
nikcleju@27 106 print "***** delta = ",delta," rho = ",rho
nikcleju@22 107 mrelerrN,mrelerrL = jobs[idx]()
nikcleju@22 108 for algotuple in algosN:
nikcleju@22 109 meanmatrix[algotuple[1]][irho,idelta] = 1 - mrelerrN[algotuple[1]]
nikcleju@22 110 if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]):
nikcleju@22 111 meanmatrix[algotuple[1]][irho,idelta] = 0
nikcleju@22 112 for algotuple in algosL:
nikcleju@27 113 for ilbd in numpy.arange(lambdas.size):
nikcleju@22 114 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 1 - mrelerrL[algotuple[1]][ilbd]
nikcleju@22 115 if meanmatrix[algotuple[1]][ilbd,irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][ilbd,irho,idelta]):
nikcleju@22 116 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 0
nikcleju@22 117 idx = idx + 1
nikcleju@22 118
nikcleju@22 119 # # Prepare matrices to show
nikcleju@22 120 # showmats = dict()
nikcleju@27 121 # for i,algo in zip(numpy.arange(nalgosN),algosN):
nikcleju@27 122 # showmats[algo[1]] = numpy.zeros(rhos.size, deltas.size)
nikcleju@27 123 # for i,algo in zip(numpy.arange(nalgosL),algosL):
nikcleju@27 124 # showmats[algo[1]] = numpy.zeros(lambdas.size, rhos.size, deltas.size)
nikcleju@22 125
nikcleju@22 126 # Save
nikcleju@22 127 tosave = dict()
nikcleju@22 128 tosave['meanmatrix'] = meanmatrix
nikcleju@22 129 tosave['d'] = d
nikcleju@22 130 tosave['sigma'] = sigma
nikcleju@22 131 tosave['deltas'] = deltas
nikcleju@22 132 tosave['rhos'] = rhos
nikcleju@22 133 tosave['numvects'] = numvects
nikcleju@22 134 tosave['SNRdb'] = SNRdb
nikcleju@22 135 tosave['lambdas'] = lambdas
nikcleju@22 136 try:
nikcleju@22 137 scipy.io.savemat('ABSapprox.mat',tosave)
nikcleju@22 138 except TypeError:
nikcleju@22 139 print "Oops, Type Error"
nikcleju@22 140 raise
nikcleju@22 141 # Show
nikcleju@27 142 # for algotuple in algosN:
nikcleju@27 143 # plt.figure()
nikcleju@27 144 # plt.imshow(meanmatrix[algotuple[1]], cmap=cm.gray, interpolation='nearest')
nikcleju@27 145 # for algotuple in algosL:
nikcleju@27 146 # for ilbd in numpy.arange(lambdas.size):
nikcleju@27 147 # plt.figure()
nikcleju@27 148 # plt.imshow(meanmatrix[algotuple[1]][ilbd], cmap=cm.gray, interpolation='nearest')
nikcleju@27 149 # plt.show()
nikcleju@22 150 print "Finished."
nikcleju@22 151
nikcleju@22 152 def genData(d,sigma,delta,rho,numvects,SNRdb):
nikcleju@22 153
nikcleju@22 154 # Process parameters
nikcleju@22 155 noiselevel = 1.0 / (10.0**(SNRdb/10.0));
nikcleju@22 156 p = round(sigma*d);
nikcleju@22 157 m = round(delta*d);
nikcleju@22 158 l = round(d - rho*m);
nikcleju@22 159
nikcleju@22 160 # Generate Omega and data based on parameters
nikcleju@22 161 Omega = pyCSalgos.GAP.GAP.Generate_Analysis_Operator(d, p);
nikcleju@22 162 # Optionally make Omega more coherent
nikcleju@27 163 U,S,Vt = numpy.linalg.svd(Omega);
nikcleju@27 164 Sdnew = S * (1+numpy.arange(S.size)) # Make D coherent, not Omega!
nikcleju@27 165 Snew = numpy.vstack((numpy.diag(Sdnew), numpy.zeros((Omega.shape[0] - Omega.shape[1], Omega.shape[1]))))
nikcleju@27 166 Omega = numpy.dot(U , numpy.dot(Snew,Vt))
nikcleju@22 167
nikcleju@22 168 # Generate data
nikcleju@22 169 x0,y,M,Lambda,realnoise = pyCSalgos.GAP.GAP.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0');
nikcleju@22 170
nikcleju@22 171 return Omega,x0,y,M,realnoise
nikcleju@22 172
nikcleju@22 173 def runonce(algosN,algosL,Omega,y,lambdas,realnoise,M,x0):
nikcleju@22 174
nikcleju@22 175 d = Omega.shape[1]
nikcleju@22 176
nikcleju@22 177 nalgosN = len(algosN)
nikcleju@22 178 nalgosL = len(algosL)
nikcleju@22 179
nikcleju@22 180 xrec = dict()
nikcleju@22 181 err = dict()
nikcleju@22 182 relerr = dict()
nikcleju@22 183
nikcleju@22 184 # Prepare storage variables for algorithms non-Lambda
nikcleju@27 185 for i,algo in zip(numpy.arange(nalgosN),algosN):
nikcleju@27 186 xrec[algo[1]] = numpy.zeros((d, y.shape[1]))
nikcleju@27 187 err[algo[1]] = numpy.zeros(y.shape[1])
nikcleju@27 188 relerr[algo[1]] = numpy.zeros(y.shape[1])
nikcleju@22 189 # Prepare storage variables for algorithms with Lambda
nikcleju@27 190 for i,algo in zip(numpy.arange(nalgosL),algosL):
nikcleju@27 191 xrec[algo[1]] = numpy.zeros((lambdas.size, d, y.shape[1]))
nikcleju@27 192 err[algo[1]] = numpy.zeros((lambdas.size, y.shape[1]))
nikcleju@27 193 relerr[algo[1]] = numpy.zeros((lambdas.size, y.shape[1]))
nikcleju@22 194
nikcleju@22 195 # Run algorithms non-Lambda
nikcleju@27 196 for iy in numpy.arange(y.shape[1]):
nikcleju@22 197 for algofunc,strname in algosN:
nikcleju@27 198 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
nikcleju@22 199 xrec[strname][:,iy] = algofunc(y[:,iy],M,Omega,epsilon)
nikcleju@27 200 err[strname][iy] = numpy.linalg.norm(x0[:,iy] - xrec[strname][:,iy])
nikcleju@27 201 relerr[strname][iy] = err[strname][iy] / numpy.linalg.norm(x0[:,iy])
nikcleju@22 202 for algotuple in algosN:
nikcleju@27 203 print algotuple[1],' : avg relative error = ',numpy.mean(relerr[strname])
nikcleju@22 204
nikcleju@22 205 # Run algorithms with Lambda
nikcleju@27 206 for ilbd,lbd in zip(numpy.arange(lambdas.size),lambdas):
nikcleju@27 207 for iy in numpy.arange(y.shape[1]):
nikcleju@27 208 D = numpy.linalg.pinv(Omega)
nikcleju@27 209 U,S,Vt = numpy.linalg.svd(D)
nikcleju@22 210 for algofunc,strname in algosL:
nikcleju@27 211 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
nikcleju@22 212 gamma = algofunc(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd)
nikcleju@27 213 xrec[strname][ilbd,:,iy] = numpy.dot(D,gamma)
nikcleju@27 214 err[strname][ilbd,iy] = numpy.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy])
nikcleju@27 215 relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / numpy.linalg.norm(x0[:,iy])
nikcleju@22 216 print 'Lambda = ',lbd,' :'
nikcleju@22 217 for algotuple in algosL:
nikcleju@27 218 print ' ',algotuple[1],' : avg relative error = ',numpy.mean(relerr[strname][ilbd,:])
nikcleju@22 219
nikcleju@22 220 # Prepare results
nikcleju@22 221 mrelerrN = dict()
nikcleju@22 222 for algotuple in algosN:
nikcleju@27 223 mrelerrN[algotuple[1]] = numpy.mean(relerr[algotuple[1]])
nikcleju@22 224 mrelerrL = dict()
nikcleju@22 225 for algotuple in algosL:
nikcleju@27 226 mrelerrL[algotuple[1]] = numpy.mean(relerr[algotuple[1]],1)
nikcleju@22 227
nikcleju@22 228 return mrelerrN,mrelerrL
nikcleju@22 229
nikcleju@22 230 # Script main
nikcleju@22 231 if __name__ == "__main__":
nikcleju@22 232 mainrun()