Mercurial > hg > absrec
view test_exact_old.py @ 21:d395461b92ae tip
Lots and lots of modifications. Approximate recovery script working.
author | Nic Cleju <nikcleju@gmail.com> |
---|---|
date | Mon, 23 Apr 2012 10:54:57 +0300 |
parents | 7fdf964f4edd |
children |
line wrap: on
line source
# -*- coding: utf-8 -*- """ Old version, ignore it Author: Nicolae Cleju """ import numpy import scipy.io import math import os import time import multiprocessing import sys _currmodule = sys.modules[__name__] # Lock for printing in a thread-safe way _printLock = None import stdparams_exact import AnalysisGenerate # For exceptions import pyCSalgos.BP.l1eq_pd import pyCSalgos.NESTA.NESTA def _initProcess(share, njobs, printLock): """ Pool initializer function (multiprocessing) Needed to pass the shared variable to the worker processes The variables must be global in the module in order to be seen later in run_once_tuple() see http://stackoverflow.com/questions/1675766/how-to-combine-pool-map-with-array-shared-memory-in-python-multiprocessing """ currmodule = sys.modules[__name__] currmodule.proccount = share currmodule.njobs = njobs currmodule._printLock = printLock #========================== # Interface run functions #========================== def run(std=stdparams_exact.std1,ncpus=None): algos,d,sigma,deltas,rhos,numvects,SNRdb,dosavedata,savedataname,doshowplot,dosaveplot,saveplotbase,saveplotexts = std() run_multi(algos, d,sigma,deltas,rhos,numvects,SNRdb,dosavedata=dosavedata,savedataname=savedataname,\ ncpus=ncpus,\ doshowplot=doshowplot,dosaveplot=dosaveplot,saveplotbase=saveplotbase,saveplotexts=saveplotexts) #========================== # Main functions #========================== def run_multi(algos, d, sigma, deltas, rhos, numvects, SNRdb, ncpus=None,\ doshowplot=False, dosaveplot=False, saveplotbase=None, saveplotexts=None,\ dosavedata=False, savedataname=None): print "This is analysis recovery ABS approximation script by Nic" print "Running phase transition ( run_multi() )" if ncpus is None: print " Running in parallel with default",multiprocessing.cpu_count(),"threads using \"multiprocessing\" package" if multiprocessing.cpu_count() == 1: doparallel = False else: doparallel = True elif ncpus > 1: print " Running in parallel with",ncpus,"threads using \"multiprocessing\" package" doparallel = True elif ncpus == 1: print "Running single thread" doparallel = False else: print "Wrong number of threads, exiting" return if dosaveplot or doshowplot: try: import matplotlib if doshowplot or os.name == 'nt': print "Importing matplotlib with default (GUI) backend... ", else: print "Importing matplotlib with \"Cairo\" backend... ", matplotlib.use('Cairo') import matplotlib.pyplot as plt import matplotlib.cm as cm import matplotlib.colors as mcolors print "OK" except: print "FAIL" print "Importing matplotlib.pyplot failed. No figures at all" print "Try selecting a different backend" doshowplot = False dosaveplot = False # Print summary of parameters print "Parameters:" if doshowplot: print " Showing figures" else: print " Not showing figures" if dosaveplot: print " Saving figures as "+saveplotbase+"* with extensions ",saveplotexts else: print " Not saving figures" print " Running algorithms",[algotuple[1] for algotuple in algos] nalgos = len(algos) meanmatrix = dict() elapsed = dict() for i,algo in zip(numpy.arange(nalgos),algos): meanmatrix[algo[1]] = numpy.zeros((rhos.size, deltas.size)) elapsed[algo[1]] = 0 # Prepare parameters jobparams = [] print " (delta, rho) pairs to be run:" for idelta,delta in zip(numpy.arange(deltas.size),deltas): for irho,rho in zip(numpy.arange(rhos.size),rhos): # Generate data and operator Omega,x0,y,M,realnoise = generateData(d,sigma,delta,rho,numvects,SNRdb) #Save the parameters, and run after print " delta = ",delta," rho = ",rho jobparams.append((algos,Omega,y,M,x0)) print "End of parameters" _currmodule.njobs = len(jobparams) # Thread-safe variable to store number of finished jobs _currmodule.proccount = multiprocessing.Value('I', 0) # 'I' = unsigned int, see docs (multiprocessing, array) # Run jobresults = [] if doparallel: _currmodule._printLock = multiprocessing.Lock() pool = multiprocessing.Pool(ncpus,initializer=_initProcess,initargs=(_currmodule.proccount,_currmodule.njobs,_currmodule._printLock)) jobresults = pool.map(run_once_tuple, jobparams) else: for jobparam in jobparams: jobresults.append(run_once_tuple(jobparam)) # Read results idx = 0 for idelta,delta in zip(numpy.arange(deltas.size),deltas): for irho,rho in zip(numpy.arange(rhos.size),rhos): mrelerr,addelapsed = jobresults[idx] idx = idx+1 for algotuple in algos: meanmatrix[algotuple[1]][irho,idelta] = mrelerr[algotuple[1]] if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]): meanmatrix[algotuple[1]][irho,idelta] = 0 elapsed[algotuple[1]] = elapsed[algotuple[1]] + addelapsed[algotuple[1]] # Save if dosavedata: tosave = dict() tosave['meanmatrix'] = meanmatrix tosave['elapsed'] = elapsed tosave['d'] = d tosave['sigma'] = sigma tosave['deltas'] = deltas tosave['rhos'] = rhos tosave['numvects'] = numvects tosave['SNRdb'] = SNRdb # Save algo names as cell array obj_arr = numpy.zeros((len(algos),), dtype=numpy.object) idx = 0 for algotuple in algos: obj_arr[idx] = algotuple[1] idx = idx+1 tosave['algonames'] = obj_arr try: scipy.io.savemat(savedataname, tosave) except: print "Save error" # Show if doshowplot or dosaveplot: for algotuple in algos: algoname = algotuple[1] plt.figure() plt.imshow(meanmatrix[algoname], cmap=cm.gray, norm=mcolors.Normalize(0,1), interpolation='nearest',origin='lower') if dosaveplot: for ext in saveplotexts: plt.savefig(saveplotbase + algoname + '.' + ext, bbox_inches='tight') if doshowplot: plt.show() print "Finished." def run_once_tuple(t): results = run_once(*t) if _currmodule._printLock: _currmodule._printLock.acquire() _currmodule.proccount.value = _currmodule.proccount.value + 1 print "================================" print "Finished job",_currmodule.proccount.value,"/",_currmodule.njobs,"jobs remaining",_currmodule.njobs - _currmodule.proccount.value,"/",_currmodule.njobs print "================================" _currmodule._printLock.release() return results def run_once(algos,Omega,y,M,x0): d = Omega.shape[1] nalgos = len(algos) xrec = dict() err = dict() relerr = dict() elapsed = dict() # Prepare storage variables for algorithms for i,algo in zip(numpy.arange(nalgos),algos): xrec[algo[1]] = numpy.zeros((d, y.shape[1])) err[algo[1]] = numpy.zeros(y.shape[1]) relerr[algo[1]] = numpy.zeros(y.shape[1]) elapsed[algo[1]] = 0 # Run algorithms for iy in numpy.arange(y.shape[1]): for algofunc,strname in algos: try: timestart = time.time() xrec[strname][:,iy] = algofunc(y[:,iy],M,Omega) elapsed[strname] = elapsed[strname] + (time.time() - timestart) except pyCSalgos.BP.l1eq_pd.l1eqNotImplementedError as e: if _currmodule._printLock: _currmodule._printLock.acquire() print "Caught exception when running algorithm",strname," :",e.message _currmodule._printLock.release() err[strname][iy] = numpy.linalg.norm(x0[:,iy] - xrec[strname][:,iy]) relerr[strname][iy] = err[strname][iy] / numpy.linalg.norm(x0[:,iy]) for algofunc,strname in algos: if _currmodule._printLock: _currmodule._printLock.acquire() print strname,' : avg relative error = ',numpy.mean(relerr[strname]) _currmodule._printLock.release() # Prepare results #mrelerr = dict() #for algotuple in algos: # mrelerr[algotuple[1]] = numpy.mean(relerr[algotuple[1]]) #return mrelerr,elapsed # Should return number of reconstructions with error < threshold, not average error exactthr = 1e-6 mrelerr = dict() for algotuple in algos: mrelerr[algotuple[1]] = float(numpy.count_nonzero(relerr[algotuple[1]] < exactthr)) / y.shape[1] return mrelerr,elapsed def generateData(d,sigma,delta,rho,numvects,SNRdb): # Process parameters noiselevel = 1.0 / (10.0**(SNRdb/10.0)); p = round(sigma*d); m = round(delta*d); l = round(d - rho*m); # Generate Omega and data based on parameters Omega = AnalysisGenerate.Generate_Analysis_Operator(d, p); # Optionally make Omega more coherent #U,S,Vt = numpy.linalg.svd(Omega); #Sdnew = S * (1+numpy.arange(S.size)) # Make D coherent, not Omega! #Snew = numpy.vstack((numpy.diag(Sdnew), numpy.zeros((Omega.shape[0] - Omega.shape[1], Omega.shape[1])))) #Omega = numpy.dot(U , numpy.dot(Snew,Vt)) # Generate data x0,y,M,Lambda,realnoise = AnalysisGenerate.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0'); return Omega,x0,y,M,realnoise def testMatlab(): mdict = scipy.io.loadmat("E:\\CS\\Ale mele\\Analysis_ExactRec\\temp.mat") algos = stdparams_exact.std1()[0] res = run_once(algos, mdict['Omega'].byteswap().newbyteorder(),mdict['y'],mdict['M'],mdict['x0']) def generateFig(): run(stdparams_exact.std1) # Script main if __name__ == "__main__": #import cProfile #cProfile.run('mainrun()', 'profile') #run_mp(stdparams_exact.stdtest) #runsingleexampledebug() run(stdparams_exact.std1, ncpus=3) #testMatlab() #run(stdparams_exact.stdtest, ncpus=1)