nikcleju@15
|
1 # -*- coding: utf-8 -*-
|
nikcleju@15
|
2 """
|
nikcleju@17
|
3 Trying to write a common framework for simulations
|
nikcleju@17
|
4 Not finished yet, better be ignored
|
nikcleju@15
|
5
|
nikcleju@15
|
6 @author: Nic
|
nikcleju@15
|
7 """
|
nikcleju@15
|
8
|
nikcleju@15
|
9 import numpy
|
nikcleju@15
|
10 import scipy.io
|
nikcleju@15
|
11 import math
|
nikcleju@15
|
12 import os
|
nikcleju@15
|
13 import time
|
nikcleju@15
|
14
|
nikcleju@15
|
15 import multiprocessing
|
nikcleju@15
|
16 import sys
|
nikcleju@15
|
17 currmodule = sys.modules[__name__]
|
nikcleju@15
|
18 # Lock for printing in a thread-safe way
|
nikcleju@15
|
19 printLock = None
|
nikcleju@15
|
20
|
nikcleju@15
|
21 import stdparams_exact
|
nikcleju@16
|
22 import stdparams_approx
|
nikcleju@15
|
23 import AnalysisGenerate
|
nikcleju@15
|
24
|
nikcleju@15
|
25 # For exceptions
|
nikcleju@15
|
26 import pyCSalgos.BP.l1eq_pd
|
nikcleju@15
|
27 import pyCSalgos.NESTA.NESTA
|
nikcleju@15
|
28
|
nikcleju@15
|
29 class RunBatch():
|
nikcleju@15
|
30 """
|
nikcleju@15
|
31 Class to run batch
|
nikcleju@15
|
32 """
|
nikcleju@15
|
33
|
nikcleju@16
|
34 def __init__(self, paramfunc, immedResultsFunc, processResultsFunc):
|
nikcleju@15
|
35 self.paramfunc = paramfunc
|
nikcleju@16
|
36 self.immedResultsFunc = immedResultsFunc
|
nikcleju@16
|
37 self.processResultsFunc = processResultsFunc
|
nikcleju@15
|
38
|
nikcleju@15
|
39 def initProcess(self, share, njobs, printLock):
|
nikcleju@15
|
40 """
|
nikcleju@15
|
41 Pool initializer function (multiprocessing)
|
nikcleju@15
|
42 Needed to pass the shared variable to the worker processes
|
nikcleju@15
|
43 The variables must be global in the module in order to be seen later in run_once_tuple()
|
nikcleju@15
|
44 see http://stackoverflow.com/questions/1675766/how-to-combine-pool-map-with-array-shared-memory-in-python-multiprocessing
|
nikcleju@15
|
45 """
|
nikcleju@15
|
46 currmodule = sys.modules[__name__]
|
nikcleju@15
|
47 currmodule.proccount = share
|
nikcleju@15
|
48 currmodule.njobs = njobs
|
nikcleju@15
|
49 currmodule._printLock = printLock
|
nikcleju@15
|
50
|
nikcleju@16
|
51 def run(self, globalparams):
|
nikcleju@15
|
52
|
nikcleju@15
|
53 print "This is RunBatch.run() by Nic"
|
nikcleju@15
|
54
|
nikcleju@16
|
55 ncpus = globalparams['ncpus']
|
nikcleju@16
|
56 savedataname = globalparams['savedataname']
|
nikcleju@15
|
57
|
nikcleju@15
|
58 if ncpus is None:
|
nikcleju@15
|
59 print " Running in parallel with default",multiprocessing.cpu_count(),"threads using \"multiprocessing\" package"
|
nikcleju@15
|
60 if multiprocessing.cpu_count() == 1:
|
nikcleju@15
|
61 doparallel = False
|
nikcleju@15
|
62 else:
|
nikcleju@15
|
63 doparallel = True
|
nikcleju@15
|
64 elif ncpus > 1:
|
nikcleju@15
|
65 print " Running in parallel with",ncpus,"threads using \"multiprocessing\" package"
|
nikcleju@15
|
66 doparallel = True
|
nikcleju@15
|
67 elif ncpus == 1:
|
nikcleju@15
|
68 print "Running single thread"
|
nikcleju@15
|
69 doparallel = False
|
nikcleju@15
|
70 else:
|
nikcleju@15
|
71 print "Wrong number of threads, exiting"
|
nikcleju@15
|
72 return
|
nikcleju@15
|
73
|
nikcleju@15
|
74 # Prepare parameters
|
nikcleju@16
|
75 #taskparams = generateTaskParams(params)
|
nikcleju@16
|
76 taskparams, refparams = self.paramfunc(globalparams)
|
nikcleju@15
|
77
|
nikcleju@15
|
78 # Store global variables
|
nikcleju@15
|
79 currmodule.ntasks = len(taskparams)
|
nikcleju@15
|
80
|
nikcleju@15
|
81 # Run
|
nikcleju@15
|
82 taskresults = []
|
nikcleju@15
|
83 if doparallel:
|
nikcleju@15
|
84 currmodule.printLock = multiprocessing.Lock()
|
nikcleju@15
|
85 pool = multiprocessing.Pool(ncpus,initializer=initProcess,initargs=(currmodule.proccount,currmodule.ntasks,currmodule.printLock))
|
nikcleju@16
|
86 taskresults = pool.map(self.run_once_tuple, globalparams,taskparams)
|
nikcleju@15
|
87 else:
|
nikcleju@16
|
88 for taskparam,refparam in zip(taskparams, refparams):
|
nikcleju@16
|
89 #taskresults.append(self.run_once_tuple(globalparams,taskparam))
|
nikcleju@16
|
90 taskresults.append(self.run_once(globalparams,taskparam,refparam))
|
nikcleju@15
|
91
|
nikcleju@15
|
92 # Process results
|
nikcleju@15
|
93 procresults = processResults(params, taskresults)
|
nikcleju@16
|
94 #procresults = []
|
nikcleju@16
|
95 #for taskresult in taskresults
|
nikcleju@16
|
96 # procresults.append(self.processResultsFunc(globalparams, taskresult))
|
nikcleju@15
|
97
|
nikcleju@15
|
98 # Save
|
nikcleju@16
|
99 saveSim(globalparams, procresults)
|
nikcleju@15
|
100
|
nikcleju@15
|
101 print "Finished."
|
nikcleju@15
|
102
|
nikcleju@16
|
103 def run_once_tuple(self,globalparams,taskparam):
|
nikcleju@16
|
104 results = self.run_once(*t)
|
nikcleju@15
|
105 import sys
|
nikcleju@15
|
106 currmodule = sys.modules[__name__]
|
nikcleju@15
|
107 currmodule.proccount.value = currmodule.proccount.value + 1
|
nikcleju@15
|
108 print "================================"
|
nikcleju@15
|
109 print "Finished task",currmodule.proccount.value,"of",currmodule.ntasks
|
nikcleju@15
|
110 print "================================"
|
nikcleju@16
|
111 return results
|
nikcleju@16
|
112
|
nikcleju@16
|
113 def run_once(self, globalparams, algoparams, refparam):
|
nikcleju@16
|
114
|
nikcleju@16
|
115 d = globalparams['d']
|
nikcleju@16
|
116
|
nikcleju@16
|
117 #xrec = dict()
|
nikcleju@16
|
118 #err = dict()
|
nikcleju@16
|
119 #relerr = dict()
|
nikcleju@16
|
120 #elapsed = dict()
|
nikcleju@16
|
121
|
nikcleju@16
|
122 # Prepare storage variables for algorithms non-Lambda
|
nikcleju@16
|
123 #for algo in algosN:
|
nikcleju@16
|
124 # xrec[algo[1]] = numpy.zeros((d, y.shape[1]))
|
nikcleju@16
|
125 # err[algo[1]] = numpy.zeros(y.shape[1])
|
nikcleju@16
|
126 # relerr[algo[1]] = numpy.zeros(y.shape[1])
|
nikcleju@16
|
127 # elapsed[algo[1]] = 0
|
nikcleju@16
|
128 # Prepare storage variables for algorithms with Lambda
|
nikcleju@16
|
129 #for algo in algosL:
|
nikcleju@16
|
130 # xrec[algo[1]] = numpy.zeros((lambdas.size, d, y.shape[1]))
|
nikcleju@16
|
131 # err[algo[1]] = numpy.zeros((lambdas.size, y.shape[1]))
|
nikcleju@16
|
132 # relerr[algo[1]] = numpy.zeros((lambdas.size, y.shape[1]))
|
nikcleju@16
|
133 # elapsed[algo[1]] = numpy.zeros(lambdas.size)
|
nikcleju@16
|
134
|
nikcleju@16
|
135 taskresult = []
|
nikcleju@16
|
136 rawresults = None
|
nikcleju@16
|
137 for algoparam in algoparams:
|
nikcleju@16
|
138 try:
|
nikcleju@16
|
139 #timestart = time.time()
|
nikcleju@16
|
140 #xrec[strname][:,iy] = algoparams[0](*algoparams[1:])
|
nikcleju@16
|
141 rawresults = algoparam[0](*algoparam[1:])
|
nikcleju@16
|
142 #elapsed[strname] = elapsed[strname] + (time.time() - timestart)
|
nikcleju@16
|
143 except pyCSalgos.BP.l1qec.l1qecInputValueError as e:
|
nikcleju@16
|
144 print "Caught exception when running algorithm",strname," :",e.message
|
nikcleju@16
|
145 except pyCSalgos.NESTA.NESTA.NestaError as e:
|
nikcleju@16
|
146 #print "Caught exception when running algorithm",strname," :",e.message
|
nikcleju@16
|
147 print "Caught error! :",e.message
|
nikcleju@16
|
148 #err[strname][iy] = numpy.linalg.norm(x0[:,iy] - xrec[strname][:,iy])
|
nikcleju@16
|
149 #relerr[strname][iy] = err[strname][iy] / numpy.linalg.norm(x0[:,iy])
|
nikcleju@16
|
150 #taskresult.append(immediateProcessResults(rawresults))
|
nikcleju@16
|
151 taskresult.append(self.immedResultsFunc(rawresults, refparam))
|
nikcleju@16
|
152
|
nikcleju@16
|
153 return taskresult
|
nikcleju@16
|
154
|
nikcleju@16
|
155
|
nikcleju@16
|
156 # # Run algorithms with Lambda
|
nikcleju@16
|
157 # for ilbd,lbd in zip(numpy.arange(lambdas.size),lambdas):
|
nikcleju@16
|
158 # for iy in numpy.arange(y.shape[1]):
|
nikcleju@16
|
159 # D = numpy.linalg.pinv(Omega)
|
nikcleju@16
|
160 # #U,S,Vt = numpy.linalg.svd(D)
|
nikcleju@16
|
161 # for algofunc,strname in algosL:
|
nikcleju@16
|
162 # epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
|
nikcleju@16
|
163 # try:
|
nikcleju@16
|
164 # timestart = time.time()
|
nikcleju@16
|
165 # #gamma = algofunc(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd)
|
nikcleju@16
|
166 # gamma = algofunc(y[:,iy],M,Omega,epsilon,lbd)
|
nikcleju@16
|
167 # elapsed[strname][ilbd] = elapsed[strname][ilbd] + (time.time() - timestart)
|
nikcleju@16
|
168 # except pyCSalgos.BP.l1qc.l1qcInputValueError as e:
|
nikcleju@16
|
169 # print "Caught exception when running algorithm",strname," :",e.message
|
nikcleju@16
|
170 # xrec[strname][ilbd,:,iy] = numpy.dot(D,gamma)
|
nikcleju@16
|
171 # err[strname][ilbd,iy] = numpy.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy])
|
nikcleju@16
|
172 # relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / numpy.linalg.norm(x0[:,iy])
|
nikcleju@16
|
173 # print 'Lambda = ',lbd,' :'
|
nikcleju@16
|
174 # for algofunc,strname in algosL:
|
nikcleju@16
|
175 # print ' ',strname,' : avg relative error = ',numpy.mean(relerr[strname][ilbd,:])
|
nikcleju@16
|
176
|
nikcleju@16
|
177 # # Prepare results
|
nikcleju@16
|
178 # mrelerrN = dict()
|
nikcleju@16
|
179 # for algotuple in algosN:
|
nikcleju@16
|
180 # mrelerrN[algotuple[1]] = numpy.mean(relerr[algotuple[1]])
|
nikcleju@16
|
181 # mrelerrL = dict()
|
nikcleju@16
|
182 # for algotuple in algosL:
|
nikcleju@16
|
183 # mrelerrL[algotuple[1]] = numpy.mean(relerr[algotuple[1]],1)
|
nikcleju@16
|
184 #
|
nikcleju@16
|
185 # return mrelerrN,mrelerrL,elapsed
|
nikcleju@16
|
186
|
nikcleju@16
|
187
|
nikcleju@16
|
188
|
nikcleju@16
|
189 def generateTaskParams(globalparams):
|
nikcleju@16
|
190 """
|
nikcleju@16
|
191 Generate a list of task parameters
|
nikcleju@16
|
192 """
|
nikcleju@16
|
193 taskparams = []
|
nikcleju@16
|
194 SNRdb = globalparams['SNRdb']
|
nikcleju@16
|
195 sigma = globalparams['sigma']
|
nikcleju@16
|
196 d = globalparams['d']
|
nikcleju@16
|
197 deltas = globalparams['deltas']
|
nikcleju@16
|
198 rhos = globalparams['rhos']
|
nikcleju@16
|
199 numvects = globalparams['numvects']
|
nikcleju@16
|
200 algosN = globalparams['algosN']
|
nikcleju@16
|
201 algosL = globalparams['algosL']
|
nikcleju@16
|
202 lambdas = globalparams['lambdas']
|
nikcleju@16
|
203
|
nikcleju@16
|
204 # Process parameters
|
nikcleju@16
|
205 noiselevel = 1.0 / (10.0**(SNRdb/10.0));
|
nikcleju@16
|
206
|
nikcleju@16
|
207 for delta in deltas:
|
nikcleju@16
|
208 for rho in rhos:
|
nikcleju@16
|
209 p = round(sigma*d);
|
nikcleju@16
|
210 m = round(delta*d);
|
nikcleju@16
|
211 l = round(d - rho*m);
|
nikcleju@16
|
212
|
nikcleju@16
|
213 # Generate Omega and data based on parameters
|
nikcleju@16
|
214 Omega = AnalysisGenerate.Generate_Analysis_Operator(d, p);
|
nikcleju@16
|
215 D = numpy.linalg.pinv(Omega)
|
nikcleju@16
|
216
|
nikcleju@16
|
217 # Generate data
|
nikcleju@16
|
218 x0,y,M,Lambda,realnoise = AnalysisGenerate.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0')
|
nikcleju@16
|
219
|
nikcleju@16
|
220 boxparams = []
|
nikcleju@16
|
221 refparams = []
|
nikcleju@16
|
222 # Prepare algos and params to run
|
nikcleju@16
|
223 for iy in numpy.arange(y.shape[1]):
|
nikcleju@16
|
224 for algofunc,strname in algosN:
|
nikcleju@16
|
225 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
|
nikcleju@16
|
226 boxparams.append((algofunc,y[:,iy],M,Omega,epsilon))
|
nikcleju@16
|
227 refparams.append(x0[:,iy])
|
nikcleju@16
|
228 for ilbd,lbd in zip(numpy.arange(lambdas.size),lambdas):
|
nikcleju@16
|
229 for iy in numpy.arange(y.shape[1]):
|
nikcleju@16
|
230 for algofunc,strname in algosL:
|
nikcleju@16
|
231 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
|
nikcleju@16
|
232 boxparams.append((algofunc,y[:,iy],M,Omega,epsilon,lbd))
|
nikcleju@16
|
233 refparams.append(x0[:,iy])
|
nikcleju@16
|
234
|
nikcleju@16
|
235 # algoparams = algo function + parameters it requires
|
nikcleju@16
|
236 taskparams.append(boxparams)
|
nikcleju@16
|
237
|
nikcleju@16
|
238 return taskparams, refparams
|
nikcleju@16
|
239
|
nikcleju@16
|
240
|
nikcleju@16
|
241 def immedResults(xrec,x0):
|
nikcleju@16
|
242 if xrec == None:
|
nikcleju@16
|
243 return None
|
nikcleju@16
|
244 err = numpy.linalg.norm(x0 - xrec)
|
nikcleju@16
|
245 relerr = err / numpy.linalg.norm(x0)
|
nikcleju@16
|
246
|
nikcleju@16
|
247 return err,relerr
|
nikcleju@16
|
248
|
nikcleju@16
|
249 def processResults(globalparams, taskresults):
|
nikcleju@16
|
250 deltas = globalparams['deltas']
|
nikcleju@16
|
251 rhos = globalparams['rhos']
|
nikcleju@16
|
252 algosN = globalparams['algosN']
|
nikcleju@16
|
253 algosL = globalparams['algosL']
|
nikcleju@16
|
254 lambdas = globalparams['lambdas']
|
nikcleju@16
|
255
|
nikcleju@16
|
256 meanmatrix = dict()
|
nikcleju@16
|
257 elapsed = dict()
|
nikcleju@16
|
258 for algo in algosN:
|
nikcleju@16
|
259 meanmatrix[algo[1]] = numpy.zeros((rhos.size, deltas.size))
|
nikcleju@16
|
260 elapsed[algo[1]] = 0
|
nikcleju@16
|
261 for algo in algosL:
|
nikcleju@16
|
262 meanmatrix[algo[1]] = numpy.zeros((lambdas.size, rhos.size, deltas.size))
|
nikcleju@16
|
263 elapsed[algo[1]] = numpy.zeros(lambdas.size)
|
nikcleju@16
|
264
|
nikcleju@16
|
265 # To fix this
|
nikcleju@16
|
266 idx = 0
|
nikcleju@16
|
267 for idelta,delta in zip(numpy.arange(deltas.size),deltas):
|
nikcleju@16
|
268 for irho,rho in zip(numpy.arange(rhos.size),rhos):
|
nikcleju@16
|
269 immedResults = taskresults[idx]
|
nikcleju@16
|
270 for iy in numpy.arange(y.shape[1]):
|
nikcleju@16
|
271 for algofunc,strname in algosN:
|
nikcleju@16
|
272 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
|
nikcleju@16
|
273 boxparams.append((algofunc,y[:,iy],M,Omega,epsilon))
|
nikcleju@16
|
274 refparams.append(x0[:,iy])
|
nikcleju@16
|
275 for ilbd,lbd in zip(numpy.arange(lambdas.size),lambdas):
|
nikcleju@16
|
276 for iy in numpy.arange(y.shape[1]):
|
nikcleju@16
|
277 for algofunc,strname in algosL:
|
nikcleju@16
|
278 epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
|
nikcleju@16
|
279 boxparams.append((algofunc,y[:,iy],M,Omega,epsilon,lbd))
|
nikcleju@16
|
280 refparams.append(x0[:,iy])
|
nikcleju@16
|
281
|
nikcleju@16
|
282
|
nikcleju@16
|
283 # Process results
|
nikcleju@16
|
284 idx = 0
|
nikcleju@16
|
285 for idelta,delta in zip(numpy.arange(deltas.size),deltas):
|
nikcleju@16
|
286 for irho,rho in zip(numpy.arange(rhos.size),rhos):
|
nikcleju@16
|
287 #mrelerrN,mrelerrL,addelapsed = taskresults[idx]
|
nikcleju@16
|
288 mrelerrN,mrelerrL = taskresults[idx]
|
nikcleju@16
|
289 idx = idx+1
|
nikcleju@16
|
290 for algotuple in algosN:
|
nikcleju@16
|
291 meanmatrix[algotuple[1]][irho,idelta] = 1 - mrelerrN[algotuple[1]]
|
nikcleju@16
|
292 if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]):
|
nikcleju@16
|
293 meanmatrix[algotuple[1]][irho,idelta] = 0
|
nikcleju@16
|
294 elapsed[algotuple[1]] = elapsed[algotuple[1]] + addelapsed[algotuple[1]]
|
nikcleju@16
|
295 for algotuple in algosL:
|
nikcleju@16
|
296 for ilbd in numpy.arange(lambdas.size):
|
nikcleju@16
|
297 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 1 - mrelerrL[algotuple[1]][ilbd]
|
nikcleju@16
|
298 if meanmatrix[algotuple[1]][ilbd,irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][ilbd,irho,idelta]):
|
nikcleju@16
|
299 meanmatrix[algotuple[1]][ilbd,irho,idelta] = 0
|
nikcleju@16
|
300 elapsed[algotuple[1]][ilbd] = elapsed[algotuple[1]][ilbd] + addelapsed[algotuple[1]][ilbd]
|
nikcleju@16
|
301
|
nikcleju@16
|
302
|
nikcleju@16
|
303 procresults = dict()
|
nikcleju@16
|
304 procresults['meanmatrix'] = meanmatrix
|
nikcleju@16
|
305 procresults['elapsed'] = elapsed
|
nikcleju@16
|
306 return procresults
|
nikcleju@16
|
307
|
nikcleju@16
|
308 # Script main
|
nikcleju@16
|
309 if __name__ == "__main__":
|
nikcleju@16
|
310
|
nikcleju@16
|
311 stdparams_approx.paramstest['ncpus'] = 1
|
nikcleju@16
|
312 rb = RunBatch(generateTaskParams, immedResults, processResults)
|
nikcleju@16
|
313 rb.run(stdparams_approx.paramstest)
|
nikcleju@16
|
314
|
nikcleju@16
|
315 print "Finished" |