comparison pyCSalgos/SL0/SL0_approx.py @ 15:0d66a0aafb39

SL0_approx test working
author nikcleju
date Sat, 05 Nov 2011 22:10:06 +0000
parents
children afcfd4d1d548
comparison
equal deleted inserted replaced
14:fc245ada9b0f 15:0d66a0aafb39
1 # -*- coding: utf-8 -*-
2 """
3 Created on Sat Nov 05 21:29:09 2011
4
5 @author: Nic
6 """
7
8 # -*- coding: utf-8 -*-
9 """
10 Created on Sat Nov 05 18:39:54 2011
11
12 @author: Nic
13 """
14
15 import numpy as np
16
17 #function s=SL0(A, x, sigma_min, sigma_decrease_factor, mu_0, L, A_pinv, true_s)
18 def SL0_approx(A, x, eps, sigma_min, sigma_decrease_factor=0.5, mu_0=2, L=3, A_pinv=None, true_s=None):
19
20 if A_pinv is None:
21 A_pinv = np.linalg.pinv(A)
22
23 if true_s is not None:
24 ShowProgress = True
25 else:
26 ShowProgress = False
27
28 # Initialization
29 #s = A\x;
30 s = np.dot(A_pinv,x)
31 sigma = 2.0 * np.abs(s).max()
32
33 # Main Loop
34 while sigma>sigma_min:
35 for i in np.arange(L):
36 delta = OurDelta(s,sigma)
37 s = s - mu_0*delta
38 # At this point, s no longer exactly satisfies x = A*s
39 # The original SL0 algorithm projects s onto {s | x = As} with
40 # s = s - np.dot(A_pinv,(np.dot(A,s)-x)) # Projection
41 # We want to project s onto {s | |x-As| < eps}
42 # We move onto the direction -A_pinv*(A*s-x), but only with a
43 # smaller step:
44 direction = np.dot(A_pinv,(np.dot(A,s)-x))
45 if (np.linalg.norm(np.dot(A,direction)) >= eps):
46 s = s - (1.0 - eps/np.linalg.norm(np.dot(A,direction))) * direction
47
48 #assert(np.linalg.norm(x - np.dot(A,s)) < eps + 1e-6)
49
50 if ShowProgress:
51 #fprintf(' sigma=#f, SNR=#f\n',sigma,estimate_SNR(s,true_s))
52 string = ' sigma=%f, SNR=%f\n' % sigma,estimate_SNR(s,true_s)
53 print string
54
55 sigma = sigma * sigma_decrease_factor
56
57 return s
58
59
60 ####################################################################
61 #function delta=OurDelta(s,sigma)
62 def OurDelta(s,sigma):
63
64 return s * np.exp( (-np.abs(s)**2) / sigma**2)
65
66 ####################################################################
67 #function SNR=estimate_SNR(estim_s,true_s)
68 def estimate_SNR(estim_s, true_s):
69
70 err = true_s - estim_s
71 return 10*np.log10((true_s**2).sum()/(err**2).sum())
72