changeset 17:7fdf964f4edd

Added docstrings to files and functions
author Nic Cleju <nikcleju@gmail.com>
date Tue, 03 Apr 2012 16:27:18 +0300
parents 23e9b536ba71
children 4a967f4f18a0
files ABSexact.py ABSlambda.py ABSmixed.py AnalysisGenerate.py SL0_pt_noise.py algos.py runbatch.py stdparams_approx.py stdparams_exact.py test_approx.py test_exact.py test_exact_old.py utils.py
diffstat 13 files changed, 302 insertions(+), 492 deletions(-) [+]
line wrap: on
line diff
--- a/ABSexact.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/ABSexact.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,19 +1,29 @@
 # -*- coding: utf-8 -*-
 """
-Created on Fri Mar 09 14:06:13 2012
+Algorithms for exact analysis recovery based on synthesis solvers (a.k.a. Analysis by Synthesis, ABS).
+Exact reconstruction.
 
-@author: ncleju
+Author: Nicolae Cleju
 """
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
+
 
 import numpy
+
+# Import synthesis solvers from pyCSalgos package
 import pyCSalgos.BP.l1eq_pd
 import pyCSalgos.BP.cvxopt_lp
 import pyCSalgos.OMP.omp_QR
 import pyCSalgos.SL0.SL0
 import pyCSalgos.TST.RecommendedTST
 
+
 def bp(y,M,Omega,x0, pdtol=1e-3, pdmaxiter=50, cgtol=1e-8, cgmaxiter=200, verbose=False):
-
+  """
+  ABS-exact: Basis Pursuit (based on l1magic toolbox)
+  """
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -26,7 +36,9 @@
   return numpy.dot(D , pyCSalgos.BP.l1eq_pd.l1eq_pd(x0,Atilde,Atilde.T,ytilde, pdtol, pdmaxiter, cgtol, cgmaxiter, verbose))
 
 def bp_cvxopt(y,M,Omega):
-
+  """
+  ABS-exact: Basis Pursuit (based cvxopt)
+  """
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -40,6 +52,9 @@
 
 
 def ompeps(y,M,Omega,epsilon):
+  """
+  ABS-exact: OMP with stopping criterion residual < epsilon 
+  """
   
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
@@ -56,6 +71,9 @@
   return numpy.dot(D , pyCSalgos.OMP.omp_QR.greed_omp_qr(ytilde,Atilde,Atilde.shape[1],opts)[0])
 
 def ompk(y,M,Omega,k):
+  """
+  ABS-exact: OMP with stopping criterion fixed number of atoms = k
+  """
   
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
@@ -71,6 +89,9 @@
   return numpy.dot(D , pyCSalgos.OMP.omp_QR.greed_omp_qr(ytilde,Atilde,Atilde.shape[1],opts)[0])
 
 def sl0(y,M,Omega, sigma_min, sigma_decrease_factor=0.5, mu_0=2, L=3, true_s=None):
+  """
+  ABS-exact: Smooth L0 (SL0)
+  """
   
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
@@ -84,6 +105,9 @@
   return numpy.dot(D, pyCSalgos.SL0.SL0.SL0(Atilde,ytilde,sigma_min,sigma_decrease_factor,mu_0,L,true_s))
 
 def tst_recom(y,M,Omega, nsweep=300, tol=0.00001, xinitial=None, ro=None):
+  """
+  ABS-exact: Two Stage Thresholding (TST) with optimized parameters (see Maleki & Donoho)
+  """
   
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
--- a/ABSlambda.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/ABSlambda.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,18 +1,27 @@
 # -*- coding: utf-8 -*-
 """
-Created on Fri Mar 09 14:06:13 2012
+Algorithms for approximate analysis recovery based on synthesis solvers (a.k.a. Analysis by Synthesis, ABS).
+Approximate reconstruction, ABS-lambda.
 
-@author: ncleju
+Author: Nicolae Cleju
 """
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
+
 
 import numpy
+
+# Import synthesis solvers from pyCSalgos package
 import pyCSalgos.BP.l1qc
 import pyCSalgos.SL0.SL0_approx
 import pyCSalgos.OMP.omp_QR
 import pyCSalgos.TST.RecommendedTST
 
 def sl0(y,M,Omega,epsilon,lbd,sigma_min, sigma_decrease_factor=0.5, mu_0=2, L=3, A_pinv=None, true_s=None):
-  
+  """
+  ABS-lambda: Smooth L0 (SL0)
+  """    
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -24,7 +33,9 @@
   return numpy.dot(D, pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigma_min,sigma_decrease_factor,mu_0,L,A_pinv,true_s))
   
 def bp(y,M,Omega,epsilon,lbd, x0, lbtol=1e-3, mu=10, cgtol=1e-8, cgmaxiter=200, verbose=False):
-  
+  """
+  ABS-lambda: Basis Pursuit (based on l1magic toolbox)
+  """    
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -36,7 +47,9 @@
   return numpy.dot(D, pyCSalgos.BP.l1qc.l1qc_logbarrier(x0,aggD,aggD.T,aggy,epsilon, lbtol, mu, cgtol, cgmaxiter, verbose))
 
 def ompeps(y,M,Omega,epsilon,lbd):
