nikcleju@10
|
1 # -*- coding: utf-8 -*-
|
nikcleju@10
|
2 """
|
nikcleju@10
|
3 Created on Sat Nov 05 18:08:40 2011
|
nikcleju@10
|
4
|
nikcleju@10
|
5 @author: Nic
|
nikcleju@10
|
6 """
|
nikcleju@10
|
7
|
nikcleju@19
|
8 import numpy as np
|
nikcleju@10
|
9 import pyCSalgos
|
nikcleju@19
|
10 import pyCSalgos.GAP.GAP
|
nikcleju@19
|
11 import pyCSalgos.SL0.SL0_approx
|
nikcleju@10
|
12
|
nikcleju@19
|
13 # Define functions that prepare arguments for each algorithm call
|
nikcleju@10
|
14 def gap_paramsetup(y,M,Omega,epsilon,lbd):
|
nikcleju@19
|
15 gapparams = {"num_iteration" : 1000,\
|
nikcleju@19
|
16 "greedy_level" : 0.9,\
|
nikcleju@19
|
17 "stopping_coefficient_size" : 1e-4,\
|
nikcleju@19
|
18 "l2solver" : 'pseudoinverse',\
|
nikcleju@19
|
19 "noise_level": epsilon}
|
nikcleju@19
|
20 return y,M,M.T,Omega,Omega.T,gapparams,np.zeros(Omega.shape[1])
|
nikcleju@19
|
21 def sl0_paramsetup(y,M,Omega,epsilon,lbd):
|
nikcleju@19
|
22
|
nikcleju@19
|
23 N,n = Omega.shape
|
nikcleju@19
|
24 D = np.linalg.pinv(Omega)
|
nikcleju@19
|
25 U,S,Vt = np.linalg.svd(D)
|
nikcleju@19
|
26 aggDupper = np.dot(M,D)
|
nikcleju@19
|
27 aggDlower = Vt[-(N-n):,:]
|
nikcleju@19
|
28 aggD = np.concatenate((aggDupper, lbd * aggDlower))
|
nikcleju@19
|
29 aggy = np.concatenate((y, np.zeros(N-n)))
|
nikcleju@19
|
30
|
nikcleju@20
|
31 sigmamin = 0.01
|
nikcleju@20
|
32 sigma_decrease_factor = 0.8
|
nikcleju@20
|
33 mu_0 = 2
|
nikcleju@20
|
34 L = 10
|
nikcleju@20
|
35 return aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L
|
nikcleju@20
|
36
|
nikcleju@20
|
37 def post_multiply_with_D(D,gamma):
|
nikcleju@20
|
38 return np.dot(D,gamma)
|
nikcleju@20
|
39 def post_do_nothing(D,gamma):
|
nikcleju@20
|
40 return gamma
|
nikcleju@10
|
41
|
nikcleju@19
|
42 # Define tuples (algorithm setup function, algorithm function, name)
|
nikcleju@20
|
43 gap = (gap_paramsetup, pyCSalgos.GAP.GAP.GAP, post_do_nothing, 'GAP')
|
nikcleju@20
|
44 sl0 = (sl0_paramsetup, pyCSalgos.SL0.SL0_approx.SL0_approx, post_multiply_with_D, 'SL0_approx')
|
nikcleju@20
|
45 #sl0 = (sl0_paramsetup, lambda x: np.dot(x[0],x[1]()), 'SL0_approx')
|
nikcleju@10
|
46
|
nikcleju@19
|
47 # Main function
|
nikcleju@19
|
48 def mainrun():
|
nikcleju@10
|
49
|
nikcleju@19
|
50 # Define which algorithms to run
|
nikcleju@19
|
51 algos = (gap, sl0)
|
nikcleju@19
|
52 numalgos = len(algos)
|
nikcleju@19
|
53
|
nikcleju@19
|
54 # Set up experiment parameters
|
nikcleju@19
|
55 sigma = 2.0;
|
nikcleju@19
|
56 delta = 0.8;
|
nikcleju@19
|
57 rho = 0.15;
|
nikcleju@20
|
58 numvects = 10; # Number of vectors to generate
|
nikcleju@20
|
59 SNRdb = 20.; # This is norm(signal)/norm(noise), so power, not energy
|
nikcleju@10
|
60
|
nikcleju@19
|
61 # Process parameters
|
nikcleju@20
|
62 noiselevel = 1.0 / (10.0**(SNRdb/10.0));
|
nikcleju@19
|
63 d = 50;
|
nikcleju@19
|
64 p = round(sigma*d);
|
nikcleju@19
|
65 m = round(delta*d);
|
nikcleju@19
|
66 l = round(d - rho*m);
|
nikcleju@19
|
67
|
nikcleju@19
|
68 # Generate Omega and data based on parameters
|
nikcleju@19
|
69 Omega = pyCSalgos.GAP.GAP.Generate_Analysis_Operator(d, p);
|
nikcleju@19
|
70 # Optionally make Omega more coherent
|
nikcleju@19
|
71 #[U, S, Vt] = np.linalg.svd(Omega);
|
nikcleju@19
|
72 #Sdnew = np.diag(S) * (1+np.arange(np.diag(S).size)); % Make D coherent, not Omega!
|
nikcleju@19
|
73 #Snew = [diag(Sdnew); zeros(size(S,1) - size(S,2), size(S,2))];
|
nikcleju@19
|
74 #Omega = U * Snew * V';
|
nikcleju@10
|
75
|
nikcleju@19
|
76 # Generate data
|
nikcleju@19
|
77 x0,y,M,Lambda,realnoise = pyCSalgos.GAP.GAP.Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0');
|
nikcleju@19
|
78
|
nikcleju@19
|
79 # Values for lambda
|
nikcleju@19
|
80 #lambdas = [0 10.^linspace(-5, 4, 10)];
|
nikcleju@19
|
81 lambdas = np.concatenate((np.array([0]), 10**np.linspace(-5, 4, 10)))
|
nikcleju@10
|
82
|
nikcleju@19
|
83 xrec = dict()
|
nikcleju@19
|
84 err = dict()
|
nikcleju@19
|
85 relerr = dict()
|
nikcleju@19
|
86 for i,algo in zip(np.arange(numalgos),algos):
|
nikcleju@20
|
87 xrec[algo[3]] = np.zeros((lambdas.size, d, y.shape[1]))
|
nikcleju@20
|
88 err[algo[3]] = np.zeros((lambdas.size, y.shape[1]))
|
nikcleju@20
|
89 relerr[algo[3]] = np.zeros((lambdas.size, y.shape[1]))
|
nikcleju@19
|
90
|
nikcleju@19
|
91 for ilbd,lbd in zip(np.arange(lambdas.size),lambdas):
|
nikcleju@19
|
92 for iy in np.arange(y.shape[1]):
|
nikcleju@20
|
93 for algosetupfunc,algofunc,algopostfunc,strname in algos:
|
nikcleju@19
|
94 epsilon = 1.1 * np.linalg.norm(realnoise[:,iy])
|
nikcleju@19
|
95
|
nikcleju@19
|
96 inparams = algosetupfunc(y[:,iy],M,Omega,epsilon,lbd)
|
nikcleju@20
|
97 xrec[strname][ilbd,:,iy] = algopostfunc(algofunc(*inparams)[0])
|
nikcleju@19
|
98
|
nikcleju@19
|
99 err[strname][ilbd,iy] = np.linalg.norm(x0[:,iy] - xrec[strname][ilbd,:,iy])
|
nikcleju@19
|
100 relerr[strname][ilbd,iy] = err[strname][ilbd,iy] / np.linalg.norm(x0[:,iy])
|
nikcleju@19
|
101
|
nikcleju@19
|
102 print 'Lambda = ',lbd,' :'
|
nikcleju@19
|
103 for strname in relerr:
|
nikcleju@19
|
104 print ' ',strname,' : avg relative error = ',np.mean(relerr[strname][ilbd,:])
|
nikcleju@10
|
105
|
nikcleju@10
|
106
|
nikcleju@10
|
107
|
nikcleju@19
|
108 # Script main
|
nikcleju@19
|
109 if __name__ == "__main__":
|
nikcleju@19
|
110 mainrun() |