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