-  
+  """
+  ABS-lambda: OMP with stopping criterion residual < epsilon 
+  """
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -51,7 +64,9 @@
   return numpy.dot(D, pyCSalgos.OMP.omp_QR.greed_omp_qr(aggy,aggD,aggD.shape[1],opts)[0])
   
 def tst_recom(y,M,Omega,epsilon,lbd, nsweep=300, xinitial=None, ro=None):
-  
+  """
+  ABS-lambda: Two Stage Thresholding (TST) with optimized parameters (see Maleki & Donoho)
+  """  
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
--- a/ABSmixed.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/ABSmixed.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,16 +1,25 @@
 # -*- coding: utf-8 -*-
 """
-Created on Fri Mar 09 14:06:13 2012
+Algorithms for approximate analysis recovery based on synthesis solvers (a.k.a. Analysis by Synthesis, ABS).
+Approximate reconstruction, ABS-mixed.
 
-@author: ncleju
+Author: Nicolae Cleju
 """
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
+
 
 import numpy
+
+# Import synthesis solvers from pyCSalgos package
 import pyCSalgos.BP.l1qec
 import pyCSalgos.SL0.SL0_approx
 
 def bp(y,M,Omega,epsilon, x0, lbtol=1e-3, mu=10, cgtol=1e-8, cgmaxiter=200, verbose=False):
-  
+  """
+  ABS-mixed: Basis Pursuit (based on l1magic toolbox)
+  """  
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
@@ -20,7 +29,9 @@
   return numpy.dot(D , pyCSalgos.BP.l1qec.l1qec_logbarrier(x0,Aeps,Aeps.T,y,epsilon,Aexact,Aexact.T,numpy.zeros(N-n), lbtol, mu, cgtol, cgmaxiter, verbose))
 
 def sl0(y,M,Omega,epsilon, sigma_min, sigma_decrease_factor=0.5, mu_0=2, L=3, Aeps_pinv=None, Aexact_pinv=None, true_s=None):
-  
+  """
+  ABS-mixed: Smooth L0 (SL0)
+  """  
   N,n = Omega.shape
   D = numpy.linalg.pinv(Omega)
   U,S,Vt = numpy.linalg.svd(D)
--- a/AnalysisGenerate.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/AnalysisGenerate.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,9 +1,14 @@
 # -*- coding: utf-8 -*-
 """
-Created on Thu Dec 08 10:56:56 2011
+Generate analysis operator and cosparse data.
+Based on Matlab functions writteh by Sangnam Nam, INRIA Rennes
 
-@author: ncleju
+Author: Nicolae Cleju
 """
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
+
 
 import numpy
 import numpy.linalg
@@ -12,7 +17,9 @@
 rng = RandomState()
 
 def Generate_Analysis_Operator(d, p):
-  # generate random tight frame with equal column norms
+  """
+  Generate random tight frame with equal column norms
+  """
   if p == d:
     T = rng.randn(d,d);
     [Omega, discard] = numpy.qr(T);
@@ -37,23 +44,23 @@
   return Omega
 
 
+#function [x0,y,M,LambdaMat] = Generate_Data_Known_Omega(Omega, d,p,m,k,noiselevel, numvectors, normstr)
 def Generate_Data_Known_Omega(Omega, d,p,m,k,noiselevel, numvectors, normstr):
-  #function [x0,y,M,LambdaMat] = Generate_Data_Known_Omega(Omega, d,p,m,k,noiselevel, numvectors, normstr)
-  
-  # Building an analysis problem, which includes the ingredients: 
-  #   - Omega - the analysis operator of size p*d
-  #   - M is anunderdetermined measurement matrix of size m*d (m<d)
-  #   - x0 is a vector of length d that satisfies ||Omega*x0||=p-k
-  #   - Lambda is the true location of these k zeros in Omega*x0
-  #   - a measurement vector y0=Mx0 is computed
-  #   - noise contaminated measurement vector y is obtained by
-  #     y = y0 + n where n is an additive gaussian noise with norm(n,2)/norm(y0,2) = noiselevel
-  # Added by Nic:
-  #   - Omega = analysis operator
-  #   - normstr: if 'l0', generate l0 sparse vector (unchanged). If 'l1',
-  #   generate a vector of Laplacian random variables (gamma) and
-  #   pseudoinvert to find x
-
+  """
+  Building an analysis problem, which includes the ingredients: 
+    - Omega - the analysis operator of size p*d
+    - M is anunderdetermined measurement matrix of size m*d (m<d)
+    - x0 is a vector of length d that satisfies ||Omega*x0||=p-k
+    - Lambda is the true location of these k zeros in Omega*x0
+    - a measurement vector y0=Mx0 is computed
+    - noise contaminated measurement vector y is obtained by
+      y = y0 + n where n is an additive gaussian noise with norm(n,2)/norm(y0,2) = noiselevel
+  Added by Nicolae Cleju:
+    - Omega = analysis operator
+    - normstr: if 'l0', generate l0 sparse vector (unchanged). If 'l1',
+    generate a vector of Laplacian random variables (gamma) and
+    pseudoinvert to find x
+  """
   # Omega is known as input parameter
   #Omega=Generate_Analysis_Operator(d, p);
   # Omega = randn(p,d);
