nikcleju@27: # -*- coding: utf-8 -*- nikcleju@27: """ nikcleju@27: Created on Sat Nov 05 18:08:40 2011 nikcleju@27: nikcleju@27: @author: Nic nikcleju@27: """ nikcleju@27: nikcleju@27: import numpy as np nikcleju@27: import scipy.io nikcleju@27: import math nikcleju@27: from multiprocessing import Pool nikcleju@27: doplot = True nikcleju@27: try: nikcleju@27: import matplotlib.pyplot as plt nikcleju@27: except: nikcleju@27: doplot = False nikcleju@27: if doplot: nikcleju@27: import matplotlib.cm as cm nikcleju@27: import pyCSalgos nikcleju@27: import pyCSalgos.GAP.GAP nikcleju@27: import pyCSalgos.SL0.SL0_approx nikcleju@27: nikcleju@27: # Define functions that prepare arguments for each algorithm call nikcleju@27: def run_gap(y,M,Omega,epsilon): nikcleju@27: gapparams = {"num_iteration" : 1000,\ nikcleju@27: "greedy_level" : 0.9,\ nikcleju@27: "stopping_coefficient_size" : 1e-4,\ nikcleju@27: "l2solver" : 'pseudoinverse',\ nikcleju@27: "noise_level": epsilon} nikcleju@27: return pyCSalgos.GAP.GAP.GAP(y,M,M.T,Omega,Omega.T,gapparams,np.zeros(Omega.shape[1]))[0] nikcleju@27: nikcleju@27: def run_sl0(y,M,Omega,D,U,S,Vt,epsilon,lbd): nikcleju@27: nikcleju@27: N,n = Omega.shape nikcleju@27: #D = np.linalg.pinv(Omega) nikcleju@27: #U,S,Vt = np.linalg.svd(D) nikcleju@27: aggDupper = np.dot(M,D) nikcleju@27: aggDlower = Vt[-(N-n):,:] nikcleju@27: aggD = np.concatenate((aggDupper, lbd * aggDlower)) nikcleju@27: aggy = np.concatenate((y, np.zeros(N-n))) nikcleju@27: nikcleju@27: sigmamin = 0.001 nikcleju@27: sigma_decrease_factor = 0.5 nikcleju@27: mu_0 = 2 nikcleju@27: L = 10 nikcleju@27: return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L) nikcleju@27: nikcleju@27: def run_bp(y,M,Omega,D,U,S,Vt,epsilon,lbd): nikcleju@27: nikcleju@27: N,n = Omega.shape nikcleju@27: #D = np.linalg.pinv(Omega) nikcleju@27: #U,S,Vt = np.linalg.svd(D) nikcleju@27: aggDupper = np.dot(M,D) nikcleju@27: aggDlower = Vt[-(N-n):,:] nikcleju@27: aggD = np.concatenate((aggDupper, lbd * aggDlower)) nikcleju@27: aggy = np.concatenate((y, np.zeros(N-n))) nikcleju@27: nikcleju@27: sigmamin = 0.001 nikcleju@27: sigma_decrease_factor = 0.5 nikcleju@27: mu_0 = 2 nikcleju@27: L = 10 nikcleju@27: return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L) nikcleju@27: nikcleju@27: nikcleju@27: # Define tuples (algorithm setup function, algorithm function, name) nikcleju@27: gap = (run_gap, 'GAP') nikcleju@27: sl0 = (run_sl0, 'SL0_approx') nikcleju@27: nikcleju@27: # Define which algorithms to run nikcleju@27: # 1. Algorithms not depending on lambda nikcleju@27: algosN = gap, # tuple nikcleju@27: # 2. Algorithms depending on lambda (our ABS approach) nikcleju@27: algosL = sl0, # tuple nikcleju@27: nikcleju@27: def mainrun(): nikcleju@27: nikcleju@27: nalgosN = len(algosN) nikcleju@27: nalgosL = len(algosL) nikcleju@27: nikcleju@27: #Set up experiment parameters nikcleju@27: d = 50.0; nikcleju@27: sigma = 2.0 nikcleju@27: #deltas = np.arange(0.05,1.,0.05) nikcleju@27: #rhos = np.arange(0.05,1.,0.05) nikcleju@27: deltas = np.array([0.05, 0.45, 0.95]) nikcleju@27: rhos = np.array([0.05, 0.45, 0.95]) nikcleju@27: #deltas = np.array([0.05]) nikcleju@27: #rhos = np.array([0.05]) nikcleju@27: #delta = 0.8; nikcleju@27: #rho = 0.15; nikcleju@27: numvects = 100; # Number of vectors to generate nikcleju@27: SNRdb = 20.; # This is norm(signal)/norm(noise), so power, not energy nikcleju@27: # Values for lambda nikcleju@27: #lambdas = [0 10.^linspace(-5, 4, 10)]; nikcleju@27: #lambdas = np.concatenate((np.array([0]), 10**np.linspace(-5, 4, 10))) nikcleju@27: lambdas = np.array([0., 0.0001, 0.01, 1, 100, 10000]) nikcleju@27: nikcleju@27: meanmatrix = dict() nikcleju@27: for i,algo in zip(np.arange(nalgosN),algosN): nikcleju@27: meanmatrix[algo[1]] = np.zeros((rhos.size, deltas.size)) nikcleju@27: for i,algo in zip(np.arange(nalgosL),algosL): nikcleju@27: meanmatrix[algo[1]] = np.zeros((lambdas.size, rhos.size, deltas.size)) nikcleju@27: nikcleju@27: jobparams = [] nikcleju@27: for idelta,delta in zip(np.arange(deltas.size),deltas): nikcleju@27: for irho,rho in zip(np.arange(rhos.size),rhos): nikcleju@27: nikcleju@27: # Generate data and operator nikcleju@27: Omega,x0,y,M,realnoise = genData(d,sigma,delta,rho,numvects,SNRdb) nikcleju@27: nikcleju@27: # Run algorithms nikcleju@27: print "***** delta = ",delta," rho = ",rho nikcleju@27: #mrelerrN,mrelerrL = runonce(algosN,algosL,Omega,y,lambdas,realnoise,M,x0) nikcleju@27: jobparams.append((algosN,algosL, Omega,y,lambdas,realnoise,M,x0)) nikcleju@27: nikcleju@27: pool = Pool(4) nikcleju@27: jobresults = pool.map(runoncetuple,jobparams) nikcleju@27: nikcleju@27: idx = 0 nikcleju@27: for idelta,delta in zip(np.arange(deltas.size),deltas): nikcleju@27: for irho,rho in zip(np.arange(rhos.size),rhos): nikcleju@27: mrelerrN,mrelerrL = jobresults[idx] nikcleju@27: idx = idx+1 nikcleju@27: for algotuple in algosN: nikcleju@27: meanmatrix[algotuple[1]][irho,idelta] = 1 - mrelerrN[algotuple[1]] nikcleju@27: if meanmatrix[algotuple[1]][irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][irho,idelta]): nikcleju@27: meanmatrix[algotuple[1]][irho,idelta] = 0 nikcleju@27: for algotuple in algosL: nikcleju@27: for ilbd in np.arange(lambdas.size): nikcleju@27: meanmatrix[algotuple[1]][ilbd,irho,idelta] = 1 - mrelerrL[algotuple[1]][ilbd] nikcleju@27: if meanmatrix[algotuple[1]][ilbd,irho,idelta] < 0 or math.isnan(meanmatrix[algotuple[1]][ilbd,irho,idelta]): nikcleju@27: meanmatrix[algotuple[1]][ilbd,irho,idelta] = 0 nikcleju@27: nikcleju@27: # # Prepare matrices to show nikcleju@27: # showmats = dict() nikcleju@27: # for i,algo in zip(np.arange(nalgosN),algosN): nikcleju@27: # showmats[algo[1]] = np.zeros(rhos.size, deltas.size) nikcleju@27: # for i,algo in zip(np.arange(nalgosL),algosL): nikcleju@27: # showmats[algo[1]] = np.zeros(lambdas.size, rhos.size, deltas.size) nikcleju@27: nikcleju@27: # Save nikcleju@27: tosave = dict() nikcleju@27: tosave['meanmatrix'] = meanmatrix nikcleju@27: tosave['d'] = d nikcleju@27: tosave['sigma'] = sigma nikcleju@27: tosave['deltas'] = deltas nikcleju@27: tosave['rhos'] = rhos nikcleju@27: tosave['numvects'] = numvects nikcleju@27: tosave['SNRdb'] = SNRdb nikcleju@27: tosave['lambdas'] = lambdas nikcleju@27: try: nikcleju@27: scipy.io.savemat('ABSapprox.mat',tosave) nikcleju@27: except TypeError: nikcleju@27: print "Oops, Type Error" nikcleju@27: raise nikcleju@27: # Show nikcleju@27: if doplot: nikcleju@27: for algotuple in algosN: nikcleju@27: plt.figure() nikcleju@27: plt.imshow(meanmatrix[algotuple[1]], cmap=cm.gray, interpolation='nearest',origin='lower') nikcleju@27: for algotuple in algosL: nikcleju@27: for ilbd in np.arange(lambdas.size): nikcleju@27: plt.figure() nikcleju@27: plt.imshow(meanmatrix[algotuple[1]][ilbd], cmap=cm.gray, interpolation='nearest',origin='lower') nikcleju@27: plt.show() nikcleju@27: print "Finished." nikcleju@27: nikcleju@27: def genData(d,sigma,delta,rho,numvects,SNRdb): nikcleju@27: nikcleju@27: # Process parameters nikcleju@27: noiselevel = 1.0 / (10.0**(SNRdb/10.0)); nikcleju@27: p = round(sigma*d); nikcleju@27: m = round(delta*d); nikcleju@27: l = round(d - rho*m); nikcleju@27: nikcleju@27: # Generate Omega and data based on parameters nikcleju@27: Omega = pyCSalgos.GAP.GAP.Generate_Analysis_Operator(d, p); nikcleju@27: # Optionally make Omega more coherent nikcleju@27: U,S,Vt = np.linalg.svd(Omega); nikcleju@27: Sdnew = S * (1+np.arange(S.size)) # Make D coherent, not Omega! nikcleju@27: Snew = np.vstack((np.diag(Sdnew), np.zeros((Omega.shape[0] - Omega.shape[1], Omega.shape[1])))) nikcleju@27: Omega = np.dot(U , np.dot(Snew,Vt)) nikcleju@27: nikcleju@27: # Generate data nikcleju@27: x0,y,M,Lambda,realnoise = pyCSalgos.GAP.GAP.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0'); nikcleju@27: nikcleju@27: return Omega,x0,y,M,realnoise nikcleju@27: nikcleju@27: def runoncetuple(t): nikcleju@27: return runonce(*t) nikcleju@27: nikcleju@27: def runonce(algosN,algosL,Omega,y,lambdas,realnoise,M,x0): nikcleju@27: nikcleju@27: d = Omega.shape[1] nikcleju@27: nikcleju@27: nalgosN = len(algosN) nikcleju@27: nalgosL = len(algosL) nikcleju@27: nikcleju@27: xrec = dict() nikcleju@27: err = dict() nikcleju@27: relerr = dict() nikcleju@27: nikcleju@27: # Prepare storage variables for algorithms non-Lambda nikcleju@27: for i,algo in zip(np.arange(nalgosN),algosN): nikcleju@27: xrec[algo[1]] = np.zeros((d, y.shape[1])) nikcleju@27: err[algo[1]] = np.zeros(y.shape[1]) nikcleju@27: relerr[algo[1]] = np.zeros(y.shape[1]) nikcleju@27: # Prepare storage variables for algorithms with Lambda nikcleju@27: for i,algo in zip(np.arange(nalgosL),algosL): nikcleju@27: xrec[algo[1]] = np.zeros((lambdas.size, d, y.shape[1])) nikcleju@27: err[algo[1]] = np.zeros((lambdas.size, y.shape[1])) nikcleju@27: relerr[algo[1]] = np.zeros((lambdas.size, y.shape[1])) nikcleju@27: nikcleju@27: # Run algorithms non-Lambda nikcleju@27: for iy in np.arange(y.shape[1]): nikcleju@27: for algofunc,strname in algosN: nikcleju@27: epsilon = 1.1 * np.linalg.norm(realnoise[:,iy]) nikcleju@27: xrec[strname][:,iy] = algofunc(y[:,iy],M,Omega,epsilon) nikcleju@27: err[strname][iy] = np.linalg.norm(x0[:,iy] - xrec[strname][:,iy]) nikcleju@27: relerr[strname][iy] = err[strname][iy] / np.linalg.norm(x0[:,iy]) nikcleju@27: for algotuple in algosN: nikcleju@27: print algotuple[1],' : avg relative error = ',np.mean(relerr[strname]) nikcleju@27: nikcleju@27: # Run algorithms with Lambda nikcleju@27: for ilbd,lbd in zip(np.arange(lambdas.size),lambdas): nikcleju@27: for iy in np.arange(y.shape[1]): nikcleju@27: D = np.linalg.pinv(Omega) nikcleju@27: U,S,Vt = np.linalg.svd(D) nikcleju@27: for algofunc,strname in algosL: nikcleju@27: epsilon = 1.1 * np.linalg.norm(realnoise[:,iy]) nikcleju@27: gamma = algofunc(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd) nikcleju@27: xrec[strname][ilbd,:,iy] = np.dot(D,gamma) nikcleju@27: err[strname][ilbd,iy] = np.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy]) nikcleju@27: relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / np.linalg.norm(x0[:,iy]) nikcleju@27: print 'Lambda = ',lbd,' :' nikcleju@27: for algotuple in algosL: nikcleju@27: print ' ',algotuple[1],' : avg relative error = ',np.mean(relerr[strname][ilbd,:]) nikcleju@27: nikcleju@27: # Prepare results nikcleju@27: mrelerrN = dict() nikcleju@27: for algotuple in algosN: nikcleju@27: mrelerrN[algotuple[1]] = np.mean(relerr[algotuple[1]]) nikcleju@27: mrelerrL = dict() nikcleju@27: for algotuple in algosL: nikcleju@27: mrelerrL[algotuple[1]] = np.mean(relerr[algotuple[1]],1) nikcleju@27: nikcleju@27: return mrelerrN,mrelerrL nikcleju@27: nikcleju@27: # Script main nikcleju@27: if __name__ == "__main__": nikcleju@27: #import cProfile nikcleju@27: #cProfile.run('mainrun()', 'profile') nikcleju@27: nikcleju@27: mainrun()