--- a/SL0_pt_noise.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/SL0_pt_noise.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 """
-Created on Sat Nov 05 18:08:40 2011
+Test SL0 behavior in the presence of strong noise
 
-@author: Nic
+Author: Nicolae Cleju
 """
 
 from algos import *
--- a/algos.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/algos.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,24 +1,28 @@
 # -*- coding: utf-8 -*-
 """
-Define simple wrappers for algorithms
+Define simple wrappers for algorithms, with similar header.
+Specific algorithm parameters are defined inside here.
 
-Created on Wed Dec 07 14:06:13 2011
+Author: Nicolae Cleju
+"""
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
 
-@author: ncleju
-"""
 
 import numpy
+
+# Module with algorithms implemented in Python
 import pyCSalgos
 import pyCSalgos.GAP.GAP
+
+# Analysis by Synthesis - exact algorithms
 import ABSexact
+# Analysis by Synthesis - mixed algorithms
 import ABSmixed
+# Analysis by Synthesis - lambda algorithms
 import ABSlambda
-#import pyCSalgos.BP.l1qc
-#import pyCSalgos.BP.l1qec
-#import pyCSalgos.SL0.SL0_approx
-#import pyCSalgos.OMP.omp_QR
-#import pyCSalgos.RecomTST.RecommendedTST
-#import pyCSalgos.NESTA.NESTA
+
 
 ###---------------------------------
 ### Exact reconstruction algorithms
@@ -161,7 +165,8 @@
   return ABSlambda.tst_recom(y,M,Omega,epsilon,lbd, nsweep)
   
   
-### Algorithm tuples
+### Define algorithm tuples: (function, name)
+### Will be used in stdparams and in test scripts
 ## Exact recovery
 exact_gap = (run_exact_gap, 'GAP')
 exact_bp = (run_exact_bp, 'ABSexact_BP')
@@ -181,124 +186,3 @@
 lambda_bp = (run_lambda_bp, 'ABSlambda_BP')
 lambda_ompeps = (run_lambda_ompeps, 'ABSlambda_OMPeps')
 lambda_tst = (run_lambda_tst, 'ABSlambda_TST')
-
-##==========================
-## Algorithm functions
-##==========================
-#def run_gap(y,M,Omega,epsilon):
-#  gapparams = {"num_iteration" : 1000,\
-#                   "greedy_level" : 0.9,\
-#                   "stopping_coefficient_size" : 1e-4,\
-#                   "l2solver" : 'pseudoinverse',\
-#                   "noise_level": epsilon}
-#  return pyCSalgos.GAP.GAP.GAP(y,M,M.T,Omega,Omega.T,gapparams,numpy.zeros(Omega.shape[1]))[0]
-#
-#def run_bp_analysis(y,M,Omega,epsilon):
-#  
-#  N,n = Omega.shape
-#  D = numpy.linalg.pinv(Omega)
-#  U,S,Vt = numpy.linalg.svd(D)
-#  Aeps = numpy.dot(M,D)
-#  Aexact = Vt[-(N-n):,:]
-#  # We don't ned any aggregate matrices anymore
-#  
-#  x0 = numpy.zeros(N)
-#  return numpy.dot(D , pyCSalgos.BP.l1qec.l1qec_logbarrier(x0,Aeps,Aeps.T,y,epsilon,Aexact,Aexact.T,numpy.zeros(N-n)))
-#
-#def run_sl0_analysis(y,M,Omega,epsilon):
-#  
-#  N,n = Omega.shape
-#  D = numpy.linalg.pinv(Omega)
-#  U,S,Vt = numpy.linalg.svd(D)
-#  Aeps = numpy.dot(M,D)
-#  Aexact = Vt[-(N-n):,:]
-#  # We don't ned any aggregate matrices anymore
-#  
-#  sigmamin = 0.001
-#  sigma_decrease_factor = 0.5
-#  mu_0 = 2
-#  L = 10
-#  return numpy.dot(D , pyCSalgos.SL0.SL0_approx.SL0_approx_analysis(Aeps,Aexact,y,epsilon,sigmamin,sigma_decrease_factor,mu_0,L))
-#
-#def run_nesta(y,M,Omega,epsilon):
-#  
-#  U,S,V = numpy.linalg.svd(M, full_matrices = True)
-#  V = V.T         # Make like Matlab
-#  m,n = M.shape   # Make like Matlab
-#  S = numpy.hstack((numpy.diag(S), numpy.zeros((m,n-m))))  
-#
-#  opt_muf = 1e-3
-#  optsUSV = {'U':U, 'S':S, 'V':V}
-#  opts = {'U':Omega, 'Ut':Omega.T.copy(), 'USV':optsUSV, 'TolVar':1e-5, 'Verbose':0}
-#  return pyCSalgos.NESTA.NESTA.NESTA(M, None, y, opt_muf, epsilon, opts)[0]
-#
-#
-#def run_sl0(y,M,Omega,D,U,S,Vt,epsilon,lbd):
-#  
-#  N,n = Omega.shape
-#  #D = numpy.linalg.pinv(Omega)
-#  #U,S,Vt = numpy.linalg.svd(D)
-#  aggDupper = numpy.dot(M,D)
-#  aggDlower = Vt[-(N-n):,:]
-#  aggD = numpy.concatenate((aggDupper, lbd * aggDlower))
-#  aggy = numpy.concatenate((y, numpy.zeros(N-n)))
-#  
-#  sigmamin = 0.001
-#  sigma_decrease_factor = 0.5
-#  mu_0 = 2
-#  L = 10
-#  return pyCSalgos.SL0.SL0_approx.SL0_approx(aggD,aggy,epsilon,sigmamin,sigma_decrease_factor,mu_0,L)
-#  
-#def run_bp(y,M,Omega,D,U,S,Vt,epsilon,lbd):
-#  
-#  N,n = Omega.shape
-#  #D = numpy.linalg.pinv(Omega)
-#  #U,S,Vt = numpy.linalg.svd(D)
-#  aggDupper = numpy.dot(M,D)
-#  aggDlower = Vt[-(N-n):,:]
-#  aggD = numpy.concatenate((aggDupper, lbd * aggDlower))
-#  aggy = numpy.concatenate((y, numpy.zeros(N-n)))
-#
-#  x0 = numpy.zeros(N)
-#  return pyCSalgos.BP.l1qc.l1qc_logbarrier(x0,aggD,aggD.T,aggy,epsilon)
-#
-#def run_ompeps(y,M,Omega,D,U,S,Vt,epsilon,lbd):
-#  
-#  N,n = Omega.shape
-#  #D = numpy.linalg.pinv(Omega)
-#  #U,S,Vt = numpy.linalg.svd(D)
-#  aggDupper = numpy.dot(M,D)
-#  aggDlower = Vt[-(N-n):,:]
-#  aggD = numpy.concatenate((aggDupper, lbd * aggDlower))
-#  aggy = numpy.concatenate((y, numpy.zeros(N-n)))
-#  
-#  opts = dict()
-#  opts['stopCrit'] = 'mse'
-#  opts['stopTol'] = epsilon**2 / aggy.size
-#  return pyCSalgos.OMP.omp_QR.greed_omp_qr(aggy,aggD,aggD.shape[1],opts)[0]
-#  
-#def run_tst(y,M,Omega,D,U,S,Vt,epsilon,lbd):
-#  
-#  N,n = Omega.shape
-#  #D = numpy.linalg.pinv(Omega)
-#  #U,S,Vt = numpy.linalg.svd(D)
-#  aggDupper = numpy.dot(M,D)
-#  aggDlower = Vt[-(N-n):,:]
-#  aggD = numpy.concatenate((aggDupper, lbd * aggDlower))
-#  aggy = numpy.concatenate((y, numpy.zeros(N-n)))
-#  
-#  nsweep = 300
-#  tol = epsilon / numpy.linalg.norm(aggy)
-#  return pyCSalgos.RecomTST.RecommendedTST.RecommendedTST(aggD, aggy, nsweep=nsweep, tol=tol)
-#
-##==========================
-## Define tuples (algorithm function, name)
-##==========================
-#gap = (run_gap, 'GAP')
-#sl0 = (run_sl0, 'SL0a')
-#sl0analysis = (run_sl0_analysis, 'SL0a2')
-#bpanalysis = (run_bp_analysis, 'BPa2')
-#nesta = (run_nesta, 'NESTA')
-#bp  = (run_bp, 'BP')
-#ompeps = (run_ompeps, 'OMPeps')
-#tst = (run_tst, 'TST')
\ No newline at end of file
--- a/runbatch.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/runbatch.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-Created on Sat Nov 05 18:08:40 2011
+Trying to write a common framework for simulations
+Not finished yet, better be ignored
 
 @author: Nic
 """
--- a/stdparams_approx.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/stdparams_approx.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,25 +1,22 @@
 # -*- coding: utf-8 -*-
 """
-Created on Wed Dec 07 14:04:40 2011
+Defines standard parameters for approximate reconstruction simulation
 
-@author: ncleju
+Author: Nicolae Cleju
 """
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
 
 import numpy
+
+# Solver algorithms to run
 from algos import *
 
-#==========================
-# Standard parameters
-#==========================
-# Standard parameters for quick testing
-# Algorithms: GAP, SL0 and BP
-# d=50, sigma = 2, delta and rho only 3 x 3, lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# Useful for short testing 
+# Test parameters
 paramstest = dict()
 paramstest['algosN'] = nesta,      # tuple of algorithms not depending on lambda
-  #algosL = sl0,bp    # tuple of algorithms depending on lambda (our ABS approach)
-paramstest['algosL'] = lambda_sl0,
+paramstest['algosL'] = lambda_sl0,  # tuple of algorithms depending on lambda (ABS-lambda)
 paramstest['d'] = 50.0
 paramstest['sigma'] = 2.0
 paramstest['deltas'] = numpy.array([0.05, 0.45, 0.95])
@@ -27,7 +24,7 @@
 #deltas = numpy.array([0.95])
 #deltas = numpy.arange(0.05,1.,0.05)
 #rhos = numpy.array([0.05])
-paramstest['numvects'] = 10; # Number of vectors to generate
+paramstest['numvects'] = 10;  # Number of vectors to generate
 paramstest['SNRdb'] = 20.;    # This is norm(signal)/norm(noise), so power, not energy
 # Values for lambda
 #lambdas = [0 10.^linspace(-5, 4, 10)];
@@ -39,240 +36,73 @@
 
 # Standard parameters 1
 # All algorithms, 100 vectors
-# d=50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-def std1():
-  # Define which algorithms to run
-  algosN = gap,mixed_sl0,mixed_bp,nesta       # tuple of algorithms not depending on lambda
-  algosL = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 50.0;
-  sigma = 2.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 20.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std1.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std1_'
-  saveplotexts = ('png','pdf','eps')
+# d = 50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
+# Noise 40db
+params1 = dict()
+params1['algosN'] = gap,mixed_sl0,mixed_bp,nesta      # tuple of algorithms not depending on lambda
+params1['algosL'] = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst  # tuple of algorithms depending on lambda (ABS-lambda)
+params1['d'] = 50.0
+params1['sigma'] = 2.0
+params1['deltas'] = numpy.arange(0.05,1.,0.05)
+params1['rhos'] = numpy.arange(0.05,1.,0.05)
+params1['numvects'] = 10;  # Number of vectors to generate
+params1['SNRdb'] = 40.;    # This is norm(signal)/norm(noise), so power, not energy
+params1['lambdas'] = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
+params1['savedataname'] = 'approx_pt_stdtest.mat'
+params1['saveplotbase'] = 'approx_pt_stdtest_'
+params1['saveplotexts'] = ('png','pdf','eps')
 
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
-          
-         
 # Standard parameters 2
 # All algorithms, 100 vectors
-# d=20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-def std2():
-  # Define which algorithms to run
-  algosN = gap,mixed_sl0,mixed_bp,nesta      # tuple of algorithms not depending on lambda
-  algosL = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst    # tuple of algorithms depending on lambda (our ABS approach)
+# d = 20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
+# Noise 40db
+params2 = dict()
+params2['algosN'] = gap,mixed_sl0,mixed_bp,nesta      # tuple of algorithms not depending on lambda
+params2['algosL'] = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst  # tuple of algorithms depending on lambda (ABS-lambda)
+params2['d'] = 20.0
+params2['sigma'] = 10.0
+params2['deltas'] = numpy.arange(0.05,1.,0.05)
+params2['rhos'] = numpy.arange(0.05,1.,0.05)
+params2['numvects'] = 10;  # Number of vectors to generate
+params2['SNRdb'] = 40.;    # This is norm(signal)/norm(noise), so power, not energy
+params2['lambdas'] = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
+params2['savedataname'] = 'approx_pt_stdtest.mat'
+params2['saveplotbase'] = 'approx_pt_stdtest_'
+params2['saveplotexts'] = ('png','pdf','eps')
   
-  d = 20.0
-  sigma = 10.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 20.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
   
-  dosavedata = True
-  savedataname = 'approx_pt_std2.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std2_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
-  
-  
-  # Standard parameters 3
+# Standard parameters 3
 # All algorithms, 100 vectors
-# d=50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# IDENTICAL with 1 but with 10dB SNR noise
-def std3():
-  # Define which algorithms to run
-  algosN = gap,mixed_sl0,mixed_bp,nesta        # tuple of algorithms not depending on lambda
-  algosL = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 50.0;
-  sigma = 2.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 10.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std3.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std3_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
+# d = 50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
+# Identical with 1 but with 20dB SNR noise
+params3 = dict()
+params3['algosN'] = gap,mixed_sl0,mixed_bp,nesta      # tuple of algorithms not depending on lambda
+params3['algosL'] = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst  # tuple of algorithms depending on lambda (ABS-lambda)
+params3['d'] = 50.0
+params3['sigma'] = 2.0
+params3['deltas'] = numpy.arange(0.05,1.,0.05)
+params3['rhos'] = numpy.arange(0.05,1.,0.05)
+params3['numvects'] = 10;  # Number of vectors to generate
+params3['SNRdb'] = 20.;    # This is norm(signal)/norm(noise), so power, not energy
+params3['lambdas'] = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
+params3['savedataname'] = 'approx_pt_stdtest.mat'
+params3['saveplotbase'] = 'approx_pt_stdtest_'
+params3['saveplotexts'] = ('png','pdf','eps')
           
 # Standard parameters 4
 # All algorithms, 100 vectors
-# d=20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# Identical to 2 but with 10dB SNR noise
-def std4():
-  # Define which algorithms to run
-  algosN = gap,mixed_sl0,mixed_bp,nesta    # tuple of algorithms not depending on lambda
-  algosL = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 20.0
-  sigma = 10.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 10.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std4.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std4_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
-          
-# Standard parameters 1nesta
-# Only NESTA, 100 vectors
-# d=50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# Identical to std1 but with only NESTA
-def std1nesta():
-  # Define which algorithms to run
-  algosN = nesta,               # tuple of algorithms not depending on lambda
-  algosL = ()    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 50.0;
-  sigma = 2.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 20.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std1nesta.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std1nesta_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts    
-          
-# Standard parameters 2nesta
-# Only NESTA, 100 vectors
-# d=20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# Identical with std2, but with only NESTA
-def std2nesta():
-  # Define which algorithms to run
-  algosN = nesta,      # tuple of algorithms not depending on lambda
-  algosL = ()    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 20.0
-  sigma = 10.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 20.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std2nesta.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std2nesta_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
-
-  # Standard parameters 3nesta
-# Only NESTA, 100 vectors
-# d=50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# IDENTICAL with 3 but with only NESTA
-def std3nesta():
-  # Define which algorithms to run
-  algosN = nesta,               # tuple of algorithms not depending on lambda
-  algosL = ()    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 50.0;
-  sigma = 2.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 10.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std3nesta.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std3nesta_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
-          
-# Standard parameters 4nesta
-# Only NESTA, 100 vectors
-# d=20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
-# Identical to 4 but with only NESTA
-def std4nesta():
-  # Define which algorithms to run
-  algosN = nesta,      # tuple of algorithms not depending on lambda
-  algosL = ()    # tuple of algorithms depending on lambda (our ABS approach)
-  
-  d = 20.0
-  sigma = 10.0
-  deltas = numpy.arange(0.05,1.,0.05)
-  rhos = numpy.arange(0.05,1.,0.05)
-  numvects = 100; # Number of vectors to generate
-  SNRdb = 10.;    # This is norm(signal)/norm(noise), so power, not energy
-  # Values for lambda
-  #lambdas = [0 10.^linspace(-5, 4, 10)];
-  lambdas = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
-  
-  dosavedata = True
-  savedataname = 'approx_pt_std4nesta.mat'
-  doshowplot = False
-  dosaveplot = True
-  saveplotbase = 'approx_pt_std4nesta_'
-  saveplotexts = ('png','pdf','eps')
-
-  return algosN,algosL,d,sigma,deltas,rhos,lambdas,numvects,SNRdb,dosavedata,savedataname,\
-          doshowplot,dosaveplot,saveplotbase,saveplotexts
\ No newline at end of file
+# d = 20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
+# Identical to 2 but with 20dB SNR noise
+params4 = dict()
+params4['algosN'] = gap,mixed_sl0,mixed_bp,nesta      # tuple of algorithms not depending on lambda
+params4['algosL'] = lambda_sl0,lambda_bp,lambda_ompeps,lambda_tst  # tuple of algorithms depending on lambda (ABS-lambda)
+params4['d'] = 20.0
+params4['sigma'] = 10.0
+params4['deltas'] = numpy.arange(0.05,1.,0.05)
+params4['rhos'] = numpy.arange(0.05,1.,0.05)
+params4['numvects'] = 10;  # Number of vectors to generate
+params4['SNRdb'] = 20.;    # This is norm(signal)/norm(noise), so power, not energy
+params4['lambdas'] = numpy.array([0., 0.0001, 0.01, 1, 100, 10000])
+params4['savedataname'] = 'approx_pt_stdtest.mat'
+params4['saveplotbase'] = 'approx_pt_stdtest_'
+params4['saveplotexts'] = ('png','pdf','eps')
--- a/stdparams_exact.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/stdparams_exact.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,13 +1,20 @@
 # -*- coding: utf-8 -*-
 """
-Created on Wed Dec 07 14:04:40 2011
+Defines standard parameters for exact reconstruction simulation
+Author: Nicolae Cleju
+"""
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
 
-@author: ncleju
-"""
 
 import numpy
+
+# Solver algorithms to run
 from algos import *
 
+
+# Test parameters
 paramstest = dict()
 paramstest['algos'] = exact_gap,exact_sl0,exact_bp,exact_ompeps,exact_tst       # tuple of algorithms
 #paramstest['algos'] = exact_bp_cvxopt,       # tuple of algorithms
@@ -26,11 +33,11 @@
 
 # Standard parameters 1
 # All algorithms, 100 vectors
-# d=50, sigma = 2, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
+# d = 200, sigma = 1.2, delta and rho full resolution (0.05 step)
+# Virtually no noise (100db)
 params1 = dict()
 params1['algos'] = exact_gap,exact_sl0,exact_bp_cvxopt,exact_ompeps,exact_tst       # tuple of algorithms
-params1['d'] = 50.0;
+params1['d'] = 200.0;
 params1['sigma'] = 1.2
 params1['deltas'] = numpy.arange(0.05,1.,0.05)
 params1['rhos'] = numpy.arange(0.05,1.,0.05)
@@ -43,8 +50,8 @@
         
 # Standard parameters 2
 # All algorithms, 100 vectors
-# d=20, sigma = 10, delta and rho full resolution (0.05 step), lambdas = 0, 1e-4, 1e-2, 1, 100, 10000
-# Do save data, do save plots, don't show plots
+# d = 20, sigma = 10, delta and rho full resolution (0.05 step)
+# Virtually no noise (100db)
 params2 = dict()
 params2['algos'] = exact_gap,exact_sl0,exact_bp_cvxopt,exact_ompeps,exact_tst       # tuple of algorithms
 params2['d'] = 20.0
--- a/test_approx.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/test_approx.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,16 +1,22 @@
 # -*- coding: utf-8 -*-
 """
-Created on Sat Nov 05 18:08:40 2011
+Main script for approximate reconstruction tests.
+Author: Nicolae Cleju
+"""
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
 
-@author: Nic
-"""
 
 import numpy
 import scipy.io
 import math
 import os
 import time
+import multiprocessing
+import sys
 
+# Try to do smart importing of matplotlib
 try:
   import matplotlib
   if os.name == 'nt':
@@ -26,14 +32,15 @@
   print "Importing matplotlib.pyplot failed. No figures at all"
   print "Try selecting a different backend"
 
-import multiprocessing
-import sys
 currmodule = sys.modules[__name__]
-# Lock for printing in a thread-safe way
-printLock = None
+printLock = None # Lock for printing in a thread-safe way
+ # Thread-safe variable to store number of finished tasks
 proccount = multiprocessing.Value('I', 0) # 'I' = unsigned int, see docs (multiprocessing, array)
 
+# Contains pre-defined simulation parameters
 import stdparams_approx
+
+# Analysis operator and data generation functions
 import AnalysisGenerate
 
 # For exceptions
@@ -41,6 +48,8 @@
 import pyCSalgos.BP.l1qc
 import pyCSalgos.NESTA.NESTA
 
+
+
 def initProcess(share, ntasks, printLock):
     """
     Pool initializer function (multiprocessing)
@@ -55,7 +64,7 @@
 
 def generateTaskParams(globalparams):
   """
-  Generate a list of task parameters
+  Generate a list of task parameters (for parallel running)
   """
   taskparams = []
   SNRdb = globalparams['SNRdb'] 
@@ -208,7 +217,8 @@
 
 def plot(savedataname):
   """
-  Plot results
+  Plot results from a mat file.
+  The files are saved in the current folder.
   """
   params, procresults = loadSim(savedataname)
   meanmatrix = procresults['meanmatrix']
@@ -234,9 +244,12 @@
 # Main function
 #==========================
 def run(params):
-
+  """
+  Run simulation with given parameters
+  """
+  
   print "This is analysis recovery ABS approximation script by Nic"
-  print "Running phase transition ( run_multi() )"
+  print "Running simulation"
 
   algosN = params['algosN']
   algosL = params['algosL']
@@ -295,16 +308,30 @@
   print "Finished."
   
 def run_once_tuple(t):
+  """
+  Wrapper for run_once() that explodes the tuple argument t and shows
+  the number of finished / remaining tasks
+  """
+    
+  # Call run_once() here  
   results = run_once(*t)
-  import sys
-  currmodule = sys.modules[__name__]  
-  currmodule.proccount.value = currmodule.proccount.value + 1
-  print "================================"
-  print "Finished task",currmodule.proccount.value,"of",currmodule.ntasks
-  print "================================"
+  
+  if currmodule.printLock:
+    currmodule.printLock.acquire()  
+    
+    currmodule.proccount.value = currmodule.proccount.value + 1
+    print "================================"
+    print "Finished task",currmodule.proccount.value,"of",currmodule.ntasks
+    print "================================"
+    
+    currmodule.printLock.release()
+    
   return results
 
 def run_once(algosN,algosL,Omega,y,lambdas,realnoise,M,x0):
+  """
+  Run single task (i.e. task function)
+  """
   
   d = Omega.shape[1]  
   
@@ -374,39 +401,20 @@
   
   return mrelerrN,mrelerrL,elapsed
 
-
-def runsingleexampledebug():
-  d = 50.0;
-  sigma = 2.0
-  delta = 0.9
-  rho = 0.05
-  numvects = 20; # Number of vectors to generate
-  SNRdb = 7.;    # This is norm(signal)/norm(noise), so power, not energy
-  lbd = 10000
-  
-  Omega,x0,y,M,realnoise = generateData(d,sigma,delta,rho,numvects,SNRdb)
-  D = numpy.linalg.pinv(Omega)
-  U,S,Vt = numpy.linalg.svd(D)
+def generateFig():
+  """
+  Generates figures. 
+  Figures are saved in the current folder.
+  """
+  run(stdparams_exact.std1)
+  plot(stdparams_exact.std1['savedataname'])
  
-  xrec   = numpy.zeros((d, y.shape[1]))
-  err    = numpy.zeros((y.shape[1]))
-  relerr = numpy.zeros((y.shape[1]))  
- 
-  for iy in numpy.arange(y.shape[1]):
-    epsilon = 1.1 * numpy.linalg.norm(realnoise[:,iy])
-    gamma = run_sl0(y[:,iy],M,Omega,D,U,S,Vt,epsilon,lbd)
-    xrec[:,iy] = numpy.dot(D,gamma)
-    err[iy]    = numpy.linalg.norm(x0[:,iy] - xrec[:,iy])
-    relerr[iy] = err[iy] / numpy.linalg.norm(x0[:,iy])    
-  
-  print "Finished runsingleexampledebug()"
-  
 # Script main
 if __name__ == "__main__":
-  #import cProfile
-  #cProfile.run('mainrun()', 'profile')    
-  #runsingleexampledebug()
+
+  generateFig()
   
-  stdparams_approx.paramstest['ncpus'] = 1
-  run(stdparams_approx.paramstest)
-  plot(stdparams_approx.paramstest['savedataname'])
+  # Run test parameters
+  #stdparams_approx.paramstest['ncpus'] = 1
+  #run(stdparams_approx.paramstest)
+  #plot(stdparams_approx.paramstest['savedataname'])
--- a/test_exact.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/test_exact.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,16 +1,22 @@
 # -*- coding: utf-8 -*-
 """
-Created on Sat Nov 05 18:08:40 2011
+Main script for exact reconstruction tests.
+Author: Nicolae Cleju
+"""
+__author__ = "Nicolae Cleju"
+__license__ = "GPL"
+__email__ = "nikcleju@gmail.com"
 
-@author: Nic
-"""
 
 import numpy
 import scipy.io
 import math
 import os
 import time
+import multiprocessing
+import sys
 
+# Try to do smart importing of matplotlib
 try:
   import matplotlib
   if os.name == 'nt':
@@ -26,15 +32,15 @@
   print "Importing matplotlib.pyplot failed. No figures at all"
   print "Try selecting a different backend"
 
-import multiprocessing
-import sys
 currmodule = sys.modules[__name__]
-# Lock for printing in a thread-safe way
-printLock = None
-# Thread-safe variable to store number of finished tasks
+printLock = None  # Lock for printing in a thread-safe way
+ # Thread-safe variable to store number of finished tasks
 currmodule.proccount = multiprocessing.Value('I', 0) # 'I' = unsigned int, see docs (multiprocessing, array)
 
+# Contains pre-defined simulation parameters
 import stdparams_exact
+
+# Analysis operator and data generation functions
 import AnalysisGenerate
 
 # For exceptions
@@ -42,6 +48,7 @@
 import pyCSalgos.NESTA.NESTA
 
 
+
 def initProcess(share, ntasks, printLock):
     """
     Pool initializer function (multiprocessing)
@@ -57,7 +64,7 @@
 
 def generateTaskParams(globalparams):
   """
-  Generate a list of task parameters
+  Generate a list of task parameters (for parallel running)
   """
   taskparams = []
   SNRdb = globalparams['SNRdb'] 
@@ -184,7 +191,8 @@
 
 def plot(savedataname):
   """
-  Plot results
+  Plot results from a mat file.
+  The files are saved in the current folder.
   """
   params, procresults = loadSim(savedataname)
   meanmatrix = procresults['meanmatrix']
@@ -204,11 +212,11 @@
 #==========================
 def run(params):
   """
-  Run with given parameters
+  Run simulation with given parameters
   """
 
-  print "This is analysis recovery ABS approximation script by Nic"
-  print "Running phase transition ( run_multi() )"
+  print "This is analysis recovery ABS exact script by Nic"
+  print "Running simulation
 
   algos = params['algos']
   d = params['d']
@@ -265,6 +273,12 @@
   print "Finished."
   
 def run_once_tuple(t):
+  """
+  Wrapper for run_once() that explodes the tuple argument t and shows
+  the number of finished / remaining tasks
+  """
+  
+  # Call run_once() here
   results = run_once(*t)
   
   if currmodule.printLock:
@@ -281,7 +295,7 @@
 
 def run_once(algos,Omega,y,M,x0):
   """
-  Run single task (task function)
+  Run single task (i.e. task function)
   """
   
   d = Omega.shape[1]  
@@ -326,7 +340,6 @@
   #  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:
@@ -335,20 +348,30 @@
 
   
 def testMatlab():
+    """
+    For debugging only.
+    Load parameters from a mat file saved by Matlab.
+    """
     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():
+  """
+  Generates figures from paper "Analysis-based sparse reconstruction with synthesis-based solvers".
+  The figures are saved in the current folder.
+  """
   run(stdparams_exact.std1)
+  plot(stdparams_exact.std1['savedataname'])
   
 # Script main
 if __name__ == "__main__":
-  #import cProfile
-  #cProfile.run('mainrun()', 'profile')    
-  #run_mp(stdparams_exact.stdtest)
-  #runsingleexampledebug()
   
-  stdparams_exact.paramstest['ncpus'] = 1
-  run(stdparams_exact.paramstest)
-  plot(stdparams_exact.paramstest['savedataname'])
+  # Set the number of cpus for paraller running (or comment to leave default = max)
+  #stdparams_exact.paramstest['ncpus'] = 1
+  
+  generateFig()
+
+  # Run test parameters
+  #run(stdparams_exact.paramstest)
+  #plot(stdparams_exact.paramstest['savedataname'])
--- a/test_exact_old.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/test_exact_old.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 """
-Created on Sat Nov 05 18:08:40 2011
+Old version, ignore it
 
-@author: Nic
+Author: Nicolae Cleju
 """
 
 import numpy
--- a/utils.py	Tue Apr 03 10:18:11 2012 +0300
+++ b/utils.py	Tue Apr 03 16:27:18 2012 +0300
@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 """
-Created on Wed Nov 09 12:28:55 2011
+Some utility functions.
 
-@author: ncleju
+Author: Nicolae Cleju
 """
 
 import numpy