changeset 140:31d2864dfdd4 ivand_dev

Audio Impainting additional constraints with cvx added
author Ivan Damnjanovic lnx <ivan.damnjanovic@eecs.qmul.ac.uk>
date Mon, 25 Jul 2011 17:27:05 +0100
parents 4bd6856a7128
children b8db4285e0ca
files Problems/AudioDeclipping_reconstruct.m Problems/generateAudioDeclippingProblem.m SMALLboxSetup.m examples/AudioInpainting/Audio_Declipping_Example.m solvers/CVX_add_const_Audio_declipping.m solvers/SMALL_ompGabor/make.m solvers/SMALL_ompGabor/mexutils.c solvers/SMALL_ompGabor/mexutils.h solvers/SMALL_ompGabor/myblas.c solvers/SMALL_ompGabor/myblas.h solvers/SMALL_ompGabor/omp2Gabor.m solvers/SMALL_ompGabor/omp2mex.c solvers/SMALL_ompGabor/omp2mex.m solvers/SMALL_ompGabor/omp2mexGabor.c solvers/SMALL_ompGabor/omp2mexGabor.m solvers/SMALL_ompGabor/ompGabor.m solvers/SMALL_ompGabor/ompcore.c solvers/SMALL_ompGabor/ompcore.h solvers/SMALL_ompGabor/ompcoreGabor.c solvers/SMALL_ompGabor/ompcoreGabor.h solvers/SMALL_ompGabor/ompmex.c solvers/SMALL_ompGabor/ompmex.m solvers/SMALL_ompGabor/ompmexGabor.c solvers/SMALL_ompGabor/ompmexGabor.m solvers/SMALL_ompGabor/ompprof.c solvers/SMALL_ompGabor/ompprof.h solvers/SMALL_ompGabor/omputils.c solvers/SMALL_ompGabor/omputils.h solvers/SMALL_ompGabor/printf.m toolboxes/AudioInpaintingToolbox/Experiments/DeclippingExperiment/declipOneSoundExperiment.m util/SMALL_init_solver.m util/SMALL_solve.m util/ksvd utils/ompbox utils/make.m util/ksvd utils/ompbox utils/mexutils.c util/ksvd utils/ompbox utils/mexutils.h util/ksvd utils/ompbox utils/myblas.c util/ksvd utils/ompbox utils/myblas.h util/ksvd utils/ompbox utils/omp2Gabor.m util/ksvd utils/ompbox utils/omp2mex.c util/ksvd utils/ompbox utils/omp2mex.m util/ksvd utils/ompbox utils/omp2mexGabor.c util/ksvd utils/ompbox utils/omp2mexGabor.m util/ksvd utils/ompbox utils/ompGabor.m util/ksvd utils/ompbox utils/ompcore.c util/ksvd utils/ompbox utils/ompcore.h util/ksvd utils/ompbox utils/ompcoreGabor.c util/ksvd utils/ompbox utils/ompcoreGabor.h util/ksvd utils/ompbox utils/ompmex.c util/ksvd utils/ompbox utils/ompmex.m util/ksvd utils/ompbox utils/ompmexGabor.c util/ksvd utils/ompbox utils/ompmexGabor.m util/ksvd utils/ompbox utils/ompprof.c util/ksvd utils/ompbox utils/ompprof.h util/ksvd utils/ompbox utils/omputils.c util/ksvd utils/ompbox utils/omputils.h util/ksvd utils/ompbox utils/printf.m
diffstat 56 files changed, 4187 insertions(+), 4021 deletions(-) [+]
line wrap: on
line diff
--- a/Problems/AudioDeclipping_reconstruct.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/Problems/AudioDeclipping_reconstruct.m	Mon Jul 25 17:27:05 2011 +0100
@@ -2,8 +2,15 @@
 %%  Audio declipping Problem reconstruction function
 %   
 %   This reconstruction function is using sparse representation y 
-%   in dictionary Problem.A to reconstruct the patches of the denoised
-%   image.
+%   in dictionary Problem.A to reconstruct declipped audio.
+%
+%   [1] I. Damnjanovic, M. E. P. Davies, and M. P. Plumbley "SMALLbox - an 
+%   evaluation framework for sparse representations and dictionary 
+%   learning algorithms," V. Vigneron et al. (Eds.): LVA/ICA 2010, 
+%   Springer-Verlag, Berlin, Germany, LNCS 6365, pp. 418-425
+%   [2] A. Adler, V. Emiya, M. G. Jafari, M. Elad, R. Gribonval, and M. D.
+%   Plumbley, “Audio Inpainting,” submitted to IEEE Trans. Audio, Speech,
+%   and Lang. Proc., 2011, http://hal.inria.fr/inria-00577079/en/.
 
 %
 %   Centre for Digital Music, Queen Mary, University of London.
--- a/Problems/generateAudioDeclippingProblem.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/Problems/generateAudioDeclippingProblem.m	Mon Jul 25 17:27:05 2011 +0100
@@ -1,26 +1,18 @@
 function data = generateAudioDeclippingProblem(soundfile, clippingLevel, windowSize, overlap, wa, ws, wd, Dict_fun, redundancyFactor)
 %%  Generate Audio Declipping Problem
 %   
-%   CHANGE!!!generateAMT_Learning_Problem is a part of the SMALLbox and generates
-%   a problem that can be used for comparison of Dictionary Learning/Sparse
-%   Representation techniques in automatic music transcription scenario.
-%   The function prompts a user for an audio file (mid, wav, mat) reads it
-%   and generates a spectrogram given fft size (default nfft=4096), analysis
-%   window size (windowSize=2822), and analysis window overlap (overlap =
-%   0.5).
-%   
-%   The output of the function is stucture with following fields:
-%       b - matrix with magnitudes of the spectrogram
-%       f - vector of frequencies at wihch spectrogram is computed
-%       windowSize - analysis window size
-%       overlap - analysis window overlap
-%       fs - sampling frequency
-%       m - number of frequenciy points in spectrogram
-%       n - number of time points in the spectrogram
-%       p - number of dictionary elements to be learned (eg 88 for piano)
-%       notesOriginal - notes of the original audio to be used for
-%                       comparison (if midi of the original exists)
-%       name - name of the audio file to transcribe
+%   generateAudioDeclippingProblem is part of the SMALLbox [1] and generates
+%   Audio declipping is a problem proposed in Audio Inpaining Toolbox and
+%   in [2]. 
+%
+%   [1] I. Damnjanovic, M. E. P. Davies, and M. P. Plumbley "SMALLbox - an 
+%   evaluation framework for sparse representations and dictionary 
+%   learning algorithms," V. Vigneron et al. (Eds.): LVA/ICA 2010, 
+%   Springer-Verlag, Berlin, Germany, LNCS 6365, pp. 418-425
+%   [2] A. Adler, V. Emiya, M. G. Jafari, M. Elad, R. Gribonval, and M. D.
+%   Plumbley, “Audio Inpainting,” submitted to IEEE Trans. Audio, Speech,
+%   and Lang. Proc., 2011, http://hal.inria.fr/inria-00577079/en/.
+
 
 %   Centre for Digital Music, Queen Mary, University of London.
 %   This file copyright 2011 Ivan Damnjanovic.
--- a/SMALLboxSetup.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/SMALLboxSetup.m	Mon Jul 25 17:27:05 2011 +0100
@@ -274,7 +274,15 @@
 end
 
 %%
+%% KSVD utils setup
 
+if ~(exist('addtocols')==3)
+    cd([SMALL_path,FS,'util',FS,'ksvd utils']);
+    make
+    cd(SMALL_path);
+end
+
+%%
 if ~exist('ksvdver.m','file')
     fprintf('\n ******************************************************************');
     fprintf('\n\n Initialising OMPbox and KSVDBox Setup');
@@ -300,9 +308,9 @@
             fprintf('\n\n Downloading toolbox, please be patient\n\n');
         end
         unzip(KSVD_zip,[KSVD_path, FS, 'ksvdbox']);
-%         cd([KSVD_path, FS, 'ksvdbox', FS, 'private']);
-%         make;
-%         cd(SMALL_path);
+        cd([KSVD_path, FS, 'ksvdbox', FS, 'private']);
+        make;
+        cd(SMALL_path);
         KSVD_p=genpath(KSVD_path);
         addpath(KSVD_p);
         fprintf('\n KSVDBox and OMPBox Installation Successful\n');
@@ -392,13 +400,7 @@
     fprintf('\n\n matlab_midi (http://www.kenschutte.com/midi/) is already installed');
 end
 
-%% KSVD utils setup
 
-if ~(exist('addtocols')==3)
-    cd([SMALL_path,FS,'util',FS,'ksvd utils']);
-    make
-    cd(SMALL_path);
-end
 
 %% RWT setup
 if ~(exist('mdwt')==3)
--- a/examples/AudioInpainting/Audio_Declipping_Example.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/examples/AudioInpainting/Audio_Declipping_Example.m	Mon Jul 25 17:27:05 2011 +0100
@@ -1,11 +1,16 @@
 %%  Audio Declipping Example
 %   
-%   CHANGE!!! This example is based on the experiment suggested by Professor Pierre
-%   Vandergheynst on the SMALL meeting in Villars.
-%   The idea behind is to use patches from source image as a dictionary in
-%   which we represent target image using matching pursuit algorithm.
-%   Calling Pierre_Problem function to get src image to be used as dictionary
-%   and target image to be represented using MP with 3 patches from source image
+%   Audio declipping is a problem proposed in Audio Inpaining Toolbox and
+%   in [2]. This is an example of solving the problem with fast omp using
+%   Gabor dictionary and ompGabor implemented in SMALLbox [1].
+%
+%   [1] I. Damnjanovic, M. E. P. Davies, and M. P. Plumbley "SMALLbox - an 
+%   evaluation framework for sparse representations and dictionary 
+%   learning algorithms," V. Vigneron et al. (Eds.): LVA/ICA 2010, 
+%   Springer-Verlag, Berlin, Germany, LNCS 6365, pp. 418-425
+%   [2] A. Adler, V. Emiya, M. G. Jafari, M. Elad, R. Gribonval, and M. D.
+%   Plumbley, “Audio Inpainting,” submitted to IEEE Trans. Audio, Speech,
+%   and Lang. Proc., 2011, http://hal.inria.fr/inria-00577079/en/.
 
 %
 %   Centre for Digital Music, Queen Mary, University of London.
@@ -20,88 +25,123 @@
 %%
 
 clear all;
+%   Defining the solvers to test in Audio declipping scenario
+
+% First solver omp2 - DCT+DST dictionary  with no additional constraints
+
+SMALL.solver(1) = SMALL_init_solver('ompbox', 'omp2', '', 0);
+SMALL.solver(1).add_constraints = 0;
+
+% Second solver omp2 - DCT+DST dictionary  with additional constraints
+
+SMALL.solver(2) = SMALL_init_solver('ompbox', 'omp2', '', 0);
+SMALL.solver(2).add_constraints = 1;
+
+% Third solver omp2 - Gabor dictionary with no additional constraints
+
+SMALL.solver(3) = SMALL_init_solver('ompbox', 'omp2Gabor', '', 0);
+SMALL.solver(3).add_constraints = 0;
+
+% Fourth solver omp2- Gabor dictionary with no additional constraints
+
+SMALL.solver(4) = SMALL_init_solver('ompbox', 'omp2Gabor', '', 0);
+SMALL.solver(4).add_constraints = 1;
 
 %   Defining the Problem structure
 
 SMALL.Problem = generateAudioDeclippingProblem('male01_8kHz.wav', 0.6, 256, 0.5, @wRect, @wSine, @wRect, @Gabor_Dictionary, 2);
 
-% %   Show original image and image that is used as a dictionary
-% figure('Name', 'Original and Dictionary Image');
-% 
-% subplot(1,2,1); imagesc(SMALL.Problem.imageTrg/SMALL.Problem.maxval);
-% title('Original Image');colormap(gray);axis off; axis image;
-% subplot(1,2,2); imagesc(SMALL.Problem.imageSrc/SMALL.Problem.maxval);
-% title('Dictionary image:');colormap(gray);axis off; axis image;
-time=0;
-error2=0.001^2;
-coeffFrames = zeros(SMALL.Problem.p, SMALL.Problem.n);
-
-for i=1:SMALL.Problem.n
+for idxSolver = 1:4
     
-    idx = find(SMALL.Problem.M(:,i));
-    if size(idx,1)==SMALL.Problem.m
-        continue
+    fprintf('\nStarting Audio Declipping of %s... \n', SMALL.Problem.name);
+    fprintf('\nClipping level %s... \n', SMALL.Problem.clippingLevel);
+    
+    start=cputime;
+    tStart=tic;
+    
+    error2=0.001^2;
+    coeffFrames = zeros(SMALL.Problem.p, SMALL.Problem.n);
+    
+    
+    
+    for i = 1:SMALL.Problem.n
+        
+        idx = find(SMALL.Problem.M(:,i));
+        if size(idx,1)==SMALL.Problem.m
+            continue
+        end
+        Dict = SMALL.Problem.B(idx,:);
+        wDict = 1./sqrt(diag(Dict'*Dict));
+        
+        SMALL.Problem.A  = Dict*diag(wDict);
+        
+        SMALL.Problem.b1 = SMALL.Problem.b(idx,i);
+        
+        
+        
+        % set solver parameters
+        
+        SMALL.solver(idxSolver).param=struct(...
+            'epsilon', error2*size(idx,1),...
+            'maxatoms', 128, ...
+            'profile', 'off');
+        
+        % Find solution
+        
+        SMALL.solver(idxSolver)=SMALL_solve(SMALL.Problem, SMALL.solver(idxSolver));
+        
+        % Refine solution with additional constraints for declipping scenario
+        
+        if (SMALL.solver(idxSolver).add_constraints)
+            SMALL.solver(idxSolver)=CVX_add_const_Audio_declipping(...
+                SMALL.Problem, SMALL.solver(idxSolver), i);
+        end
+        
+        %%
+        coeffFrames(:,i) = wDict .* SMALL.solver(idxSolver).solution;
+        
+        
     end
-    Dict = SMALL.Problem.B(idx,:);
-    wDict = 1./sqrt(diag(Dict'*Dict));
     
-    SMALL.Problem.A  = Dict*diag(wDict);
+    %%   Set reconstruction function
     
-    SMALL.Problem.b1 = SMALL.Problem.b(idx,i);
+    SMALL.Problem.reconstruct=@(x) AudioDeclipping_reconstruct(x, SMALL.Problem);
+    reconstructed=SMALL.Problem.reconstruct(coeffFrames);
+    SMALL.Problem = rmfield(SMALL.Problem, 'reconstruct');
+    tElapsed=toc(tStart);
     
+    SMALL.solver(idxSolver).time = cputime - start;
+    fprintf('Solver %s finished task in %2f seconds (cpu time). \n', ...
+        SMALL.solver(idxSolver).name, SMALL.solver(idxSolver).time);
+    fprintf('Solver %s finished task in %2f seconds (tic-toc time). \n', ...
+        SMALL.solver(idxSolver).name, tElapsed);
     
     
-    %   Defining the parameters sparse representation
-    SMALL.solver=SMALL_init_solver;
-    SMALL.solver.toolbox='ompbox';
-    SMALL.solver.name='omp2Gabor';
     
-    SMALL.solver.param=struct(...
-        'epsilon', error2*size(idx,1),...
-        'maxatoms', 128); 
+    %% Plot results
     
-    % Find solution
+    xClipped = SMALL.Problem.clipped;
+    xClean   = SMALL.Problem.original;
+    xEst1    = reconstructed.audioAllSamples;
+    xEst2    = reconstructed.audioOnlyClipped;
+    fs       = SMALL.Problem.fs;
     
-    SMALL.solver=SMALL_solve(SMALL.Problem, SMALL.solver);
-    
-    
-    coeffFrames(:,i) = wDict .* SMALL.solver.solution;
-    time = time + SMALL.solver.time;
-    
-    
-      
+    figure
+    hold on
+    plot(xClipped,'r')
+    plot(xClean)
+    plot(xEst2,'--g')
+    plot([1;length(xClipped)],[1;1]*[-1,1]*max(abs(xClipped)),':r')
+    legend('Clipped','True solution','Estimate')
 end
 
-%%   Set reconstruction function
-
-SMALL.Problem.reconstruct=@(x) AudioDeclipping_reconstruct(x, SMALL.Problem);
-reconstructed=SMALL.Problem.reconstruct(coeffFrames);
-
-
-
-%% Plot results
-
-xClipped = SMALL.Problem.clipped;
-xClean   = SMALL.Problem.original;
-xEst1    = reconstructed.audioAllSamples;
-xEst2    = reconstructed.audioOnlyClipped;
-fs       = SMALL.Problem.fs;
-
-figure
-hold on
-plot(xClipped,'r')
-plot(xClean)
-plot(xEst2,'--g')
-plot([1;length(xClipped)],[1;1]*[-1,1]*max(abs(xClipped)),':r')
-legend('Clipped','True solution','Estimate')
-
-% Normalized and save sounds
-normX = 1.1*max(abs([xEst1(:);xEst2(:);xClean(:)]));
-L = min([length(xEst2),length(xEst1),length(xClean),length(xEst1),length(xClipped)]);
-xEst1 = xEst1(1:L)/normX;
-xEst2 = xEst2(1:L)/normX;
-xClipped = xClipped(1:L)/normX;
-xClean = xClean(1:L)/normX;
+% % Normalized and save sounds
+% normX = 1.1*max(abs([xEst1(:);xEst2(:);xClean(:)]));
+% L = min([length(xEst2),length(xEst1),length(xClean),length(xEst1),length(xClipped)]);
+% xEst1 = xEst1(1:L)/normX;
+% xEst2 = xEst2(1:L)/normX;
+% xClipped = xClipped(1:L)/normX;
+% xClean = xClean(1:L)/normX;
 % wavwrite(xEst1,fs,[expParam.destDir 'xEst1.wav']);
 % wavwrite(xEst2,fs,[expParam.destDir 'xEst2.wav']);
 % wavwrite(xClipped,fs,[expParam.destDir 'xClipped.wav']);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/CVX_add_const_Audio_declipping.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,85 @@
+function solver=CVX_add_const_Audio_declipping(Problem, solver, idxFrame)
+
+%% CVX additional constrains 
+    % Clipping level: take the analysis window into account
+    % clipping level detection
+    
+    signal = Problem.b1;
+    signalFull = Problem.b(:,idxFrame);
+    Dict = Problem.A;
+    DictFull = Problem.B;
+    Clipped = ~Problem.M(:,idxFrame);
+    W=1./sqrt(diag(Dict'*Dict));
+    
+    idxCoeff = find(solver.solution~=0);
+    
+    solution = solver.solution;
+    
+    wa = Problem.wa(Problem.windowSize); % analysis window
+    
+    
+    clippingLevelEst = max(abs(signal./wa(~Clipped)'));
+
+    idxPos = find(signalFull>=0 & Clipped);
+    idxNeg = find(signalFull<0  & Clipped);
+
+    DictPos=DictFull(idxPos,:);
+    DictNeg=DictFull(idxNeg,:);
+    
+    
+    wa_pos = wa(idxPos);
+    wa_neg = wa(idxNeg);
+    b_ineq_pos = wa_pos(:)*clippingLevelEst;
+    b_ineq_neg = -wa_neg(:)*clippingLevelEst;
+    if isfield(Problem,'Upper_Limit') && ~isempty(Problem.Upper_Limit)
+        b_ineq_pos_upper_limit = wa_pos(:)*Problem.Upper_Limit*clippingLevelEst;
+        b_ineq_neg_upper_limit = -wa_neg(:)*Problem.Upper_Limit*clippingLevelEst;
+    else
+        b_ineq_pos_upper_limit = Inf;
+        b_ineq_neg_upper_limit = -Inf;
+    end
+    
+    
+    j = length(idxCoeff);
+    
+    if isinf(b_ineq_pos_upper_limit)
+        %% CVX code
+        cvx_begin
+        cvx_quiet(true)
+        variable solution(j)
+        minimize(norm(Dict(:,idxCoeff)*solution-signal))
+        subject to
+        DictPos(:,idxCoeff)*(W(idxCoeff).*solution) >= b_ineq_pos
+        DictNeg(:,idxCoeff)*(W(idxCoeff).*solution) <= b_ineq_neg
+        cvx_end
+        if cvx_optval>1e3
+            cvx_begin
+            cvx_quiet(true)
+            variable solution(j)
+            minimize(norm(Dict(:,idxCoeff)*solution-xObs))
+            cvx_end
+        end
+    else
+        %% CVX code
+        cvx_begin
+        cvx_quiet(true)
+        variable solution(j)
+        minimize(norm(Dict(:,idxCoeff)*solution-signal))
+        subject to
+        DictPos(:,idxCoeff)*(W(idxCoeff).*solution) >= b_ineq_pos
+        DictNeg(:,idxCoeff)*(W(idxCoeff).*solution) <= b_ineq_neg
+        DictPos(:,idxCoeff)*(W(idxCoeff).*solution) <= b_ineq_pos_upper_limit
+        DictNeg(:,idxCoeff)*(W(idxCoeff).*solution) >= b_ineq_neg_upper_limit
+        cvx_end
+        if cvx_optval>1e3
+            cvx_begin
+            cvx_quiet(true)
+            variable solution(j)
+            minimize(norm(Dict(:,idxCoeff)*solution-xObs))
+            cvx_end
+        end
+    end
+ 
+   solver.solution(idxCoeff) = solution;
+    
+   
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/make.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,41 @@
+function make
+%MAKE Build the OMPBox package.
+%  MAKE compiles all OMPBox MEX functions, using Matlab's default MEX
+%  compiler. If the MEX compiler has not been set-up before, please run
+%
+%    mex -setup
+%
+%  before using this MAKE file.
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  August 2009
+
+
+% detect platform 
+
+compstr = computer;
+is64bit = strcmp(compstr(end-1:end),'64');
+
+
+% compilation parameters
+
+compile_params = cell(0);
+if (is64bit)
+  compile_params{1} = '-largeArrayDims';
+end
+
+
+% Compile files %
+
+ompsources = {'mexutils.c','ompcoreGabor.c','omputils.c','myblas.c','ompprof.c'};
+
+disp('Compiling ompmex...');
+mex('ompmexGabor.c', ompsources{:},compile_params{:});
+
+disp('Compiling omp2mex...');
+mex('omp2mexGabor.c',ompsources{:},compile_params{:});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/mexutils.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,79 @@
+/**************************************************************************
+ *
+ * File name: mexutils.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 15.8.2009
+ *
+ *************************************************************************/
+
+#include "mexutils.h"
+#include <math.h>
+
+
+
+/* verify that the mxArray contains a double matrix */
+
+void checkmatrix(const mxArray *param, char *fname, char *pname)
+{
+  char errmsg[100];
+  sprintf(errmsg, "%.15s requires that %.25s be a double matrix.", fname, pname);
+  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2) {
+    mexErrMsgTxt(errmsg);
+  }
+}
+
+
+/* verify that the mxArray contains a 1-D double vector */
+
+void checkvector(const mxArray *param, char *fname, char *pname)
+{
+  char errmsg[100];
+  sprintf(errmsg, "%.15s requires that %.25s be a double vector.", fname, pname);
+  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) {
+    mexErrMsgTxt(errmsg);
+  }
+}
+
+
+/* verify that the mxArray contains a double scalar */
+
+void checkscalar(const mxArray *param, char *fname, char *pname)
+{
+  char errmsg[100];
+  sprintf(errmsg, "%.15s requires that %.25s be a double scalar.", fname, pname);
+  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || 
+      mxGetM(param)!=1 || mxGetN(param)!=1) 
+  {
+    mexErrMsgTxt(errmsg);
+  }
+}
+
+
+/* verify that the mxArray contains a sparse matrix */
+
+void checksparse(const mxArray *param, char *fname, char *pname)
+{
+  char errmsg[100];
+  sprintf(errmsg, "%.15s requires that %.25s be sparse.", fname, pname);
+  if (!mxIsSparse(param)) {
+    mexErrMsgTxt(errmsg);
+  }
+}
+
+
+/* verify that the mxArray contains a 1-dimensional cell array */
+
+void checkcell_1d(const mxArray *param, char *fname, char *pname)
+{
+  char errmsg[100];
+  sprintf(errmsg, "%.15s requires that %.25s be a 1-D cell array.", fname, pname);
+  if (!mxIsCell(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) {
+    mexErrMsgTxt(errmsg);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/mexutils.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,103 @@
+/**************************************************************************
+ *
+ * File name: mexutils.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ * Utility functions for MEX files.
+ *
+ *************************************************************************/
+
+
+#ifndef __MEX_UTILS_H__
+#define __MEX_UTILS_H__
+
+#include "mex.h"
+
+
+
+/**************************************************************************
+ * Function checkmatrix:
+ *
+ * Verify that the specified mxArray is real, of type double, and has 
+ * no more than two dimensions. If not, an error message is printed
+ * and the mex file terminates.
+ * 
+ * Parameters:
+ *   param - the mxArray to be checked
+ *   fname - the name of the function where the error occured (15 characters or less)
+ *   pname - the name of the parameter (25 characters or less)
+ *
+ **************************************************************************/
+void checkmatrix(const mxArray *param, char *fname, char *pname);
+
+
+/**************************************************************************
+ * Function checkvector:
+ *
+ * Verify that the specified mxArray is 1-D, real, and of type double. The
+ * vector may be a column or row vector. Otherwise, an error message is
+ * printed and the mex file terminates.
+ * 
+ * Parameters:
+ *   param - the mxArray to be checked
+ *   fname - the name of the function where the error occured (15 characters or less)
+ *   pname - the name of the parameter (25 characters or less)
+ *
+ **************************************************************************/
+void checkvector(const mxArray *param, char *fname, char *pname);
+
+
+/**************************************************************************
+ * Function checkscalar:
+ *
+ * Verify that the specified mxArray represents a real double scalar value. 
+ * If not, an error message is printed and the mex file terminates.
+ * 
+ * Parameters:
+ *   param - the mxArray to be checked
+ *   fname - the name of the function where the error occured (15 characters or less)
+ *   pname - the name of the parameter (25 characters or less)
+ *
+ **************************************************************************/
+void checkscalar(const mxArray *param, char *fname, char *pname);
+
+
+/**************************************************************************
+ * Function checksparse:
+ *
+ * Verify that the specified mxArray contains a sparse matrix. If not,
+ * an error message is printed and the mex file terminates.
+ * 
+ * Parameters:
+ *   param - the mxArray to be checked
+ *   fname - the name of the function where the error occured (15 characters or less)
+ *   pname - the name of the parameter (25 characters or less)
+ *
+ **************************************************************************/
+void checksparse(const mxArray *param, char *fname, char *pname);
+
+
+/**************************************************************************
+ * Function checkcell_1d:
+ *
+ * Verify that the specified mxArray is a 1-D cell array. The cell array 
+ * may be arranged as either a column or a row. If not, an error message 
+ * is printed and the mex file terminates.
+ * 
+ * Parameters:
+ *   param - the mxArray to be checked
+ *   fname - the name of the function where the error occured (15 characters or less)
+ *   pname - the name of the parameter (25 characters or less)
+ *
+ **************************************************************************/
+void checkcell_1d(const mxArray *param, char *fname, char *pname);
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/myblas.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,673 @@
+/**************************************************************************
+ *
+ * File name: myblas.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Version: 1.1
+ * Last updated: 13.8.2009
+ *
+ *************************************************************************/
+
+
+#include "myblas.h"
+#include <ctype.h>
+
+
+/* find maximum of absolute values */
+
+mwIndex maxabs(double c[], mwSize m)
+{
+  mwIndex maxid=0, k;
+  double absval, maxval = SQR(*c);   /* use square which is quicker than absolute value */
+
+  for (k=1; k<m; ++k) {
+    absval = SQR(c[k]);
+    if (absval > maxval) {
+      maxval = absval;
+      maxid = k;
+    }
+  }
+  return maxid;
+}
+
+
+/* compute y := alpha*x + y */
+
+void vec_sum(double alpha, double x[], double y[], mwSize n)
+{
+  mwIndex i;
+
+  for (i=0; i<n; ++i) {
+    y[i] += alpha*x[i];
+  }
+}
+
+/* compute y := alpha*x .* y */
+
+void vec_smult(double alpha, double x[], double y[], mwSize n)
+{
+  mwIndex i;
+
+  for (i=0; i<n; ++i) {
+    y[i] *= alpha*x[i];
+  }
+}
+
+/* compute y := alpha*A*x */
+
+void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
+{
+  mwIndex i, j, i_n;
+  double *Ax;
+
+  Ax = mxCalloc(n,sizeof(double));
+
+  for (i=0; i<m; ++i) {
+    i_n = i*n;
+    for (j=0; j<n; ++j) {
+      Ax[j] += A[i_n+j] * x[i];
+    }
+  }
+
+  for (j=0; j<n; ++j) {
+    y[j] = alpha*Ax[j];
+  }
+
+  mxFree(Ax);
+}
+
+
+/* compute y := alpha*A'*x */
+
+void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
+{
+  mwIndex i, j, n_i;
+  double sum0, sum1, sum2, sum3;
+
+  for (j=0; j<m; ++j) {
+    y[j] = 0;
+  }
+
+  /* use loop unrolling to accelerate computation */
+
+  for (i=0; i<m; ++i) {
+    n_i = n*i;
+    sum0 = sum1 = sum2 = sum3 = 0;
+    for (j=0; j+4<n; j+=4) {
+      sum0 += A[n_i+j]*x[j];
+      sum1 += A[n_i+j+1]*x[j+1];
+      sum2 += A[n_i+j+2]*x[j+2];
+      sum3 += A[n_i+j+3]*x[j+3];
+    }
+    y[i] += alpha * ((sum0 + sum1) + (sum2 + sum3));
+    while (j<n) {
+      y[i] += alpha*A[n_i+j]*x[j];
+      j++;
+    }
+  }
+}
+
+
+/* compute y := alpha*A*x */
+
+void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, j1, j2;
+
+  for (i=0; i<n; ++i) {
+    y[i] = 0;
+  }
+  
+  j2 = jc[0];
+  for (i=0; i<m; ++i) {
+    j1 = j2; j2 = jc[i+1];
+    for (j=j1; j<j2; ++j) {
+      y[ir[j]] += alpha * pr[j] * x[i];
+    }
+  }
+  
+}
+
+
+/* compute y := alpha*A'*x */
+
+void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, j1, j2;
+  
+  for (i=0; i<m; ++i) {
+    y[i] = 0;
+  }
+  
+  j2 = jc[0];
+  for (i=0; i<m; ++i) {
+    j1 = j2; j2 = jc[i+1];
+    for (j=j1; j<j2; ++j) {
+      y[i] += alpha * pr[j] * x[ir[j]];
+    }
+  }
+  
+}
+
+
+/* compute y := alpha*A*x */
+
+void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, j_n, k, kend;
+  
+  for (i=0; i<n; ++i) {
+    y[i] = 0;
+  }
+  
+  kend = jc[1];
+  if (kend==0) {   /* x is empty */
+    return;
+  }
+  
+  for (k=0; k<kend; ++k) {
+    j = ir[k];
+    j_n = j*n;
+    for (i=0; i<n; ++i) {
+      y[i] += alpha * A[i+j_n] * pr[k];
+    }
+  }
+
+}
+
+
+/* compute y := alpha*A'*x */
+
+void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, j_n, k, kend;
+  
+  for (i=0; i<m; ++i) {
+    y[i] = 0;
+  }
+  
+  kend = jc[1];
+  if (kend==0) {   /* x is empty */
+    return;
+  }
+  
+  for (j=0; j<m; ++j) {
+    j_n = j*n;
+    for (k=0; k<kend; ++k) {
+      i = ir[k];
+      y[j] += alpha * A[i+j_n] * pr[k];
+    }
+  }
+  
+}
+
+
+/* compute y := alpha*A*x */
+
+void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, k, kend, j1, j2;
+
+  for (i=0; i<n; ++i) {
+    y[i] = 0;
+  }
+  
+  kend = jcx[1]; 
+  if (kend==0) {   /* x is empty */
+    return;
+  }
+  
+  for (k=0; k<kend; ++k) {
+    i = irx[k];
+    j1 = jc[i]; j2 = jc[i+1];
+    for (j=j1; j<j2; ++j) {
+      y[ir[j]] += alpha * pr[j] * prx[k];
+    }
+  }
+  
+}
+
+
+/* compute y := alpha*A'*x */
+
+void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
+{
+  
+  mwIndex i, j, k, jend, kend, jadd, kadd, delta;
+  
+  for (i=0; i<m; ++i) {
+    y[i] = 0;
+  }
+  
+  kend = jcx[1];
+  if (kend==0) {   /* x is empty */
+    return;
+  }
+  
+  for (i=0; i<m; ++i) {
+    j = jc[i]; 
+    jend = jc[i+1];
+    k = 0;
+    while (j<jend && k<kend) {
+      
+      delta = ir[j] - irx[k];
+      
+      if (delta) { /* if indices differ - increment the smaller one */
+        jadd = delta<0;
+        kadd = 1-jadd;
+        j += jadd;
+        k += kadd;
+      }
+      
+      else {    /* indices are equal - add to result and increment both */
+        y[i] += alpha * pr[j] * prx[k];
+        j++; k++;
+      }
+    }
+  }
+  
+}
+
+
+/* matrix-matrix multiplication */
+
+void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
+{
+  mwIndex i1, i2, i3, iX, iA, i2_n;
+  double b;
+  
+  for (i1=0; i1<n*k; i1++) {
+    X[i1] = 0;
+  }
+
+  for (i2=0; i2<m; ++i2) {
+    i2_n = i2*n;
+    iX = 0;
+    for (i3=0; i3<k; ++i3) {
+      iA = i2_n;
+      b = B[i2+i3*m];
+      for (i1=0; i1<n; ++i1) {
+        X[iX++] += A[iA++]*b;
+      }
+    }
+  }
+  
+  for (i1=0; i1<n*k; i1++) {
+    X[i1] *= alpha;
+  }
+}
+
+
+/* matrix-transpose-matrix multiplication */
+
+void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
+{
+  mwIndex i1, i2, i3, iX, iA, i2_n;
+  double *x, sum0, sum1, sum2, sum3;
+
+  for (i2=0; i2<m; ++i2) {
+    for (i3=0; i3<k; ++i3) {
+      sum0 = sum1 = sum2 = sum3 = 0;
+      for (i1=0; i1+4<n; i1+=4) {
+        sum0 += A[i1+0+i2*n]*B[i1+0+i3*n];
+        sum1 += A[i1+1+i2*n]*B[i1+1+i3*n];
+        sum2 += A[i1+2+i2*n]*B[i1+2+i3*n];
+        sum3 += A[i1+3+i2*n]*B[i1+3+i3*n];
+      }
+      X[i2+i3*m] = (sum0+sum1) + (sum2+sum3);
+      while(i1<n) {
+        X[i2+i3*m] += A[i1+i2*n]*B[i1+i3*n];
+        i1++;
+      }
+    }
+  }
+  
+  for (i1=0; i1<m*k; i1++) {
+    X[i1] *= alpha;
+  }
+}
+
+
+/* tensor-matrix product */
+
+void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
+{
+  mwIndex i1, i2, i3, i4, i2_n, nml;
+  double b;
+  
+  nml = n*m*l;
+  for (i1=0; i1<nml; ++i1) {
+    X[i1] = 0;
+  }
+
+  for (i2=0; i2<m; ++i2) {
+    i2_n = i2*n;
+    for (i3=0; i3<k; ++i3) {
+      for (i4=0; i4<l; ++i4) {
+        b = B[i4+i3*l];
+        for (i1=0; i1<n; ++i1) {
+          X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
+        }
+      }
+    }
+  }
+  
+  for (i1=0; i1<nml; ++i1) {
+    X[i1] *= alpha;
+  }
+}
+
+
+/* tensor-matrix-transpose product */
+
+void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
+{
+  mwIndex i1, i2, i3, i4, i2_n, nml;
+  double b;
+  
+  nml = n*m*l;
+  for (i1=0; i1<nml; ++i1) {
+    X[i1] = 0;
+  }
+
+  for (i2=0; i2<m; ++i2) {
+    i2_n = i2*n;
+    for (i4=0; i4<l; ++i4) {
+      for (i3=0; i3<k; ++i3) {
+        b = B[i3+i4*k];
+        for (i1=0; i1<n; ++i1) {
+          X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
+        }
+      }
+    }
+  }
+  
+  for (i1=0; i1<nml; ++i1) {
+    X[i1] *= alpha;
+  }
+}
+
+
+/* dot product */
+
+double dotprod(double a[], double b[], mwSize n)
+{
+  double sum = 0;
+  mwIndex i;
+  for (i=0; i<n; ++i)
+    sum += a[i]*b[i];
+  return sum;
+}
+
+
+/* find maximum of vector */
+
+mwIndex maxpos(double c[], mwSize m)
+{
+  mwIndex maxid=0, k;
+  double val, maxval = *c;
+
+  for (k=1; k<m; ++k) {
+    val = c[k];
+    if (val > maxval) {
+      maxval = val;
+      maxid = k;
+    }
+  }
+  return maxid;
+}
+
+
+/* solve L*x = b */
+
+void backsubst_L(double L[], double b[], double x[], mwSize n, mwSize k)
+{
+  mwIndex i, j;
+  double rhs;
+
+  for (i=0; i<k; ++i) {
+    rhs = b[i];
+    for (j=0; j<i; ++j) {
+      rhs -= L[j*n+i]*x[j];
+    }
+    x[i] = rhs/L[i*n+i];
+  }
+}
+
+
+/* solve L'*x = b */
+
+void backsubst_Lt(double L[], double b[], double x[], mwSize n, mwSize k)
+{
+  mwIndex i, j;
+  double rhs;
+
+  for (i=k; i>=1; --i) {
+    rhs = b[i-1];
+    for (j=i; j<k; ++j) {
+      rhs -= L[(i-1)*n+j]*x[j];
+    }
+    x[i-1] = rhs/L[(i-1)*n+i-1];
+  }
+}
+
+
+/* solve U*x = b */
+
+void backsubst_U(double U[], double b[], double x[], mwSize n, mwSize k)
+{
+  mwIndex i, j;
+  double rhs;
+
+  for (i=k; i>=1; --i) {
+    rhs = b[i-1];
+    for (j=i; j<k; ++j) {
+      rhs -= U[j*n+i-1]*x[j];
+    }
+    x[i-1] = rhs/U[(i-1)*n+i-1];
+  }
+}
+
+
+/* solve U'*x = b */
+
+void backsubst_Ut(double U[], double b[], double x[], mwSize n, mwSize k)
+{
+  mwIndex i, j;
+  double rhs;
+
+  for (i=0; i<k; ++i) {
+    rhs = b[i];
+    for (j=0; j<i; ++j) {
+      rhs -= U[i*n+j]*x[j];
+    }
+    x[i] = rhs/U[i*n+i];
+  }
+}
+
+
+/* back substitution solver */
+
+void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
+{
+  if (tolower(ul) == 'u') {
+    backsubst_U(A, b, x, n, k);
+  }
+  else if (tolower(ul) == 'l') {
+    backsubst_L(A, b, x, n, k);
+  }
+  else {
+    mexErrMsgTxt("Invalid triangular matrix type: must be ''U'' or ''L''");
+  }
+}
+
+
+/* solve equation set using cholesky decomposition */
+
+void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
+{
+  double *tmp;
+
+  tmp = mxMalloc(k*sizeof(double));
+
+  if (tolower(ul) == 'l') {
+    backsubst_L(A, b, tmp, n, k);
+    backsubst_Lt(A, tmp, x, n, k);
+  }
+  else if (tolower(ul) == 'u') {
+    backsubst_Ut(A, b, tmp, n, k);
+    backsubst_U(A, tmp, x, n, k);
+  }
+  else {
+    mexErrMsgTxt("Invalid triangular matrix type: must be either ''U'' or ''L''");
+  }
+
+  mxFree(tmp);
+}
+
+
+/* perform a permutation assignment y := x(ind(1:k)) */
+
+void vec_assign(double y[], double x[], mwIndex ind[], mwSize k)
+{
+  mwIndex i;
+
+  for (i=0; i<k; ++i)
+    y[i] = x[ind[i]];
+}
+
+
+/* matrix transpose */
+
+void transpose(double X[], double Y[], mwSize n, mwSize m)
+{
+  mwIndex i, j, i_m, j_n;
+  
+  if (n<m) {
+    for (j=0; j<m; ++j) {
+      j_n = j*n;
+      for (i=0; i<n; ++i) {
+        Y[j+i*m] = X[i+j_n];
+      }
+    }
+  }
+  else {
+    for (i=0; i<n; ++i) {
+      i_m = i*m;
+      for (j=0; j<m; ++j) {
+        Y[j+i_m] = X[i+j*n];
+      }
+    }
+  }
+}
+
+
+/* print contents of matrix */
+
+void printmat(double A[], int n, int m, char* matname)
+{
+  int i, j;
+  mexPrintf("\n%s = \n\n", matname);
+
+  if (n*m==0) {
+    mexPrintf("   Empty matrix: %d-by-%d\n\n", n, m);
+    return;
+  }
+
+  for (i=0; i<n; ++i) {
+    for (j=0; j<m; ++j)
+      mexPrintf("   %lf", A[j*n+i]);
+    mexPrintf("\n");
+  }
+  mexPrintf("\n");
+}
+
+
+/* print contents of sparse matrix */
+
+void printspmat(mxArray *a, char* matname)
+{
+  mwIndex *aJc = mxGetJc(a);
+  mwIndex *aIr = mxGetIr(a);
+  double *aPr = mxGetPr(a);
+
+  int i;
+
+  mexPrintf("\n%s = \n\n", matname);
+
+  for (i=0; i<aJc[1]; ++i)
+    printf("   (%d,1) = %lf\n", aIr[i]+1,aPr[i]);
+
+  mexPrintf("\n");
+}
+
+
+
+/* matrix multiplication using Winograd's algorithm */
+
+/*
+void mat_mat2(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
+{
+  
+  mwIndex i1, i2, i3, iX, iA, i2_n;
+  double b, *AA, *BB;
+  
+  AA = mxCalloc(n,sizeof(double));
+  BB = mxCalloc(k,sizeof(double));
+  
+  for (i1=0; i1<n*k; i1++) {
+    X[i1] = 0;
+  }
+  
+  for (i1=0; i1<n; ++i1) {
+    for (i2=0; i2<m/2; ++i2) {
+      AA[i1] += A[i1+2*i2*n]*A[i1+(2*i2+1)*n];
+    }
+  }
+
+  for (i2=0; i2<k; ++i2) {
+    for (i1=0; i1<m/2; ++i1) {
+      BB[i2] += B[2*i1+i2*m]*B[2*i1+1+i2*m];
+    }
+  }
+
+  for (i2=0; i2<k; ++i2) {
+    for (i3=0; i3<m/2; ++i3) {
+      for (i1=0; i1<n; ++i1) {
+        X[i1+i2*n] += (A[i1+(2*i3)*n]+B[2*i3+1+i2*m])*(A[i1+(2*i3+1)*n]+B[2*i3+i2*m]);
+      }
+    }
+  }
+  
+  if (m%2) {
+    for (i2=0; i2<k; ++i2) {
+      for (i1=0; i1<n; ++i1) {
+        X[i1+i2*n] += A[i1+(m-1)*n]*B[m-1+i2*m];
+      }
+    }
+  }
+  
+  for (i2=0; i2<k; ++i2) {
+    for (i1=0; i1<n; ++i1) {
+      X[i1+i2*n] -= (AA[i1] + BB[i2]);
+      X[i1+i2*n] *= alpha;
+    }
+  }
+  
+  mxFree(AA);
+  mxFree(BB);
+}
+*/
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/myblas.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,511 @@
+/**************************************************************************
+ *
+ * File name: myblas.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Version: 1.1
+ * Last updated: 17.8.2009
+ *
+ * A collection of basic linear algebra functions, in the spirit of the
+ * BLAS/LAPACK libraries.
+ *
+ *************************************************************************/
+
+
+
+#ifndef __MY_BLAS_H__
+#define __MY_BLAS_H__
+
+
+#include "mex.h"
+#include <math.h>
+
+
+
+/**************************************************************************
+ * Squared value.
+ **************************************************************************/
+#define SQR(X) ((X)*(X))
+
+
+
+/**************************************************************************
+ * Matrix-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A*x
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   x - vector of length m
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Matrix-transpose-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A'*x
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   x - vector of length n
+ *   y - output vector of length m
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Sparse-matrix-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A*x
+ *
+ * where A is a sparse matrix.
+ *
+ * Parameters:
+ *   pr,ir,jc - sparse representation of the matrix A, of size n x m
+ *   x - vector of length m
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Sparse-matrix-transpose-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A'*x
+ *
+ * where A is a sparse matrix.
+ *
+ * Parameters:
+ *   pr,ir,jc - sparse representation of the matrix A, of size n x m
+ *   x - vector of length m
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Matrix-sparse-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A*x
+ *
+ * where A is a matrix and x is a sparse vector.
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   pr,ir,jc - sparse representation of the vector x, of length m
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Matrix-transpose-sparse-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A'*x
+ *
+ * where A is a matrix and x is a sparse vector.
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   pr,ir,jc - sparse representation of the vector x, of length n
+ *   y - output vector of length m
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Sparse-matrix-sparse-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A*x
+ *
+ * where A is a sparse matrix and x is a sparse vector.
+ *
+ * Parameters:
+ *   pr,ir,jc - sparse representation of the matrix A, of size n x m
+ *   prx,irx,jcx - sparse representation of the vector x (of length m)
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Sparse-matrix-transpose-sparse-vector multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*A'*x
+ *
+ * where A is a sparse matrix and x is a sparse vector.
+ *
+ * Importnant note: this function is provided for completeness, but is NOT efficient.
+ * If possible, convert x to non-sparse representation and use matT_vec_sp instead.
+ *
+ * Parameters:
+ *   pr,ir,jc - sparse representation of the matrix A, of size n x m
+ *   prx,irx,jcx - sparse representation of the vector x (of length n)
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n, m - dimensions of A
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Matrix-matrix multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   X := alpha*A*B
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   B - matrix of size m X k
+ *   X - output matrix of size n X k
+ *   alpha - real constant
+ *   n, m, k - dimensions of A, B
+ *
+ * Note: This function re-writes the contents of X.
+ *
+ **************************************************************************/
+void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k);
+
+
+
+/**************************************************************************
+ * Matrix-transpose-matrix multiplication. 
+ *
+ * Computes an operation of the form:
+ *
+ *   X := alpha*A*B
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   B - matrix of size m X k
+ *   X - output matrix of size n X k
+ *   alpha - real constant
+ *   n, m, k - dimensions of A, B
+ *
+ * Note: This function re-writes the contents of X.
+ *
+ **************************************************************************/
+void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k);
+
+
+
+/**************************************************************************
+ * Tensor-matrix multiplication. 
+ *
+ * This function accepts a 3-D tensor A of size n X m X k
+ * and a 2-D matrix B of size l X k.
+ * The function computes the 3-D tensor X of size n X m X l, where
+ *
+ *   X(i,j,:) = B*A(i,j,:)
+ *
+ * for all i,j.
+ *
+ * Parameters:
+ *   A - tensor of size n X m X k
+ *   B - matrix of size l X k
+ *   X - output tensor of size n X m X l
+ *   alpha - real constant
+ *   n, m, k, l - dimensions of A, B
+ *
+ * Note: This function re-writes the contents of X.
+ *
+ **************************************************************************/
+void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l);
+
+
+
+/**************************************************************************
+ * Tensor-matrix-transpose multiplication. 
+ *
+ * This function accepts a 3-D tensor A of size n X m X k
+ * and a 2-D matrix B of size k X l.
+ * The function computes the 3-D tensor X of size n X m X l, where
+ *
+ *   X(i,j,:) = B'*A(i,j,:)
+ *
+ * for all i,j.
+ *
+ * Parameters:
+ *   A - tensor of size n X m X k
+ *   B - matrix of size k X l
+ *   X - output tensor of size n X m X l
+ *   alpha - real constant
+ *   n, m, k, l - dimensions of A, B
+ *
+ * Note: This function re-writes the contents of X.
+ *
+ **************************************************************************/
+void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l);
+
+
+
+/**************************************************************************
+ * Vector-vector sum.
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha*x + y
+ *
+ * Parameters:
+ *   x - vector of length n
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n - length of x,y
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+void vec_sum(double alpha, double x[], double y[], mwSize n);
+
+/**************************************************************************
+ * Vector-vector scalar multiply.
+ *
+ * Computes an operation of the form:
+ *
+ *   y := alpha* x.*y
+ *
+ * Parameters:
+ *   x - vector of length n
+ *   y - output vector of length n
+ *   alpha - real constant
+ *   n - length of x,y
+ *
+ * Note: This function re-writes the contents of y.
+ *
+ **************************************************************************/
+
+
+void vec_smult(double alpha, double x[], double y[], mwSize n);
+
+
+/**************************************************************************
+ * Triangular back substitution.
+ *
+ * Solve the set of linear equations
+ *
+ *   T*x = b
+ *
+ * where T is lower or upper triangular.
+ *
+ * Parameters:
+ *   ul - 'U' for upper triangular, 'L' for lower triangular
+ *   A  - matrix of size n x m containing T
+ *   b  - vector of length k
+ *   x  - output vector of length k
+ *   n  - size of first dimension of A
+ *   k  - the size of the equation set, k<=n,m
+ *
+ * Note:
+ *   The matrix A can be of any size n X m, as long as n,m >= k. 
+ *   Only the lower/upper triangle of the submatrix A(1:k,1:k) defines the
+ *   matrix T (depending on the parameter ul).
+ *
+ **************************************************************************/
+void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k);
+
+
+
+/**************************************************************************
+ * Solve a set of equations using a Cholesky decomposition.
+ *
+ * Solve the set of linear equations
+ *
+ *   M*x = b
+ *
+ * where M is positive definite with a known Cholesky decomposition:
+ * either M=L*L' (L lower triangular) or M=U'*U (U upper triangular).
+ *
+ * Parameters:
+ *   ul - 'U' for upper triangular, 'L' for lower triangular decomposition
+ *   A  - matrix of size n x m with the Cholesky decomposition of M
+ *   b  - vector of length k
+ *   x  - output vector of length k
+ *   n  - size of first dimension of A
+ *   k  - the size of the equation set, k<=n,m
+ *
+ * Note:
+ *   The matrix A can be of any size n X m, as long as n,m >= k. 
+ *   Only the lower/upper triangle of the submatrix A(1:k,1:k) is used as
+ *   the Cholesky decomposition of M (depending on the parameter ul).
+ *
+ **************************************************************************/
+void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k);
+
+
+
+/**************************************************************************
+ * Maximum absolute value.
+ *
+ * Returns the index of the coefficient with maximal absolute value in a vector.
+ *
+ * Parameters:
+ *   x - vector of length n
+ *   n - length of x
+ *
+ **************************************************************************/
+mwIndex maxabs(double x[], mwSize n);
+
+
+
+/**************************************************************************
+ * Maximum vector element.
+ *
+ * Returns the index of the maximal coefficient in a vector.
+ *
+ * Parameters:
+ *   x - vector of length n
+ *   n - length of x
+ *
+ **************************************************************************/
+mwIndex maxpos(double x[], mwSize n);
+
+
+
+/**************************************************************************
+ * Vector-vector dot product.
+ *
+ * Computes an operation of the form:
+ *
+ *   c = a'*b
+ *
+ * Parameters:
+ *   a, b - vectors of length n
+ *   n - length of a,b
+ *
+ * Returns: The dot product c.
+ *
+ **************************************************************************/
+double dotprod(double a[], double b[], mwSize n);
+
+
+
+/**************************************************************************
+ * Indexed vector assignment.
+ *
+ * Perform a permutation assignment of the form
+ *
+ *   y = x(ind)
+ *
+ * where ind is an array of indices to x.
+ *
+ * Parameters:
+ *   y - output vector of length k
+ *   x - input vector of arbitrary length
+ *   ind - array of indices into x (indices begin at 0)
+ *   k - length of the array ind
+ *
+ **************************************************************************/
+void vec_assign(double y[], double x[], mwIndex ind[], mwSize k);
+
+
+
+/**************************************************************************
+ * Matrix transpose.
+ *
+ * Computes Y := X'
+ *
+ * Parameters:
+ *   X - input matrix of size n X m
+ *   Y - output matrix of size m X n
+ *   n, m - dimensions of X
+ *
+ **************************************************************************/
+void transpose(double X[], double Y[], mwSize n, mwSize m);
+
+
+
+/**************************************************************************
+ * Print a matrix.
+ *
+ * Parameters:
+ *   A - matrix of size n X m
+ *   n, m - dimensions of A
+ *   matname - name of matrix to display
+ *
+ **************************************************************************/
+void printmat(double A[], int n, int m, char* matname);
+
+
+
+/**************************************************************************
+ * Print a sparse matrix.
+ *
+ * Parameters:
+ *   A - sparse matrix of type double
+ *   matname - name of matrix to display
+ *
+ **************************************************************************/
+void printspmat(mxArray *A, char* matname);
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omp2Gabor.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,223 @@
+function gamma = omp2Gabor(varargin)
+%% omp2Gabor Error-constrained Orthogonal Matching Pursuit.
+%
+%  This file is part of SMALLbox [2] and it is adaptation of Ron
+%  Rubenstein omp solver [1] for Gabor dictionary as defined in 
+%  Audio Inpainting by Adler et al [3]. The dictionary is presented as
+%  DCT+DST and solver pics two atoms per iteration (given the frequency one
+%  from DCT and one from DST). For more information look in [3].
+%  
+%  GAMMA = OMP2(D,X,G,EPSILON) solves the optimization problem
+%
+%       min  |GAMMA|_0     s.t.  |X - D*GAMMA|_2 <= EPSILON
+%      gamma
+%
+%  for each of the signals in X, using Batch Orthogonal Matching Pursuit.
+%  Here, D is a dictionary with normalized columns, X is a matrix
+%  containing column signals, EPSILON is the error target for each signal,
+%  and G is the Gramm matrix D'*D. The output GAMMA is a matrix containing
+%  the sparse representations as its columns. 
+%
+%  GAMMA = OMP2(D,X,[],EPSILON) performs the same operation, but without
+%  the matrix G, using OMP-Cholesky. This call produces the same output as
+%  Batch-OMP, but is significantly slower. Using this syntax is only
+%  recommended when available memory is too small to store G.
+%
+%  GAMMA = OMP2(DtX,XtX,G,EPSILON) is the fastest implementation of OMP2,
+%  but also requires the most memory. Here, DtX stores the projections
+%  D'*X, and XtX is a row vector containing the squared norms of the
+%  signals, sum(X.*X). In this case Batch-OMP is used, but without having
+%  to compute D'*X and XtX in advance, which slightly improves runtime.
+%  Note that in general, the call
+%
+%    GAMMA = OMP2(D'*X, sum(X.*X), G, EPSILON);
+%
+%  will be faster than the call
+%
+%    GAMMA = OMP2(D,X,G,EPSILON);
+%
+%  due to optimized matrix multiplications in Matlab. However, when the
+%  entire matrix D'*X cannot be stored in memory, one of the other two
+%  versions can be used. Both compute D'*X for just one signal at a time,
+%  and thus require much less memory.
+%
+%  GAMMA = OMP2(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional
+%  parameters for OMP2. Available parameters are:
+%
+%    'gammamode' - Specifies the representation mode for GAMMA. Can be
+%                  either 'full' or 'sparse', corresponding to a full or
+%                  sparse matrix, respectively. By default, GAMMA is
+%                  returned as a sparse matrix.
+%    'maxatoms' -  Limits the number of atoms in the representation of each
+%                  signal. If specified, the number of atoms in each
+%                  representation does not exceed this number, even if the
+%                  error target is not met. Specifying maxatoms<0 implies
+%                  no limit (default).
+%    'messages'  - Specifies whether progress messages should be displayed.
+%                  When positive, this is the number of seconds between
+%                  status prints. When negative, indicates that no messages
+%                  should be displayed (this is the default).
+%    'checkdict' - Specifies whether dictionary normalization should be
+%                  verified. When set to 'on' (default) the dictionary
+%                  atoms are verified to be of unit L2-norm. Setting this
+%                  parameter to 'off' disables verification and accelerates
+%                  function performance. Note that an unnormalized
+%                  dictionary will produce invalid results.
+%    'profile'   - Can be either 'on' or 'off'. When 'on', profiling
+%                  information is displayed at the end of the funciton
+%                  execution.
+%
+%
+%  Summary of OMP2 versions:
+%
+%    version                 |   speed     |   memory
+%  -------------------------------------------------------------
+%   OMP2(DtX,XtX,G,EPSILON)  |  very fast  |  very large
+%   OMP2(D,X,G,EPSILON)      |  fast       |  moderate
+%   OMP2(D,X,[],EPSILON)     |  very slow  |  small
+%  -------------------------------------------------------------
+%
+%
+%  References:
+%  [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation
+%      of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit",
+%      Technical Report - CS, Technion, April 2008.
+%
+%  See also OMP.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
+
+%
+%   Centre for Digital Music, Queen Mary, University of London.
+%   This file copyright 2011 Ivan Damnjanovic.
+%
+%   This program is free software; you can redistribute it and/or
+%   modify it under the terms of the GNU General Public License as
+%   published by the Free Software Foundation; either version 2 of the
+%   License, or (at your option) any later version.  See the file
+%   COPYING included with this distribution for more information.
+%%
+
+% default options
+
+sparse_gamma = 1;
+msgdelta = -1;
+maxatoms = -1;
+checkdict = 1;
+profile = 0;
+
+
+% determine number of parameters
+
+paramnum = 1;
+while (paramnum<=nargin && ~ischar(varargin{paramnum}))
+  paramnum = paramnum+1;
+end
+paramnum = paramnum-1;
+
+
+% parse options
+
+for i = paramnum+1:2:length(varargin)
+  paramname = varargin{i};
+  paramval = varargin{i+1};
+
+  switch lower(paramname)
+
+    case 'gammamode'
+      if (strcmpi(paramval,'sparse'))
+        sparse_gamma = 1;
+      elseif (strcmpi(paramval,'full'))
+        sparse_gamma = 0;
+      else
+        error('Invalid GAMMA mode');
+      end
+      
+    case 'maxatoms'
+      maxatoms = paramval;
+      
+    case 'messages'
+      msgdelta = paramval;
+
+    case 'checkdict'
+      if (strcmpi(paramval,'on'))
+        checkdict = 1;
+      elseif (strcmpi(paramval,'off'))
+        checkdict = 0;
+      else
+        error('Invalid checkdict option');
+      end
+
+    case 'profile'
+      if (strcmpi(paramval,'on'))
+        profile = 1;
+      elseif (strcmpi(paramval,'off'))
+        profile = 0;
+      else
+        error('Invalid profile mode');
+      end
+
+    otherwise
+      error(['Unknown option: ' paramname]);
+  end
+  
+end
+
+
+% determine call type
+
+if (paramnum==4)
+  
+  n1 = size(varargin{1},1);
+  n2 = size(varargin{2},1);
+  n3 = size(varargin{3},1);
+  
+  if ( (n1>1 && n2==1) || (n1==1 && n2==1 && n3==1) )  %  DtX,XtX,G,EPSILON
+    
+    DtX = varargin{1};
+    XtX = varargin{2};
+    G = varargin{3};
+    epsilon = varargin{4};
+    D = [];
+    X = [];
+    
+  else  % D,X,G,EPSILON
+    
+    D = varargin{1};
+    X = varargin{2};
+    G = varargin{3};
+    epsilon = varargin{4};
+    DtX = [];
+    XtX = [];
+    
+  end
+  
+else
+  error('Invalid number of parameters');
+end
+
+G=[];
+
+% verify dictionary normalization
+
+if (checkdict)
+  if (isempty(G))
+    atomnorms = sum(D.*D);
+  else
+    atomnorms = diag(G);
+  end
+  if (any(abs(atomnorms-1) > 1e-2))
+    error('Dictionary columns must be normalized to unit length');
+  end
+end
+
+
+% omp
+
+gamma = omp2mexGabor(D,X,DtX,XtX,G,epsilon,sparse_gamma,msgdelta,maxatoms,profile);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omp2mex.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,156 @@
+/**************************************************************************
+ *
+ * File name: omp2mex.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ *************************************************************************/
+
+#include "ompcore.h"
+#include "omputils.h"
+#include "mexutils.h"
+
+
+/* Input Arguments */
+
+#define	IN_D	        prhs[0]
+#define IN_X          prhs[1]
+#define IN_DtX        prhs[2]
+#define IN_XtX        prhs[3]
+#define IN_G          prhs[4]
+#define IN_EPS        prhs[5]
+#define IN_SPARSE_G   prhs[6]
+#define IN_MSGDELTA   prhs[7]
+#define IN_MAXATOMS   prhs[8]
+#define IN_PROFILE    prhs[9]
+
+
+/* Output Arguments */
+
+#define	GAMMA_OUT     plhs[0]
+
+
+/***************************************************************************************/
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
+
+{
+  double *D, *x, *DtX, *XtX, *G, eps, msgdelta;
+  int gmode, maxatoms, profile;
+  mwSize m, n, L;    /* D is n x m , X is n x L, DtX is m x L */
+
+  
+  /* check parameters */
+  
+  checkmatrix(IN_D, "OMP2", "D");
+  checkmatrix(IN_X, "OMP2", "X");
+  checkmatrix(IN_DtX, "OMP2", "DtX");
+  checkmatrix(IN_XtX, "OMP2", "XtX");
+  checkmatrix(IN_G, "OMP2", "G");
+  
+  checkscalar(IN_EPS, "OMP2", "EPSILON");
+  checkscalar(IN_SPARSE_G, "OMP2", "sparse_g");
+  checkscalar(IN_MSGDELTA, "OMP2", "msgdelta");
+  checkscalar(IN_MAXATOMS, "OMP2", "maxatoms");
+  checkscalar(IN_PROFILE, "OMP2", "profile");
+  
+  
+  /* get parameters */
+  
+  x = D = DtX = XtX = G = 0;
+  
+  if (!mxIsEmpty(IN_D))
+    D = mxGetPr(IN_D);
+  
+  if (!mxIsEmpty(IN_X))
+    x = mxGetPr(IN_X);
+  
+  if (!mxIsEmpty(IN_DtX))
+    DtX = mxGetPr(IN_DtX);
+  
+  if (!mxIsEmpty(IN_XtX))
+    XtX = mxGetPr(IN_XtX);
+  
+  if (!mxIsEmpty(IN_G))
+    G = mxGetPr(IN_G);
+  
+  eps = mxGetScalar(IN_EPS);
+  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
+    gmode = SPARSE_GAMMA;
+  }
+  else {
+    gmode = FULL_GAMMA;
+  }
+  msgdelta = mxGetScalar(IN_MSGDELTA);
+  if (mxGetScalar(IN_MAXATOMS) < -1e-5) {
+    maxatoms = -1;
+  }
+  else {
+    maxatoms = (int)(mxGetScalar(IN_MAXATOMS)+1e-2);
+  }
+  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
+  
+  
+  /* check sizes */
+  
+  if (D && x) {
+    n = mxGetM(IN_D);
+    m = mxGetN(IN_D);
+    L = mxGetN(IN_X);
+    
+    if (mxGetM(IN_X) != n) {
+      mexErrMsgTxt("D and X have incompatible sizes.");
+    }
+    
+    if (G) {
+      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+        mexErrMsgTxt("G must be a square matrix.");
+      }
+      if (mxGetN(IN_G) != m) {
+        mexErrMsgTxt("D and G have incompatible sizes.");
+      }
+    }
+  }
+  
+  else if (DtX && XtX) {
+    m = mxGetM(IN_DtX);
+    L = mxGetN(IN_DtX);
+    
+    /* set n to an arbitrary value that is at least the max possible number of selected atoms */
+    
+    if (maxatoms>0) {
+      n = maxatoms;
+    }
+    else {
+      n = m;
+    }
+    
+    if ( !(mxGetM(IN_XtX)==L && mxGetN(IN_XtX)==1) && !(mxGetM(IN_XtX)==1 && mxGetN(IN_XtX)==L) ) {
+      mexErrMsgTxt("DtX and XtX have incompatible sizes.");
+    }
+    
+    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+      mexErrMsgTxt("G must be a square matrix.");
+    }
+    if (mxGetN(IN_G) != m) {
+      mexErrMsgTxt("DtX and G have incompatible sizes.");
+    }
+  }
+  
+  else {
+    mexErrMsgTxt("Either D and X, or DtX and XtX, must be specified.");
+  }
+  
+  
+  /* Do OMP! */
+  
+  GAMMA_OUT = ompcore(D, x, DtX, XtX, G, n, m, L, maxatoms, eps, gmode, profile, msgdelta, 1);
+  
+  return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omp2mex.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,23 @@
+%This is the Matlab interface to the OMP2 MEX implementation.
+%The function is not for independent use, only through omp2.m.
+
+
+%OMP2MEX Matlab interface to the OMP2 MEX implementation.
+%  GAMMA = OMP2MEX(D,X,DtX,XtX,G,EPSILON,SPARSE_G,MSGDELTA,MAXATOMS,PROFILE)
+%  invokes the OMP2 MEX function according to the specified parameters. Not
+%  all the parameters are required. Those among D, X, DtX, XtX and G which
+%  are not specified should be passed as [].
+%
+%  EPSILON - the target error.
+%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
+%  MSGDELTA - the delay in secs between messages. Zero means no messages.
+%  MAXATOMS - the max number of atoms per signal, negative for no max.
+%  PROFILE - nonzero means that profiling information should be printed.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omp2mexGabor.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,156 @@
+/**************************************************************************
+ *
+ * File name: omp2mex.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ *************************************************************************/
+
+#include "ompcoreGabor.h"
+#include "omputils.h"
+#include "mexutils.h"
+
+
+/* Input Arguments */
+
+#define	IN_D	        prhs[0]
+#define IN_X          prhs[1]
+#define IN_DtX        prhs[2]
+#define IN_XtX        prhs[3]
+#define IN_G          prhs[4]
+#define IN_EPS        prhs[5]
+#define IN_SPARSE_G   prhs[6]
+#define IN_MSGDELTA   prhs[7]
+#define IN_MAXATOMS   prhs[8]
+#define IN_PROFILE    prhs[9]
+
+
+/* Output Arguments */
+
+#define	GAMMA_OUT     plhs[0]
+
+
+/***************************************************************************************/
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
+
+{
+  double *D, *x, *DtX, *XtX, *G, eps, msgdelta;
+  int gmode, maxatoms, profile;
+  mwSize m, n, L;    /* D is n x m , X is n x L, DtX is m x L */
+
+  
+  /* check parameters */
+  
+  checkmatrix(IN_D, "OMP2", "D");
+  checkmatrix(IN_X, "OMP2", "X");
+  checkmatrix(IN_DtX, "OMP2", "DtX");
+  checkmatrix(IN_XtX, "OMP2", "XtX");
+  checkmatrix(IN_G, "OMP2", "G");
+  
+  checkscalar(IN_EPS, "OMP2", "EPSILON");
+  checkscalar(IN_SPARSE_G, "OMP2", "sparse_g");
+  checkscalar(IN_MSGDELTA, "OMP2", "msgdelta");
+  checkscalar(IN_MAXATOMS, "OMP2", "maxatoms");
+  checkscalar(IN_PROFILE, "OMP2", "profile");
+  
+  
+  /* get parameters */
+  
+  x = D = DtX = XtX = G = 0;
+  
+  if (!mxIsEmpty(IN_D))
+    D = mxGetPr(IN_D);
+  
+  if (!mxIsEmpty(IN_X))
+    x = mxGetPr(IN_X);
+  
+  if (!mxIsEmpty(IN_DtX))
+    DtX = mxGetPr(IN_DtX);
+  
+  if (!mxIsEmpty(IN_XtX))
+    XtX = mxGetPr(IN_XtX);
+  
+  if (!mxIsEmpty(IN_G))
+    G = mxGetPr(IN_G);
+  
+  eps = mxGetScalar(IN_EPS);
+  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
+    gmode = SPARSE_GAMMA;
+  }
+  else {
+    gmode = FULL_GAMMA;
+  }
+  msgdelta = mxGetScalar(IN_MSGDELTA);
+  if (mxGetScalar(IN_MAXATOMS) < -1e-5) {
+    maxatoms = -1;
+  }
+  else {
+    maxatoms = (int)(mxGetScalar(IN_MAXATOMS)+1e-2);
+  }
+  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
+  
+  
+  /* check sizes */
+  
+  if (D && x) {
+    n = mxGetM(IN_D);
+    m = mxGetN(IN_D);
+    L = mxGetN(IN_X);
+    
+    if (mxGetM(IN_X) != n) {
+      mexErrMsgTxt("D and X have incompatible sizes.");
+    }
+    
+    if (G) {
+      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+        mexErrMsgTxt("G must be a square matrix.");
+      }
+      if (mxGetN(IN_G) != m) {
+        mexErrMsgTxt("D and G have incompatible sizes.");
+      }
+    }
+  }
+  
+  else if (DtX && XtX) {
+    m = mxGetM(IN_DtX);
+    L = mxGetN(IN_DtX);
+    
+    /* set n to an arbitrary value that is at least the max possible number of selected atoms */
+    
+    if (maxatoms>0) {
+      n = maxatoms;
+    }
+    else {
+      n = m;
+    }
+    
+    if ( !(mxGetM(IN_XtX)==L && mxGetN(IN_XtX)==1) && !(mxGetM(IN_XtX)==1 && mxGetN(IN_XtX)==L) ) {
+      mexErrMsgTxt("DtX and XtX have incompatible sizes.");
+    }
+    
+    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+      mexErrMsgTxt("G must be a square matrix.");
+    }
+    if (mxGetN(IN_G) != m) {
+      mexErrMsgTxt("DtX and G have incompatible sizes.");
+    }
+  }
+  
+  else {
+    mexErrMsgTxt("Either D and X, or DtX and XtX, must be specified.");
+  }
+  
+  
+  /* Do OMP! */
+  
+  GAMMA_OUT = ompcoreGabor(D, x, DtX, XtX, G, n, m, L, maxatoms, eps, gmode, profile, msgdelta, 1);
+  
+  return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omp2mexGabor.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,23 @@
+%This is the Matlab interface to the OMP2 MEX implementation.
+%The function is not for independent use, only through omp2.m.
+
+
+%OMP2MEX Matlab interface to the OMP2 MEX implementation.
+%  GAMMA = OMP2MEXGABOR(D,X,DtX,XtX,G,EPSILON,SPARSE_G,MSGDELTA,MAXATOMS,PROFILE)
+%  invokes the OMP2 MEX function according to the specified parameters. Not
+%  all the parameters are required. Those among D, X, DtX, XtX and G which
+%  are not specified should be passed as [].
+%
+%  EPSILON - the target error.
+%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
+%  MSGDELTA - the delay in secs between messages. Zero means no messages.
+%  MAXATOMS - the max number of atoms per signal, negative for no max.
+%  PROFILE - nonzero means that profiling information should be printed.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompGabor.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,180 @@
+function gamma = omp(varargin)
+%OMP Sparsity-constrained Orthogonal Matching Pursuit.
+%  GAMMA = OMP(D,X,G,T) solves the optimization problem
+%
+%       min  |X - D*GAMMA|_2     s.t.  |GAMMA|_0 <= T
+%      gamma
+%
+%  for each of the signals in X, using Batch Orthogonal Matching Pursuit.
+%  Here, D is a dictionary with normalized columns, X is a matrix
+%  containing column signals, T is the # of non-zeros in each signal
+%  representation, and G is the Gramm matrix D'*D. The output GAMMA is a
+%  matrix containing the sparse representations as its columns. 
+%
+%  GAMMA = OMP(D,X,[],T) performs the same operation, but without the
+%  matrix G, using OMP-Cholesky. This call produces the same output as
+%  Batch-OMP, but is significantly slower. Using this syntax is only
+%  recommended when available memory is too small to store G.
+%
+%  GAMMA = OMP(DtX,G,T) is the fastest implementation of OMP, but also
+%  requires the most memory. Here, DtX stores the projections D'*X. In this
+%  case Batch-OMP is used, but without having to compute D'*X in advance,
+%  which slightly improves runtime. Note that in general, the call
+%
+%    GAMMA = OMP(D'*X,G,T);
+%
+%  will be faster than the call
+%
+%    GAMMA = OMP(D,X,G,T);
+%
+%  due to optimized matrix multiplications in Matlab. However, when the
+%  entire matrix D'*X cannot be stored in memory, one of the other two
+%  versions can be used. Both compute D'*X for just one signal at a time,
+%  and thus require much less memory.
+%
+%  GAMMA = OMP(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional
+%  parameters for OMP. Available parameters are:
+%
+%    'gammamode' - Specifies the representation mode for GAMMA. Can be
+%                  either 'full' or 'sparse', corresponding to a full or
+%                  sparse matrix, respectively. By default, GAMMA is
+%                  returned as a sparse matrix.
+%    'messages'  - Specifies whether progress messages should be displayed.
+%                  When positive, this is the number of seconds between
+%                  status prints. When negative, indicates that no messages
+%                  should be displayed (this is the default).
+%    'checkdict' - Specifies whether dictionary normalization should be
+%                  verified. When set to 'on' (default) the dictionary
+%                  atoms are verified to be of unit L2-norm. Setting this
+%                  parameter to 'off' disables verification and accelerates
+%                  function performance. Note that an unnormalized
+%                  dictionary will produce invalid results.
+%    'profile'   - Can be either 'on' or 'off'. When 'on', profiling
+%                  information is displayed at the end of the funciton
+%                  execution.
+%
+%
+%  Summary of OMP versions:
+%
+%    version      |   speed     |   memory
+%  --------------------------------------------------
+%   OMP(DtX,G,T)  |  very fast  |  very large
+%   OMP(D,X,G,T)  |  fast       |  moderate
+%   OMP(D,X,[],T) |  very slow  |  small
+%  --------------------------------------------------
+%
+%
+%  References:
+%  [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation
+%      of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit",
+%      Technical Report - CS, Technion, April 2008.
+%
+%  See also OMP2.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
+
+
+% default options
+
+sparse_gamma = 1;
+msgdelta = -1;
+checkdict = 1;
+profile = 0;
+
+
+% determine number of parameters
+
+paramnum = 1;
+while (paramnum<=nargin && ~ischar(varargin{paramnum}))
+  paramnum = paramnum+1;
+end
+paramnum = paramnum-1;
+
+
+% parse options
+
+for i = paramnum+1:2:length(varargin)
+  paramname = varargin{i};
+  paramval = varargin{i+1};
+
+  switch lower(paramname)
+
+    case 'gammamode'
+      if (strcmpi(paramval,'sparse'))
+        sparse_gamma = 1;
+      elseif (strcmpi(paramval,'full'))
+        sparse_gamma = 0;
+      else
+        error('Invalid GAMMA mode');
+      end
+      
+    case 'messages'
+      msgdelta = paramval;
+
+    case 'checkdict'
+      if (strcmpi(paramval,'on'))
+        checkdict = 1;
+      elseif (strcmpi(paramval,'off'))
+        checkdict = 0;
+      else
+        error('Invalid checkdict option');
+      end
+
+    case 'profile'
+      if (strcmpi(paramval,'on'))
+        profile = 1;
+      elseif (strcmpi(paramval,'off'))
+        profile = 0;
+      else
+        error('Invalid profile mode');
+      end
+
+    otherwise
+      error(['Unknown option: ' paramname]);
+  end
+  
+end
+
+
+% determine call type
+
+if (paramnum==3)
+  DtX = varargin{1};
+  G = varargin{2};
+  T = varargin{3};
+  D = [];
+  X = [];
+elseif (paramnum==4)
+  D = varargin{1};
+  X = varargin{2};
+  G = varargin{3};
+  T = varargin{4};
+  DtX = [];
+else
+  error('Invalid number of parameters');
+end
+
+
+% verify dictionary normalization
+
+if (checkdict)
+  if (isempty(G))
+    atomnorms = sum(D.*D);
+  else
+    atomnorms = diag(G);
+  end
+  if (any(abs(atomnorms-1) > 1e-2))
+    error('Dictionary columns must be normalized to unit length');
+  end
+end
+
+
+% omp
+
+gamma = ompmexGabor(D,X,DtX,G,T,sparse_gamma,msgdelta,profile);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompcore.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,409 @@
+/**************************************************************************
+ *
+ * File name: ompcore.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 25.8.2009
+ *
+ *************************************************************************/
+
+
+#include "ompcore.h"
+#include "omputils.h"
+#include "ompprof.h"
+#include "myblas.h"
+#include <math.h>
+#include <string.h>
+
+
+
+/******************************************************************************
+ *                                                                            *
+ *                           Batch-OMP Implementation                         *
+ *                                                                            *
+ ******************************************************************************/  
+
+mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
+                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp)
+{
+  
+  profdata pd;
+  mxArray *Gamma;
+  mwIndex i, j, signum, pos, *ind, *gammaIr, *gammaJc, gamma_count;
+  mwSize allocated_coefs, allocated_cols;
+  int DtX_specified, XtX_specified, batchomp, standardomp, *selected_atoms;
+  double *alpha, *r, *Lchol, *c, *Gsub, *Dsub, sum, *gammaPr, *tempvec1, *tempvec2; 
+  double eps2, resnorm, delta, deltaprev, secs_remain;
+  int mins_remain, hrs_remain;
+  clock_t lastprint_time, starttime;
+ 
+  
+  
+  /*** status flags ***/
+  
+  DtX_specified = (DtX!=0);   /* indicates whether D'*x was provided */
+  XtX_specified = (XtX!=0);   /* indicates whether sum(x.*x) was provided */
+  
+  standardomp = (G==0);       /* batch-omp or standard omp are selected depending on availability of G */
+  batchomp = !standardomp;
+  
+  
+  
+  /*** allocate output matrix ***/
+  
+  
+  if (gamma_mode == FULL_GAMMA) {
+    
+    /* allocate full matrix of size m X L */
+    
+    Gamma = mxCreateDoubleMatrix(m, L, mxREAL);
+    gammaPr = mxGetPr(Gamma);
+    gammaIr = 0;
+    gammaJc = 0;
+  }
+  else {
+    
+    /* allocate sparse matrix with room for allocated_coefs nonzeros */
+    
+    /* for error-omp, begin with L*sqrt(n)/2 allocated nonzeros, otherwise allocate L*T nonzeros */
+    allocated_coefs = erroromp ? (mwSize)(ceil(L*sqrt((double)n)/2.0) + 1.01) : L*T;
+    Gamma = mxCreateSparse(m, L, allocated_coefs, mxREAL);
+    gammaPr = mxGetPr(Gamma);
+    gammaIr = mxGetIr(Gamma);
+    gammaJc = mxGetJc(Gamma);
+    gamma_count = 0;
+    gammaJc[0] = 0;
+  }
+  
+  
+  /*** helper arrays ***/
+  
+  alpha = (double*)mxMalloc(m*sizeof(double));        /* contains D'*residual */
+  ind = (mwIndex*)mxMalloc(n*sizeof(mwIndex));        /* indices of selected atoms */
+  selected_atoms = (int*)mxMalloc(m*sizeof(int));     /* binary array with 1's for selected atoms */
+  c = (double*)mxMalloc(n*sizeof(double));            /* orthogonal projection result */
+  
+  /* current number of columns in Dsub / Gsub / Lchol */
+  allocated_cols = erroromp ? (mwSize)(ceil(sqrt((double)n)/2.0) + 1.01) : T;
+  
+  /* Cholesky decomposition of D_I'*D_I */
+  Lchol = (double*)mxMalloc(n*allocated_cols*sizeof(double));
+
+  /* temporary vectors for various computations */
+  tempvec1 = (double*)mxMalloc(m*sizeof(double));
+  tempvec2 = (double*)mxMalloc(m*sizeof(double));
+  
+  if (batchomp) {
+    /* matrix containing G(:,ind) - the columns of G corresponding to the selected atoms, in order of selection */
+    Gsub = (double*)mxMalloc(m*allocated_cols*sizeof(double));
+  }
+  else {
+    /* matrix containing D(:,ind) - the selected atoms from D, in order of selection */
+    Dsub = (double*)mxMalloc(n*allocated_cols*sizeof(double));
+    
+    /* stores the residual */
+    r = (double*)mxMalloc(n*sizeof(double));        
+  }
+  
+  if (!DtX_specified) {
+    /* contains D'*x for the current signal */
+    DtX = (double*)mxMalloc(m*sizeof(double));  
+  }
+  
+  
+  
+  /*** initializations for error omp ***/
+  
+  if (erroromp) {
+    eps2 = eps*eps;        /* compute eps^2 */
+    if (T<0 || T>n) {      /* unspecified max atom num - set max atoms to n */
+      T = n;
+    }
+  }
+  
+  
+  
+  /*** initialize timers ***/
+  
+  initprofdata(&pd);             /* initialize profiling counters */
+  starttime = clock();           /* record starting time for eta computations */
+  lastprint_time = starttime;    /* time of last status display */
+  
+  
+  
+  /**********************   perform omp for each signal   **********************/
+  
+  
+  
+  for (signum=0; signum<L; ++signum) {
+    
+    
+    /* initialize residual norm and deltaprev for error-omp */
+    
+    if (erroromp) {
+      if (XtX_specified) {
+        resnorm = XtX[signum];
+      }
+      else {
+        resnorm = dotprod(x+n*signum, x+n*signum, n);
+        addproftime(&pd, XtX_TIME);
+      }
+      deltaprev = 0;     /* delta tracks the value of gamma'*G*gamma */
+    }
+    else {
+      /* ignore residual norm stopping criterion */
+      eps2 = 0;
+      resnorm = 1;
+    }
+    
+    
+    if (resnorm>eps2 && T>0) {
+      
+      /* compute DtX */
+      
+      if (!DtX_specified) {
+        matT_vec(1, D, x+n*signum, DtX, n, m);
+        addproftime(&pd, DtX_TIME);
+      }
+      
+      
+      /* initialize alpha := DtX */
+      
+      memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double));
+      
+      
+      /* mark all atoms as unselected */
+      
+      for (i=0; i<m; ++i) {
+        selected_atoms[i] = 0;
+      }
+      
+    }
+    
+
+    /* main loop */
+    
+    i=0;
+    while (resnorm>eps2 && i<T) {
+
+      /* index of next atom */
+      
+      pos = maxabs(alpha, m);
+      addproftime(&pd, MAXABS_TIME);
+      
+      
+      /* stop criterion: selected same atom twice, or inner product too small */
+      
+      if (selected_atoms[pos] || alpha[pos]*alpha[pos]<1e-14) {
+        break;
+      }
+      
+      
+      /* mark selected atom */
+      
+      ind[i] = pos;
+      selected_atoms[pos] = 1;
+      
+      
+      /* matrix reallocation */
+      
+      if (erroromp && i>=allocated_cols) {
+        
+        allocated_cols = (mwSize)(ceil(allocated_cols*MAT_INC_FACTOR) + 1.01);
+        
+        Lchol = (double*)mxRealloc(Lchol,n*allocated_cols*sizeof(double));
+        
+        batchomp ? (Gsub = (double*)mxRealloc(Gsub,m*allocated_cols*sizeof(double))) :
+                   (Dsub = (double*)mxRealloc(Dsub,n*allocated_cols*sizeof(double))) ;
+      }
+      
+      
+      /* append column to Gsub or Dsub */
+      
+      if (batchomp) {
+        memcpy(Gsub+i*m, G+pos*m, m*sizeof(double));
+      }
+      else {
+        memcpy(Dsub+i*n, D+pos*n, n*sizeof(double));
+      }
+      
+      
+      /*** Cholesky update ***/
+      
+      if (i==0) {
+        *Lchol = 1;
+      }
+      else {
+        
+        /* incremental Cholesky decomposition: compute next row of Lchol */
+        
+        if (standardomp) {
+          matT_vec(1, Dsub, D+n*pos, tempvec1, n, i);      /* compute tempvec1 := Dsub'*d where d is new atom */
+          addproftime(&pd, DtD_TIME);
+        }
+        else {
+          vec_assign(tempvec1, Gsub+i*m, ind, i);          /* extract tempvec1 := Gsub(ind,i) */
+        }
+        backsubst('L', Lchol, tempvec1, tempvec2, n, i);   /* compute tempvec2 = Lchol \ tempvec1 */
+        for (j=0; j<i; ++j) {                              /* write tempvec2 to end of Lchol */
+          Lchol[j*n+i] = tempvec2[j];
+        }
+        
+        /* compute Lchol(i,i) */
+        sum = 0;
+        for (j=0; j<i; ++j) {         /* compute sum of squares of last row without Lchol(i,i) */
+          sum += SQR(Lchol[j*n+i]);
+        }
+        if ( (1-sum) <= 1e-14 ) {     /* Lchol(i,i) is zero => selected atoms are dependent */
+          break;
+        }
+        Lchol[i*n+i] = sqrt(1-sum);
+      }
+      
+      addproftime(&pd, LCHOL_TIME);
+
+      i++;
+      
+      
+      /* perform orthogonal projection and compute sparse coefficients */
+      
+      vec_assign(tempvec1, DtX + m*signum*DtX_specified, ind, i);   /* extract tempvec1 = DtX(ind) */
+      cholsolve('L', Lchol, tempvec1, c, n, i);                     /* solve LL'c = tempvec1 for c */
+      addproftime(&pd, COMPCOEF_TIME);
+      
+
+      /* update alpha = D'*residual */
+      
+      if (standardomp) {
+        mat_vec(-1, Dsub, c, r, n, i);             /* compute r := -Dsub*c */
+        vec_sum(1, x+n*signum, r, n);              /* compute r := x+r */
+        
+        
+        /*memcpy(r, x+n*signum, n*sizeof(double));   /* assign r := x */
+        /*mat_vec1(-1, Dsub, c, 1, r, n, i);         /* compute r := r-Dsub*c */
+        
+        addproftime(&pd, COMPRES_TIME);
+        matT_vec(1, D, r, alpha, n, m);            /* compute alpha := D'*r */
+        addproftime(&pd, DtR_TIME);
+        
+        /* update residual norm */
+        if (erroromp) {
+          resnorm = dotprod(r, r, n);
+          addproftime(&pd, UPDATE_RESNORM_TIME);
+        }
+      }
+      else {
+        mat_vec(1, Gsub, c, tempvec1, m, i);                              /* compute tempvec1 := Gsub*c */
+        memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double));    /* set alpha = D'*x */
+        vec_sum(-1, tempvec1, alpha, m);                                  /* compute alpha := alpha - tempvec1 */
+        addproftime(&pd, UPDATE_DtR_TIME);
+        
+        /* update residual norm */
+        if (erroromp) {
+          vec_assign(tempvec2, tempvec1, ind, i);      /* assign tempvec2 := tempvec1(ind) */
+          delta = dotprod(c,tempvec2,i);               /* compute c'*tempvec2 */
+          resnorm = resnorm - delta + deltaprev;       /* residual norm update */
+          deltaprev = delta;
+          addproftime(&pd, UPDATE_RESNORM_TIME);
+        }
+      }
+    }
+    
+    
+    /*** generate output vector gamma ***/
+
+    if (gamma_mode == FULL_GAMMA) {    /* write the coefs in c to their correct positions in gamma */
+      for (j=0; j<i; ++j) {
+        gammaPr[m*signum + ind[j]] = c[j];
+      }
+    }
+    else {
+      /* sort the coefs by index before writing them to gamma */
+      quicksort(ind,c,i);
+      addproftime(&pd, INDEXSORT_TIME);
+      
+      /* gamma is full - reallocate */
+      if (gamma_count+i >= allocated_coefs) {
+        
+        while(gamma_count+i >= allocated_coefs) {
+          allocated_coefs = (mwSize)(ceil(GAMMA_INC_FACTOR*allocated_coefs) + 1.01);
+        }
+        
+        mxSetNzmax(Gamma, allocated_coefs);
+        mxSetPr(Gamma, mxRealloc(gammaPr, allocated_coefs*sizeof(double)));
+        mxSetIr(Gamma, mxRealloc(gammaIr, allocated_coefs*sizeof(mwIndex)));
+        
+        gammaPr = mxGetPr(Gamma);
+        gammaIr = mxGetIr(Gamma);
+      }
+      
+      /* append coefs to gamma and update the indices */
+      for (j=0; j<i; ++j) {
+        gammaPr[gamma_count] = c[j];
+        gammaIr[gamma_count] = ind[j];
+        gamma_count++;
+      }
+      gammaJc[signum+1] = gammaJc[signum] + i;
+    }
+    
+    
+    
+    /*** display status messages ***/
+    
+    if (msg_delta>0 && (clock()-lastprint_time)/(double)CLOCKS_PER_SEC >= msg_delta)
+    {
+      lastprint_time = clock();
+      
+      /* estimated remainig time */
+      secs2hms( ((L-signum-1)/(double)(signum+1)) * ((lastprint_time-starttime)/(double)CLOCKS_PER_SEC) ,
+        &hrs_remain, &mins_remain, &secs_remain);
+      
+      mexPrintf("omp: signal %d / %d, estimated remaining time: %02d:%02d:%05.2f\n",        
+        signum+1, L, hrs_remain, mins_remain, secs_remain);
+      mexEvalString("drawnow;");
+    }
+    
+  }
+  
+  /* end omp */
+  
+  
+  
+  /*** print final messages ***/
+  
+  if (msg_delta>0) {
+    mexPrintf("omp: signal %d / %d\n", signum, L);
+  }
+  
+  if (profile) {
+    printprofinfo(&pd, erroromp, batchomp, L);
+  }
+  
+  
+  
+  /* free memory */
+  
+  if (!DtX_specified) {
+    mxFree(DtX);
+  }
+  if (standardomp) {
+    mxFree(r);
+    mxFree(Dsub);
+  }
+  else {
+    mxFree(Gsub);
+  }  
+  mxFree(tempvec2);
+  mxFree(tempvec1);
+  mxFree(Lchol);
+  mxFree(c);
+  mxFree(selected_atoms);
+  mxFree(ind);
+  mxFree(alpha);
+  
+  return Gamma;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompcore.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,80 @@
+/**************************************************************************
+ *
+ * File name: ompcore.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ * Contains the core implementation of Batch-OMP / OMP-Cholesky.
+ *
+ *************************************************************************/
+
+
+#ifndef __OMP_CORE_H__
+#define __OMP_CORE_H__
+
+
+#include "mex.h"
+
+
+
+/**************************************************************************
+ * Perform Batch-OMP or OMP-Cholesky on a specified set of signals, using
+ * either a fixed number of atoms or an error bound.
+ *
+ * Parameters (not all required):
+ *
+ *   D - the dictionary, of size n X m
+ *   x - the signals, of size n X L
+ *   DtX - D'*x, of size m X L
+ *   XtX - squared norms of the signals in x, sum(x.*x), of length L
+ *   G - D'*D, of size m X m
+ *   T - target sparsity, or maximal number of atoms for error-based OMP
+ *   eps - target residual norm for error-based OMP
+ *   gamma_mode - one of the constants FULL_GAMMA or SPARSE_GAMMA
+ *   profile - if non-zero, profiling info is printed
+ *   msg_delta - positive: the # of seconds between status prints, otherwise: nothing is printed
+ *   erroromp - if nonzero indicates error-based OMP, otherwise fixed sparsity OMP
+ *
+ * Usage:
+ *
+ *   The function can be called using different parameters, and will have
+ *   different complexity depending on the parameters specified. Arrays which
+ *   are not specified should be passed as null (0). When G is specified, 
+ *   Batch-OMP is performed. Otherwise, OMP-Cholesky is performed.
+ *
+ *   Fixed-sparsity usage:
+ *   ---------------------
+ *   Either DtX, or D and x, must be specified. Specifying DtX is more efficient.
+ *   XtX does not need to be specified.
+ *   When D and x are specified, G is not required. However, not providing G
+ *   will significantly degrade efficiency.
+ *   The number of atoms must be specified in T. The value of eps is ignored.
+ *   Finally, set erroromp to 0.
+ *
+ *   Error-OMP usage:
+ *   ----------------
+ *   Either DtX and Xtx, or D and x, must be specified. Specifying DtX and XtX
+ *   is more efficient.
+ *   When D and x are specified, G is not required. However, not providing G
+ *   will significantly degrade efficiency.
+ *   The target error must be specified in eps. A hard limit on the number
+ *   of atoms can also be specified via the parameter T. Otherwise, T should 
+ *   be negative. Finally, set erroromp to nonzero.
+ *
+ *
+ * Returns: 
+ *   An mxArray containing the sparse representations of the signals in x
+ *   (allocated using the appropriate mxCreateXXX() function).
+ *   The array is either full or sparse, depending on gamma_mode.
+ *
+ **************************************************************************/
+mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
+                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompcoreGabor.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,465 @@
+/**************************************************************************
+ * 
+ * File name: ompcoreGabor.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 25.8.2009
+ *
+ * Modified by Ivan damnjanovic July 2011
+ * Takes to atoms per iteration. It should be used for Gabor dictionaries
+ * as specified in 
+ * "Audio Inpainting" Amir Adler, Valentin Emiya, Maria G. Jafari, 
+ * Michael Elad, Remi Gribonval and Mark D. Plumbley
+ * Draft version: March 6, 2011
+ *
+ *************************************************************************/
+
+
+#include "ompcoreGabor.h"
+#include "omputils.h"
+#include "ompprof.h"
+#include "myblas.h"
+#include <math.h>
+#include <string.h>
+
+
+
+/******************************************************************************
+ *                                                                            *
+ *                           Batch-OMP Implementation                         *
+ *                                                                            *
+ ******************************************************************************/  
+
+mxArray* ompcoreGabor(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
+                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp)
+{
+  
+  profdata pd;
+  mxArray *Gamma;
+  mwIndex i, j, k, signum, pos, *ind, *gammaIr, *gammaJc, gamma_count;
+  mwSize allocated_coefs, allocated_cols;
+  int DtX_specified, XtX_specified, batchomp, standardomp, *selected_atoms;
+  double *proj, *proj1, *proj2, *D1, *D2, *D1D2, *n12, *alpha, *beta, *error;
+  double *r, *Lchol, *c, *Gsub, *Dsub, sum, *gammaPr, *tempvec1, *tempvec2; 
+  double eps2, resnorm, delta, deltaprev, secs_remain;
+  int mins_remain, hrs_remain;
+  clock_t lastprint_time, starttime;
+ 
+  
+  
+  /*** status flags ***/
+  
+  DtX_specified = (DtX!=0);   /* indicates whether D'*x was provided */
+  XtX_specified = (XtX!=0);   /* indicates whether sum(x.*x) was provided */
+  
+  standardomp = (G==0);       /* batch-omp or standard omp are selected depending on availability of G */
+  batchomp = !standardomp;
+  
+  
+  
+  /*** allocate output matrix ***/
+  
+  
+  if (gamma_mode == FULL_GAMMA) {
+    
+    /* allocate full matrix of size m X L */
+    
+    Gamma = mxCreateDoubleMatrix(m, L, mxREAL);
+    gammaPr = mxGetPr(Gamma);
+    gammaIr = 0;
+    gammaJc = 0;
+  }
+  else {
+    
+    /* allocate sparse matrix with room for allocated_coefs nonzeros */
+    
+    /* for error-omp, begin with L*sqrt(n)/2 allocated nonzeros, otherwise allocate L*T nonzeros */
+    allocated_coefs = erroromp ? (mwSize)(ceil(L*sqrt((double)n)/2.0) + 1.01) : L*T;
+    Gamma = mxCreateSparse(m, L, allocated_coefs, mxREAL);
+    gammaPr = mxGetPr(Gamma);
+    gammaIr = mxGetIr(Gamma);
+    gammaJc = mxGetJc(Gamma);
+    gamma_count = 0;
+    gammaJc[0] = 0;
+  }
+  
+  
+  /*** helper arrays ***/
+ /* Ivan Damnjanovic July 2011*/ 
+  proj = (double*)mxMalloc(m*sizeof(double));
+  proj1 = (double*)mxMalloc(m/2*sizeof(double));
+  proj2 = (double*)mxMalloc(m/2*sizeof(double)); 
+  D1 = (double*)mxMalloc(n*m/2*sizeof(double));
+  D2 = (double*)mxMalloc(n*m/2*sizeof(double));
+  memcpy(D1, D      , n*m/2*sizeof(double));
+  memcpy(D2, D+n*m/2, n*m/2*sizeof(double)); 
+  
+  D1D2 = (double*)mxMalloc(m/2*sizeof(double));
+  n12  = (double*)mxMalloc(m/2*sizeof(double));
+  
+  vec_smult(1,D2, D1, n*m/2);
+       
+  for (i=0; i<m/2; i++) {
+	D1D2[i]=0;
+	n12[i]=0;
+    for (j=0; j<n; j++) {
+          D1D2[i] += D1[i*n+j];
+    }
+    n12[i]=1/(1-D1D2[i]*D1D2[i]);
+  }
+  
+  memcpy(D1, D      , n*m/2*sizeof(double));
+  
+  alpha = (double*)mxMalloc(m/2*sizeof(double));  /* contains D'*residual */
+  beta  = (double*)mxMalloc(m/2*sizeof(double));  
+  error = (double*)mxMalloc(m/2*sizeof(double));
+  
+  ind = (mwIndex*)mxMalloc(m*sizeof(mwIndex));        /* indices of selected atoms */
+  selected_atoms = (int*)mxMalloc(m*sizeof(int));     /* binary array with 1's for selected atoms */
+  c = (double*)mxMalloc(n*sizeof(double));            /* orthogonal projection result */
+  
+  /* current number of columns in Dsub / Gsub / Lchol */
+  allocated_cols = erroromp ? (mwSize)(ceil(sqrt((double)n)/2.0) + 1.01) : T;
+  
+  /* Cholesky decomposition of D_I'*D_I */
+  Lchol = (double*)mxMalloc(n*allocated_cols*sizeof(double));
+
+  /* temporary vectors for various computations */
+  tempvec1 = (double*)mxMalloc(m*sizeof(double));
+  tempvec2 = (double*)mxMalloc(m*sizeof(double));
+  
+  if (batchomp) {
+    /* matrix containing G(:,ind) - the columns of G corresponding to the selected atoms, in order of selection */
+    Gsub = (double*)mxMalloc(m*allocated_cols*sizeof(double));
+  }
+  else {
+    /* matrix containing D(:,ind) - the selected atoms from D, in order of selection */
+    Dsub = (double*)mxMalloc(n*allocated_cols*sizeof(double));
+    
+    /* stores the residual */
+    r = (double*)mxMalloc(n*sizeof(double));        
+  }
+  
+  if (!DtX_specified) {
+    /* contains D'*x for the current signal */
+    DtX = (double*)mxMalloc(m*sizeof(double));  
+  }
+  
+  
+  
+  /*** initializations for error omp ***/
+  
+  if (erroromp) {
+    eps2 = eps*eps;        /* compute eps^2 */
+    if (T<0 || T>n) {      /* unspecified max atom num - set max atoms to n */
+      T = n;
+    }
+  }
+  
+  
+  
+  /*** initialize timers ***/
+  
+  initprofdata(&pd);             /* initialize profiling counters */
+  starttime = clock();           /* record starting time for eta computations */
+  lastprint_time = starttime;    /* time of last status display */
+  
+  
+  
+  /**********************   perform omp for each signal   **********************/
+  
+  
+  
+  for (signum=0; signum<L; ++signum) {
+    
+    
+    /* initialize residual norm and deltaprev for error-omp */
+    
+    if (erroromp) {
+      if (XtX_specified) {
+        resnorm = XtX[signum];
+      }
+      else {
+        resnorm = dotprod(x+n*signum, x+n*signum, n);
+        addproftime(&pd, XtX_TIME);
+      }
+      deltaprev = 0;     /* delta tracks the value of gamma'*G*gamma */
+    }
+    else {
+      /* ignore residual norm stopping criterion */
+      eps2 = 0;
+      resnorm = 1;
+    }
+    
+    
+    if (resnorm>eps2 && T>0) {
+      
+      /* compute DtX */
+      
+      if (!DtX_specified) {
+        matT_vec(1, D, x+n*signum, DtX, n, m);
+        addproftime(&pd, DtX_TIME);
+        memcpy(r , x+n*signum, n*sizeof(double));
+      }
+      
+      
+      /* initialize projections to D1 and D2 := DtX */
+      
+      memcpy(proj, DtX + m*signum*DtX_specified, m*sizeof(double));
+      
+      
+      /* mark all atoms as unselected */
+      
+      for (i=0; i<m; ++i) {
+        selected_atoms[i] = 0;
+      }
+      
+    }
+    
+
+    /* main loop */
+    
+    i=0;
+    while (resnorm>eps2 && i<T) {
+
+      /* index of next atom */
+      memcpy(proj1, proj, m/2*sizeof(double));
+      memcpy(proj2, proj + m/2, m/2*sizeof(double));
+      for (k=0; k<m/2; k++){
+        alpha[k] = (proj1[k] - D1D2[k]*proj2[k])*n12[k];
+        beta[k]  = (proj2[k] - D1D2[k]*proj1[k])*n12[k];
+      }
+      for (k=0; k<m/2; k++){
+		  error[k]=0;
+          for (j=0; j<n; j++){
+                  error[k]+= (abs(r[j])-D1[k*n+j]*alpha[k]-D2[k*n+j]*beta[k])*(abs(r[j])-D1[k*n+j]*alpha[k]-D2[k*n+j]*beta[k]);
+          }
+      }
+      pos = maxabs(error, m/2);
+      addproftime(&pd, MAXABS_TIME);
+      
+      
+      /* stop criterion: selected same atom twice, or inner product too small */
+      
+      if (selected_atoms[pos] || alpha[pos]*alpha[pos]<1e-14) {
+        break;
+      }
+      
+      for (k=0;k<2;k++){
+      /* mark selected atom */
+      
+      ind[i] = pos+k*m/2;
+      selected_atoms[pos+k*m/2] = 1;
+      
+      
+      /* matrix reallocation */
+      
+      if (erroromp && i>=allocated_cols) {
+        
+        allocated_cols = (mwSize)(ceil(allocated_cols*MAT_INC_FACTOR) + 1.01);
+        
+        Lchol = (double*)mxRealloc(Lchol,n*allocated_cols*sizeof(double));
+        
+        batchomp ? (Gsub = (double*)mxRealloc(Gsub,m*allocated_cols*sizeof(double))) :
+                   (Dsub = (double*)mxRealloc(Dsub,n*allocated_cols*sizeof(double))) ;
+      }
+      
+      
+      /* append column to Gsub or Dsub */
+      
+      if (batchomp) {
+        memcpy(Gsub+i*m, G+(pos+k*m/2)*m, m*sizeof(double));
+      }
+      else {
+        memcpy(Dsub+(i)*n, D+(pos+k*m/2)*n, n*sizeof(double));
+      }
+      
+      
+      /*** Cholesky update ***/
+      
+      if (i==0) {
+        *Lchol = 1;
+      }
+      else {
+        
+        /* incremental Cholesky decomposition: compute next row of Lchol */
+        
+        if (standardomp) {
+          matT_vec(1, Dsub, D+n*(pos+k*m/2), tempvec1, n, i);      /* compute tempvec1 := Dsub'*d where d is new atom */
+          addproftime(&pd, DtD_TIME);
+        }
+        else {
+          vec_assign(tempvec1, Gsub+i*m, ind, i);          /* extract tempvec1 := Gsub(ind,i) */
+        }
+        backsubst('L', Lchol, tempvec1, tempvec2, n, i);   /* compute tempvec2 = Lchol \ tempvec1 */
+        for (j=0; j<i; ++j) {                              /* write tempvec2 to end of Lchol */
+          Lchol[j*n+i] = tempvec2[j];
+        }
+        
+        /* compute Lchol(i,i) */
+        sum = 0;
+        for (j=0; j<i; ++j) {         /* compute sum of squares of last row without Lchol(i,i) */
+          sum += SQR(Lchol[j*n+i]);
+        }
+        if ( (1-sum) <= 1e-14 ) {     /* Lchol(i,i) is zero => selected atoms are dependent */
+          break;
+        }
+        Lchol[i*n+i] = sqrt(1-sum);
+      }
+      
+      addproftime(&pd, LCHOL_TIME);
+
+      i++;
+      
+      }
+      /* perform orthogonal projection and compute sparse coefficients */
+      
+      vec_assign(tempvec1, DtX + m*signum*DtX_specified, ind, i);   /* extract tempvec1 = DtX(ind) */
+      cholsolve('L', Lchol, tempvec1, c, n, i);                     /* solve LL'c = tempvec1 for c */
+      addproftime(&pd, COMPCOEF_TIME);
+      
+
+      /* update alpha = D'*residual */
+      
+      if (standardomp) {
+        mat_vec(-1, Dsub, c, r, n, i);             /* compute r := -Dsub*c */
+        vec_sum(1, x+n*signum, r, n);              /* compute r := x+r */
+        
+        
+        /*memcpy(r, x+n*signum, n*sizeof(double));   /* assign r := x */
+        /*mat_vec1(-1, Dsub, c, 1, r, n, i);         /* compute r := r-Dsub*c */
+        
+        addproftime(&pd, COMPRES_TIME);
+        matT_vec(1, D, r, proj, n, m);            /* compute proj := D'*r */
+        addproftime(&pd, DtR_TIME);
+        
+        /* update residual norm */
+        if (erroromp) {
+          resnorm = dotprod(r, r, n);
+          addproftime(&pd, UPDATE_RESNORM_TIME);
+        }
+      }
+      else {
+        mat_vec(1, Gsub, c, tempvec1, m, i);                              /* compute tempvec1 := Gsub*c */
+        memcpy(proj, DtX + m*signum*DtX_specified, m*sizeof(double));    /* set proj = D'*x */
+        vec_sum(-1, tempvec1, proj, m);                                  /* compute proj := proj - tempvec1 */
+        addproftime(&pd, UPDATE_DtR_TIME);
+        
+        /* update residual norm */
+        if (erroromp) {
+          vec_assign(tempvec2, tempvec1, ind, i);      /* assign tempvec2 := tempvec1(ind) */
+          delta = dotprod(c,tempvec2,i);               /* compute c'*tempvec2 */
+          resnorm = resnorm - delta + deltaprev;       /* residual norm update */
+          deltaprev = delta;
+          addproftime(&pd, UPDATE_RESNORM_TIME);
+        }
+      }
+    }
+    
+    
+    /*** generate output vector gamma ***/
+
+    if (gamma_mode == FULL_GAMMA) {    /* write the coefs in c to their correct positions in gamma */
+      for (j=0; j<i; ++j) {
+        gammaPr[m*signum + ind[j]] = c[j];
+      }
+    }
+    else {
+      /* sort the coefs by index before writing them to gamma */
+      quicksort(ind,c,i);
+      addproftime(&pd, INDEXSORT_TIME);
+      
+      /* gamma is full - reallocate */
+      if (gamma_count+i >= allocated_coefs) {
+        
+        while(gamma_count+i >= allocated_coefs) {
+          allocated_coefs = (mwSize)(ceil(GAMMA_INC_FACTOR*allocated_coefs) + 1.01);
+        }
+        
+        mxSetNzmax(Gamma, allocated_coefs);
+        mxSetPr(Gamma, mxRealloc(gammaPr, allocated_coefs*sizeof(double)));
+        mxSetIr(Gamma, mxRealloc(gammaIr, allocated_coefs*sizeof(mwIndex)));
+        
+        gammaPr = mxGetPr(Gamma);
+        gammaIr = mxGetIr(Gamma);
+      }
+      
+      /* append coefs to gamma and update the indices */
+      for (j=0; j<i; ++j) {
+        gammaPr[gamma_count] = c[j];
+        gammaIr[gamma_count] = ind[j];
+        gamma_count++;
+      }
+      gammaJc[signum+1] = gammaJc[signum] + i;
+    }
+    
+    
+    
+    /*** display status messages ***/
+    
+    if (msg_delta>0 && (clock()-lastprint_time)/(double)CLOCKS_PER_SEC >= msg_delta)
+    {
+      lastprint_time = clock();
+      
+      /* estimated remainig time */
+      secs2hms( ((L-signum-1)/(double)(signum+1)) * ((lastprint_time-starttime)/(double)CLOCKS_PER_SEC) ,
+        &hrs_remain, &mins_remain, &secs_remain);
+      
+      mexPrintf("omp: signal %d / %d, estimated remaining time: %02d:%02d:%05.2f\n",        
+        signum+1, L, hrs_remain, mins_remain, secs_remain);
+      mexEvalString("drawnow;");
+    }
+    
+  }
+  
+  /* end omp */
+  
+  
+  
+  /*** print final messages ***/
+  
+  if (msg_delta>0) {
+    mexPrintf("omp: signal %d / %d\n", signum, L);
+  }
+  
+  if (profile) {
+    printprofinfo(&pd, erroromp, batchomp, L);
+  }
+  
+  
+  
+  /* free memory */
+  
+  if (!DtX_specified) {
+    mxFree(DtX);
+  }
+  if (standardomp) {
+    mxFree(r);
+    mxFree(Dsub);
+  }
+  else {
+    mxFree(Gsub);
+  }  
+  mxFree(tempvec2);
+  mxFree(tempvec1);
+  mxFree(Lchol);
+  mxFree(c);
+  mxFree(selected_atoms);
+  mxFree(ind);
+  mxFree(proj);
+  mxFree(proj1);
+  mxFree(proj2);
+  mxFree(D1);
+  mxFree(D2);
+  mxFree(D1D2);
+  mxFree(n12);
+  mxFree(alpha);
+  mxFree(beta);
+  mxFree(error);
+  
+  return Gamma;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompcoreGabor.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,80 @@
+/**************************************************************************
+ *
+ * File name: ompcore.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ * Contains the core implementation of Batch-OMP / OMP-Cholesky.
+ *
+ *************************************************************************/
+
+
+#ifndef __OMP_CORE_H__
+#define __OMP_CORE_H__
+
+
+#include "mex.h"
+
+
+
+/**************************************************************************
+ * Perform Batch-OMP or OMP-Cholesky on a specified set of signals, using
+ * either a fixed number of atoms or an error bound.
+ *
+ * Parameters (not all required):
+ *
+ *   D - the dictionary, of size n X m
+ *   x - the signals, of size n X L
+ *   DtX - D'*x, of size m X L
+ *   XtX - squared norms of the signals in x, sum(x.*x), of length L
+ *   G - D'*D, of size m X m
+ *   T - target sparsity, or maximal number of atoms for error-based OMP
+ *   eps - target residual norm for error-based OMP
+ *   gamma_mode - one of the constants FULL_GAMMA or SPARSE_GAMMA
+ *   profile - if non-zero, profiling info is printed
+ *   msg_delta - positive: the # of seconds between status prints, otherwise: nothing is printed
+ *   erroromp - if nonzero indicates error-based OMP, otherwise fixed sparsity OMP
+ *
+ * Usage:
+ *
+ *   The function can be called using different parameters, and will have
+ *   different complexity depending on the parameters specified. Arrays which
+ *   are not specified should be passed as null (0). When G is specified, 
+ *   Batch-OMP is performed. Otherwise, OMP-Cholesky is performed.
+ *
+ *   Fixed-sparsity usage:
+ *   ---------------------
+ *   Either DtX, or D and x, must be specified. Specifying DtX is more efficient.
+ *   XtX does not need to be specified.
+ *   When D and x are specified, G is not required. However, not providing G
+ *   will significantly degrade efficiency.
+ *   The number of atoms must be specified in T. The value of eps is ignored.
+ *   Finally, set erroromp to 0.
+ *
+ *   Error-OMP usage:
+ *   ----------------
+ *   Either DtX and Xtx, or D and x, must be specified. Specifying DtX and XtX
+ *   is more efficient.
+ *   When D and x are specified, G is not required. However, not providing G
+ *   will significantly degrade efficiency.
+ *   The target error must be specified in eps. A hard limit on the number
+ *   of atoms can also be specified via the parameter T. Otherwise, T should 
+ *   be negative. Finally, set erroromp to nonzero.
+ *
+ *
+ * Returns: 
+ *   An mxArray containing the sparse representations of the signals in x
+ *   (allocated using the appropriate mxCreateXXX() function).
+ *   The array is either full or sparse, depending on gamma_mode.
+ *
+ **************************************************************************/
+mxArray* ompcoreGabor(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
+                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompmex.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,133 @@
+/**************************************************************************
+ *
+ * File name: ompmex.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ *************************************************************************/
+
+#include "ompcore.h"
+#include "omputils.h"
+#include "mexutils.h"
+
+
+/* Input Arguments */
+
+#define IN_D          prhs[0]
+#define IN_X          prhs[1]
+#define IN_DtX        prhs[2]
+#define IN_G          prhs[3]
+#define IN_T          prhs[4]
+#define IN_SPARSE_G   prhs[5]
+#define IN_MSGDELTA   prhs[6]
+#define IN_PROFILE    prhs[7]
+
+
+/* Output Arguments */
+
+#define	GAMMA_OUT     plhs[0]
+
+
+/***************************************************************************************/
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
+
+{
+  double *D, *x, *DtX, *G, msgdelta;
+  int gmode, profile, T;
+  mwSize m, n, L;   /* D is n x m , X is n x L, DtX is m x L */
+  
+  
+  /* check parameters */
+  
+  checkmatrix(IN_D, "OMP", "D");
+  checkmatrix(IN_X, "OMP", "X");
+  checkmatrix(IN_DtX, "OMP", "DtX");
+  checkmatrix(IN_G, "OMP", "G");
+  
+  checkscalar(IN_T, "OMP", "T");
+  checkscalar(IN_SPARSE_G, "OMP", "sparse_g");
+  checkscalar(IN_MSGDELTA, "OMP", "msgdelta");
+  checkscalar(IN_PROFILE, "OMP", "profile");
+
+  
+  /* get parameters */
+  
+  x = D = DtX = G = 0;
+  
+  if (!mxIsEmpty(IN_D))
+    D = mxGetPr(IN_D);
+  
+  if (!mxIsEmpty(IN_X))
+    x = mxGetPr(IN_X);
+  
+  if (!mxIsEmpty(IN_DtX))
+    DtX = mxGetPr(IN_DtX);
+  
+  if (!mxIsEmpty(IN_G))
+    G = mxGetPr(IN_G);
+  
+  T = (int)(mxGetScalar(IN_T)+1e-2);
+  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
+    gmode = SPARSE_GAMMA;
+  }
+  else {
+    gmode = FULL_GAMMA;
+  }
+  msgdelta = mxGetScalar(IN_MSGDELTA);
+  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
+  
+  
+  /* check sizes */
+  
+  if (D && x) {
+    n = mxGetM(IN_D);
+    m = mxGetN(IN_D);
+    L = mxGetN(IN_X);
+    
+    if (mxGetM(IN_X) != n) {
+      mexErrMsgTxt("D and X have incompatible sizes.");
+    }
+    
+    if (G) {
+      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+        mexErrMsgTxt("G must be a square matrix.");
+      }
+      if (mxGetN(IN_G) != m) {
+        mexErrMsgTxt("D and G have incompatible sizes.");
+      }
+    }
+  }
+  
+  else if (DtX) {
+    m = mxGetM(IN_DtX);
+    L = mxGetN(IN_DtX);
+    
+    n = T;  /* arbitrary - it is enough to assume signal length is T */
+    
+    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+      mexErrMsgTxt("G must be a square matrix.");
+    }
+    if (mxGetN(IN_G) != m) {
+      mexErrMsgTxt("DtX and G have incompatible sizes.");
+    }
+  }
+  
+  else {
+    mexErrMsgTxt("Either D and X, or DtX, must be specified.");
+  }
+  
+  
+  /* Do OMP! */
+  
+  GAMMA_OUT = ompcore(D, x, DtX, 0, G, n, m, L, T, 0, gmode, profile, msgdelta, 0);
+  
+  return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompmex.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,22 @@
+%This is the Matlab interface to the OMP MEX implementation.
+%The function is not for independent use, only through omp.m.
+
+
+%OMPMEX Matlab interface to the OMP MEX implementation.
+%  GAMMA = OMPMEX(D,X,DtX,G,L,SPARSE_G,MSGDELTA,PROFILE) invokes the OMP
+%  MEX function according to the specified parameters. Not all the
+%  parameters are required. Those among D, X, DtX and G which are not
+%  specified should be passed as [].
+%
+%  L - the target sparsity.
+%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
+%  MSGDELTA - the delay in secs between messages. Zero means no messages.
+%  PROFILE - nonzero means that profiling information should be printed.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompmexGabor.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,133 @@
+/**************************************************************************
+ *
+ * File name: ompmex.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ *************************************************************************/
+
+#include "ompcoreGabor.h"
+#include "omputils.h"
+#include "mexutils.h"
+
+
+/* Input Arguments */
+
+#define IN_D          prhs[0]
+#define IN_X          prhs[1]
+#define IN_DtX        prhs[2]
+#define IN_G          prhs[3]
+#define IN_T          prhs[4]
+#define IN_SPARSE_G   prhs[5]
+#define IN_MSGDELTA   prhs[6]
+#define IN_PROFILE    prhs[7]
+
+
+/* Output Arguments */
+
+#define	GAMMA_OUT     plhs[0]
+
+
+/***************************************************************************************/
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
+
+{
+  double *D, *x, *DtX, *G, msgdelta;
+  int gmode, profile, T;
+  mwSize m, n, L;   /* D is n x m , X is n x L, DtX is m x L */
+  
+  
+  /* check parameters */
+  
+  checkmatrix(IN_D, "OMP", "D");
+  checkmatrix(IN_X, "OMP", "X");
+  checkmatrix(IN_DtX, "OMP", "DtX");
+  checkmatrix(IN_G, "OMP", "G");
+  
+  checkscalar(IN_T, "OMP", "T");
+  checkscalar(IN_SPARSE_G, "OMP", "sparse_g");
+  checkscalar(IN_MSGDELTA, "OMP", "msgdelta");
+  checkscalar(IN_PROFILE, "OMP", "profile");
+
+  
+  /* get parameters */
+  
+  x = D = DtX = G = 0;
+  
+  if (!mxIsEmpty(IN_D))
+    D = mxGetPr(IN_D);
+  
+  if (!mxIsEmpty(IN_X))
+    x = mxGetPr(IN_X);
+  
+  if (!mxIsEmpty(IN_DtX))
+    DtX = mxGetPr(IN_DtX);
+  
+  if (!mxIsEmpty(IN_G))
+    G = mxGetPr(IN_G);
+  
+  T = (int)(mxGetScalar(IN_T)+1e-2);
+  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
+    gmode = SPARSE_GAMMA;
+  }
+  else {
+    gmode = FULL_GAMMA;
+  }
+  msgdelta = mxGetScalar(IN_MSGDELTA);
+  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
+  
+  
+  /* check sizes */
+  
+  if (D && x) {
+    n = mxGetM(IN_D);
+    m = mxGetN(IN_D);
+    L = mxGetN(IN_X);
+    
+    if (mxGetM(IN_X) != n) {
+      mexErrMsgTxt("D and X have incompatible sizes.");
+    }
+    
+    if (G) {
+      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+        mexErrMsgTxt("G must be a square matrix.");
+      }
+      if (mxGetN(IN_G) != m) {
+        mexErrMsgTxt("D and G have incompatible sizes.");
+      }
+    }
+  }
+  
+  else if (DtX) {
+    m = mxGetM(IN_DtX);
+    L = mxGetN(IN_DtX);
+    
+    n = T;  /* arbitrary - it is enough to assume signal length is T */
+    
+    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
+      mexErrMsgTxt("G must be a square matrix.");
+    }
+    if (mxGetN(IN_G) != m) {
+      mexErrMsgTxt("DtX and G have incompatible sizes.");
+    }
+  }
+  
+  else {
+    mexErrMsgTxt("Either D and X, or DtX, must be specified.");
+  }
+  
+  
+  /* Do OMP! */
+  
+  GAMMA_OUT = ompcoreGabor(D, x, DtX, 0, G, n, m, L, T, 0, gmode, profile, msgdelta, 0);
+  
+  return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompmexGabor.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,22 @@
+%This is the Matlab interface to the OMP MEX implementation.
+%The function is not for independent use, only through omp.m.
+
+
+%OMPMEX Matlab interface to the OMP MEX implementation.
+%  GAMMA = OMPMEXGABOR(D,X,DtX,G,L,SPARSE_G,MSGDELTA,PROFILE) invokes the OMP
+%  MEX function according to the specified parameters. Not all the
+%  parameters are required. Those among D, X, DtX and G which are not
+%  specified should be passed as [].
+%
+%  L - the target sparsity.
+%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
+%  MSGDELTA - the delay in secs between messages. Zero means no messages.
+%  PROFILE - nonzero means that profiling information should be printed.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2009
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompprof.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,113 @@
+/**************************************************************************
+ *
+ * File name: ompprof.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 11.4.2009
+ *
+ *************************************************************************/
+
+
+#include "ompprof.h"
+
+
+/* initialize profiling information */
+
+void initprofdata(profdata *pd)
+{
+  pd->DtX_time = 0;
+  pd->XtX_time = 0;
+  pd->DtR_time = 0;
+  pd->maxabs_time = 0;
+  pd->DtD_time = 0;
+  pd->Lchol_time = 0;
+  pd->compcoef_time = 0;
+  pd->update_DtR_time = 0;
+  pd->update_resnorm_time = 0;
+  pd->compres_time = 0;
+  pd->indexsort_time = 0;
+  
+  pd->DtX_time_counted = 0;
+  pd->XtX_time_counted = 0;
+  pd->DtR_time_counted = 0;
+  pd->DtD_time_counted = 0;
+  pd->update_DtR_time_counted = 0;
+  pd->resnorm_time_counted = 0;
+  pd->compres_time_counted = 0;
+  pd->indexsort_time_counted = 0;
+  
+  pd->prevtime = clock();
+}
+
+
+/* add elapsed time to profiling data according to specified computation */
+
+void addproftime(profdata *pd, int comptype)
+{
+  switch(comptype) {
+    case DtX_TIME:            pd->DtX_time            += clock()-pd->prevtime; pd->DtX_time_counted = 1; break;
+    case XtX_TIME:            pd->XtX_time            += clock()-pd->prevtime; pd->XtX_time_counted = 1; break;
+    case DtR_TIME:            pd->DtR_time            += clock()-pd->prevtime; pd->DtR_time_counted = 1; break;
+    case DtD_TIME:            pd->DtD_time            += clock()-pd->prevtime; pd->DtD_time_counted = 1; break;
+    case COMPRES_TIME:        pd->compres_time        += clock()-pd->prevtime; pd->compres_time_counted = 1; break;
+    case UPDATE_DtR_TIME:     pd->update_DtR_time     += clock()-pd->prevtime; pd->update_DtR_time_counted = 1; break;
+    case UPDATE_RESNORM_TIME: pd->update_resnorm_time += clock()-pd->prevtime; pd->resnorm_time_counted = 1; break;
+    case INDEXSORT_TIME:      pd->indexsort_time      += clock()-pd->prevtime; pd->indexsort_time_counted = 1; break;
+    case MAXABS_TIME:         pd->maxabs_time         += clock()-pd->prevtime; break;
+    case LCHOL_TIME:          pd->Lchol_time          += clock()-pd->prevtime; break;
+    case COMPCOEF_TIME:       pd->compcoef_time       += clock()-pd->prevtime; break;
+  }
+  pd->prevtime = clock();
+}
+
+
+/* print profiling info */
+
+void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum)
+{
+  clock_t tottime;
+  
+  tottime = pd->DtX_time + pd->XtX_time + pd->DtR_time + pd->DtD_time + pd->compres_time + pd->maxabs_time + 
+            pd->Lchol_time + pd->compcoef_time + pd->update_DtR_time + pd->update_resnorm_time + pd->indexsort_time;
+  
+  mexPrintf("\n\n*****  Profiling information for %s  *****\n\n", erroromp? "OMP2" : "OMP");
+  
+  mexPrintf("OMP mode: %s\n\n", batchomp? "Batch-OMP" : "OMP-Cholesky");
+  
+  mexPrintf("Total signals processed: %d\n\n", signum);
+  
+  if (pd->DtX_time_counted) {
+    mexPrintf("Compute DtX time:      %7.3lf seconds\n", pd->DtX_time/(double)CLOCKS_PER_SEC);
+  }
+  if (pd->XtX_time_counted) {
+    mexPrintf("Compute XtX time:      %7.3lf seconds\n", pd->XtX_time/(double)CLOCKS_PER_SEC);
+  }
+  mexPrintf("Max abs time:          %7.3lf seconds\n", pd->maxabs_time/(double)CLOCKS_PER_SEC);
+  if (pd->DtD_time_counted) {
+    mexPrintf("Compute DtD time:      %7.3lf seconds\n", pd->DtD_time/(double)CLOCKS_PER_SEC);
+  }
+  mexPrintf("Lchol update time:     %7.3lf seconds\n", pd->Lchol_time/(double)CLOCKS_PER_SEC);
+  mexPrintf("Compute coef time:     %7.3lf seconds\n", pd->compcoef_time/(double)CLOCKS_PER_SEC);
+  if (pd->compres_time_counted) {
+    mexPrintf("Compute R time:        %7.3lf seconds\n", pd->compres_time/(double)CLOCKS_PER_SEC);
+  }
+  if (pd->DtR_time_counted) {
+    mexPrintf("Compute DtR time:      %7.3lf seconds\n", pd->DtR_time/(double)CLOCKS_PER_SEC);
+  }
+  if (pd->update_DtR_time_counted) {
+    mexPrintf("Update DtR time:       %7.3lf seconds\n", pd->update_DtR_time/(double)CLOCKS_PER_SEC);
+  }
+  if (pd->resnorm_time_counted) {
+    mexPrintf("Update resnorm time:   %7.3lf seconds\n", pd->update_resnorm_time/(double)CLOCKS_PER_SEC);
+  }
+  if (pd->indexsort_time_counted) {
+    mexPrintf("Index sort time:       %7.3lf seconds\n", pd->indexsort_time/(double)CLOCKS_PER_SEC);
+  }
+  mexPrintf("---------------------------------------\n");
+  mexPrintf("Total time:            %7.3lf seconds\n\n", tottime/(double)CLOCKS_PER_SEC);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/ompprof.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,106 @@
+/**************************************************************************
+ *
+ * File name: ompprof.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ * Collection of definitions and functions for profiling the OMP method.
+ *
+ *************************************************************************/
+
+
+#ifndef __OMP_PROF_H__
+#define __OMP_PROF_H__
+
+#include "mex.h"
+#include <time.h>
+
+
+
+/**************************************************************************
+ *
+ * Constants and data types.
+ *
+ **************************************************************************/
+
+
+/* constants denoting the various parts of the algorithm */
+
+enum { DtX_TIME, XtX_TIME, DtR_TIME, MAXABS_TIME, DtD_TIME, LCHOL_TIME, COMPCOEF_TIME, 
+       UPDATE_DtR_TIME, UPDATE_RESNORM_TIME, COMPRES_TIME, INDEXSORT_TIME };
+
+       
+       
+/* profiling data container with counters for each part of the algorithm */
+       
+typedef struct profdata 
+{
+  clock_t prevtime;  /* the time when last initialization/call to addproftime() was performed */
+  
+  clock_t DtX_time;
+  clock_t XtX_time;
+  clock_t DtR_time;
+  clock_t maxabs_time;
+  clock_t DtD_time;
+  clock_t Lchol_time;
+  clock_t compcoef_time;
+  clock_t update_DtR_time;
+  clock_t update_resnorm_time;
+  clock_t compres_time;
+  clock_t indexsort_time;
+  
+  /* flags indicating whether profiling data was gathered */
+  int DtX_time_counted;
+  int XtX_time_counted;
+  int DtR_time_counted;
+  int DtD_time_counted;
+  int update_DtR_time_counted;
+  int resnorm_time_counted;
+  int compres_time_counted;
+  int indexsort_time_counted;
+  
+} profdata;
+
+
+
+/**************************************************************************
+ *
+ * Initialize a profdata structure, zero all counters, and start its timer.
+ *
+ **************************************************************************/
+void initprofdata(profdata *pd);
+
+
+/**************************************************************************
+ *
+ * Add elapsed time from last call to addproftime(), or from initialization
+ * of profdata, to the counter specified by comptype. comptype must be one
+ * of the constants in the enumeration above.
+ *
+ **************************************************************************/
+void addproftime(profdata *pd, int comptype);
+
+
+/**************************************************************************
+ *
+ * Print the current contents of the counters in profdata.
+ *
+ * Parameters:
+ *   pd - the profdata to print
+ *   erroromp - indicates whether error-based (nonzero) or sparsity-based (zero)
+ *              omp was performed.
+ *   batchomp - indicates whether batch-omp (nonzero) or omp-cholesky (zero)
+ *              omp was performed.
+ *   signum   - number of signals processed by omp
+ *
+ **************************************************************************/
+void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum);
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omputils.c	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,89 @@
+/**************************************************************************
+ *
+ * File name: omputils.c
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ *************************************************************************/
+
+#include "omputils.h"
+#include <math.h>
+
+
+const char FULL_GAMMA_STR[] = "full";
+const char SPARSE_GAMMA_STR[] = "sparse";
+
+
+/* convert seconds to hours, minutes and seconds */
+
+void secs2hms(double sectot, int *hrs, int *mins, double *secs)
+{
+  *hrs = (int)(floor(sectot/3600)+1e-2);
+  sectot = sectot - 3600*(*hrs);
+  *mins = (int)(floor(sectot/60)+1e-2);
+  *secs = sectot - 60*(*mins);
+}
+
+
+/* quicksort, public-domain C implementation by Darel Rex Finley. */
+/* modification: sorts the array data[] as well, according to the values in the array vals[] */
+
+#define  MAX_LEVELS  300
+
+void quicksort(mwIndex vals[], double data[], mwIndex n) {
+  
+  long piv, beg[MAX_LEVELS], end[MAX_LEVELS], i=0, L, R, swap ;
+  double datapiv;
+  
+  beg[0]=0;
+  end[0]=n;
+  
+  while (i>=0) {
+    
+    L=beg[i]; 
+    R=end[i]-1;
+    
+    if (L<R) {
+      
+      piv=vals[L];
+      datapiv=data[L];
+      
+      while (L<R) 
+      {
+        while (vals[R]>=piv && L<R) 
+          R--;
+        if (L<R) {
+          vals[L]=vals[R];
+          data[L++]=data[R];
+        }
+        
+        while (vals[L]<=piv && L<R) 
+          L++;
+        if (L<R) { 
+          vals[R]=vals[L];
+          data[R--]=data[L];
+        }
+      }
+      
+      vals[L]=piv;
+      data[L]=datapiv;
+      
+      beg[i+1]=L+1;
+      end[i+1]=end[i];
+      end[i++]=L;
+      
+      if (end[i]-beg[i] > end[i-1]-beg[i-1]) {
+        swap=beg[i]; beg[i]=beg[i-1]; beg[i-1]=swap;
+        swap=end[i]; end[i]=end[i-1]; end[i-1]=swap;
+      }
+    }
+    else {
+      i--;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/omputils.h	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,77 @@
+/**************************************************************************
+ *
+ * File name: omputils.h
+ *
+ * Ron Rubinstein
+ * Computer Science Department
+ * Technion, Haifa 32000 Israel
+ * ronrubin@cs
+ *
+ * Last Updated: 18.8.2009
+ *
+ * Utility definitions and functions for the OMP library.
+ *
+ *************************************************************************/
+
+
+#ifndef __OMP_UTILS_H__
+#define __OMP_UTILS_H__
+
+#include "mex.h"
+
+
+/* constants for the representation mode of gamma */
+
+extern const char FULL_GAMMA_STR[];      /* "full" */
+extern const char SPARSE_GAMMA_STR[];    /* "sparse" */
+
+
+#define FULL_GAMMA 1
+#define SPARSE_GAMMA 2
+#define INVALID_MODE 3
+
+
+
+/**************************************************************************
+ * Memory management for OMP2.
+ *
+ * GAMMA_INC_FACTOR:
+ * The matrix GAMMA is allocated with sqrt(n)/2 coefficients per signal,
+ * for a total of nzmax = L*sqrt(n)/2 nonzeros. Whenever GAMMA needs to be
+ * increased, it is increased by a factor of GAMMA_INC_FACTOR.
+ *
+ * MAT_INC_FACTOR:
+ * The matrices Lchol, Gsub and Dsub are allocated with sqrt(n)/2
+ * columns each. If additional columns are needed, this number is 
+ * increased by a factor of MAT_INC_FACTOR.
+ **************************************************************************/
+
+#define GAMMA_INC_FACTOR (1.4)
+#define MAT_INC_FACTOR (1.6)
+
+
+
+/**************************************************************************
+ * Convert number of seconds to hour, minute and second representation.
+ *
+ * Parameters:
+ *   sectot - total number of seconds
+ *   hrs, mins, secs - output hours (whole) and minutes (whole) and seconds
+ *
+ **************************************************************************/
+void secs2hms(double sectot, int *hrs, int *mins, double *secs);
+
+
+
+/**************************************************************************
+ * QuickSort - public-domain C implementation by Darel Rex Finley.
+ *
+ * Modified to sort both the array vals[] and the array data[] according 
+ * to the values in the array vals[].
+ *
+ **************************************************************************/
+void quicksort(mwIndex vals[], double data[], mwIndex n);
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_ompGabor/printf.m	Mon Jul 25 17:27:05 2011 +0100
@@ -0,0 +1,26 @@
+function str = printf(varargin)
+%PRINTF Print formatted text to screen.
+%  PRINTF(FMT,VAL1,VAL2,...) formats the data in VAL1,VAL2,... according to
+%  the format string FMT, and prints the result to the screen.
+%
+%  The call to PRINTF(FMT,VAL1,VAL2,...) simply invokes the call
+%  DISP(SPRINTF(FMT,VAL1,VAL2,...)). For a complete description of the
+%  format string options see function SPRINTF.
+%
+%  STR = PRINTF(...) also returns the formatted string.
+
+
+%  Ron Rubinstein
+%  Computer Science Department
+%  Technion, Haifa 32000 Israel
+%  ronrubin@cs
+%
+%  April 2008
+
+
+if (nargout>0)
+  str = sprintf(varargin{:});
+  disp(str);
+else
+  disp(sprintf(varargin{:}));
+end
--- a/toolboxes/AudioInpaintingToolbox/Experiments/DeclippingExperiment/declipOneSoundExperiment.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/toolboxes/AudioInpaintingToolbox/Experiments/DeclippingExperiment/declipOneSoundExperiment.m	Mon Jul 25 17:27:05 2011 +0100
@@ -53,7 +53,7 @@
     expParam.solver.function = @inpaintSignal_IndependentProcessingOfFrames;
     expParam.solver.param.N = 512; % frame length
     expParam.solver.param.N = 256; % frame length
-    expParam.solver.param.inpaintFrame = @inpaintFrame_OMP_Gabor; % solver function
+    expParam.solver.param.inpaintFrame = @inpaintFrame_consOMP_Gabor; % solver function
     expParam.solver.param.OMPerr = 0.001;
     expParam.solver.param.sparsityDegree = expParam.solver.param.N/4;
     expParam.solver.param.D_fun = @Gabor_Dictionary; % Dictionary (function handle)
--- a/util/SMALL_init_solver.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/util/SMALL_init_solver.m	Mon Jul 25 17:27:05 2011 +0100
@@ -1,4 +1,4 @@
-function solver = SMALL_init_solver(varargin)
+function solver = SMALL_init_solver(toolbox, name, param, profile)
 %%   Function initialise SMALL structure for sparse representation.
 %   Optional input variables:
 %       toolbox - name of Dictionary Learning toolbox you want to use
@@ -17,11 +17,29 @@
 %
 %%
 
-solver.toolbox=[];
-solver.name=[];
-solver.param=[];
-solver.solution=[];
-solver.reconstructed=[];
-solver.time=[];
+if ~ exist( 'toolbox', 'var' ) || isempty(toolbox) 
+    solver.toolbox = []; 
+else
+    solver.toolbox = toolbox;
+end
+if ~ exist( 'name', 'var' ) || isempty(name) 
+    solver.name = [];
+else
+    solver.name = name;
+end
+if ~ exist( 'param', 'var' ) || isempty(param) 
+    solver.param = [];
+else
+    solver.param = param;
+end
+if ~ exist( 'profile', 'var' ) || isempty(profile) 
+    solver.profile = 1;
+else
+    solver.profile = profile;
+end
+solver.add_constraints = 0;
+solver.solution = [];
+solver.reconstructed = [];
+solver.time = [];
 
 end
\ No newline at end of file
--- a/util/SMALL_solve.m	Thu Jul 21 16:37:14 2011 +0100
+++ b/util/SMALL_solve.m	Mon Jul 25 17:27:05 2011 +0100
@@ -39,7 +39,10 @@
     b = Problem.b;            % The right-hand-side vector.
 end
 %%
-fprintf('\nStarting solver %s... \n', solver.name);
+if (solver.profile)
+    fprintf('\nStarting solver %s... \n', solver.name);
+end
+
 start=cputime;
 tStart=tic;
 if strcmpi(solver.toolbox,'sparselab')
@@ -93,8 +96,10 @@
 %   Sparse representation time
 tElapsed=toc(tStart);
 solver.time = cputime - start;
-fprintf('Solver %s finished task in %2f seconds (cpu time). \n', solver.name, solver.time);
-fprintf('Solver %s finished task in %2f seconds (tic-toc time). \n', solver.name, tElapsed);
+if (solver.profile)
+    fprintf('Solver %s finished task in %2f seconds (cpu time). \n', solver.name, solver.time);
+    fprintf('Solver %s finished task in %2f seconds (tic-toc time). \n', solver.name, tElapsed);
+end
 solver.time=tElapsed;
 % geting around out of memory problem when converting big matrix from
 % sparse to full...
@@ -105,7 +110,7 @@
     solver.solution = full(y);
 end
 if isfield(Problem,'reconstruct')
-%   Reconstruct the signal from the solution
-solver.reconstructed  = Problem.reconstruct(solver.solution);
+    %   Reconstruct the signal from the solution
+    solver.reconstructed  = Problem.reconstruct(solver.solution);
 end
 end
--- a/util/ksvd utils/ompbox utils/make.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-function make
-%MAKE Build the OMPBox package.
-%  MAKE compiles all OMPBox MEX functions, using Matlab's default MEX
-%  compiler. If the MEX compiler has not been set-up before, please run
-%
-%    mex -setup
-%
-%  before using this MAKE file.
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  August 2009
-
-
-% detect platform 
-
-compstr = computer;
-is64bit = strcmp(compstr(end-1:end),'64');
-
-
-% compilation parameters
-
-compile_params = cell(0);
-if (is64bit)
-  compile_params{1} = '-largeArrayDims';
-end
-
-
-% Compile files %
-
-ompsources = {'mexutils.c','ompcoreGabor.c','omputils.c','myblas.c','ompprof.c'};
-
-disp('Compiling ompmex...');
-mex('-g','ompmexGabor.c', ompsources{:},compile_params{:});
-
-disp('Compiling omp2mex...');
-mex('-g','omp2mexGabor.c',ompsources{:},compile_params{:});
-
--- a/util/ksvd utils/ompbox utils/mexutils.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/**************************************************************************
- *
- * File name: mexutils.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 15.8.2009
- *
- *************************************************************************/
-
-#include "mexutils.h"
-#include <math.h>
-
-
-
-/* verify that the mxArray contains a double matrix */
-
-void checkmatrix(const mxArray *param, char *fname, char *pname)
-{
-  char errmsg[100];
-  sprintf(errmsg, "%.15s requires that %.25s be a double matrix.", fname, pname);
-  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2) {
-    mexErrMsgTxt(errmsg);
-  }
-}
-
-
-/* verify that the mxArray contains a 1-D double vector */
-
-void checkvector(const mxArray *param, char *fname, char *pname)
-{
-  char errmsg[100];
-  sprintf(errmsg, "%.15s requires that %.25s be a double vector.", fname, pname);
-  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) {
-    mexErrMsgTxt(errmsg);
-  }
-}
-
-
-/* verify that the mxArray contains a double scalar */
-
-void checkscalar(const mxArray *param, char *fname, char *pname)
-{
-  char errmsg[100];
-  sprintf(errmsg, "%.15s requires that %.25s be a double scalar.", fname, pname);
-  if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || 
-      mxGetM(param)!=1 || mxGetN(param)!=1) 
-  {
-    mexErrMsgTxt(errmsg);
-  }
-}
-
-
-/* verify that the mxArray contains a sparse matrix */
-
-void checksparse(const mxArray *param, char *fname, char *pname)
-{
-  char errmsg[100];
-  sprintf(errmsg, "%.15s requires that %.25s be sparse.", fname, pname);
-  if (!mxIsSparse(param)) {
-    mexErrMsgTxt(errmsg);
-  }
-}
-
-
-/* verify that the mxArray contains a 1-dimensional cell array */
-
-void checkcell_1d(const mxArray *param, char *fname, char *pname)
-{
-  char errmsg[100];
-  sprintf(errmsg, "%.15s requires that %.25s be a 1-D cell array.", fname, pname);
-  if (!mxIsCell(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) {
-    mexErrMsgTxt(errmsg);
-  }
-}
-
--- a/util/ksvd utils/ompbox utils/mexutils.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/**************************************************************************
- *
- * File name: mexutils.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- * Utility functions for MEX files.
- *
- *************************************************************************/
-
-
-#ifndef __MEX_UTILS_H__
-#define __MEX_UTILS_H__
-
-#include "mex.h"
-
-
-
-/**************************************************************************
- * Function checkmatrix:
- *
- * Verify that the specified mxArray is real, of type double, and has 
- * no more than two dimensions. If not, an error message is printed
- * and the mex file terminates.
- * 
- * Parameters:
- *   param - the mxArray to be checked
- *   fname - the name of the function where the error occured (15 characters or less)
- *   pname - the name of the parameter (25 characters or less)
- *
- **************************************************************************/
-void checkmatrix(const mxArray *param, char *fname, char *pname);
-
-
-/**************************************************************************
- * Function checkvector:
- *
- * Verify that the specified mxArray is 1-D, real, and of type double. The
- * vector may be a column or row vector. Otherwise, an error message is
- * printed and the mex file terminates.
- * 
- * Parameters:
- *   param - the mxArray to be checked
- *   fname - the name of the function where the error occured (15 characters or less)
- *   pname - the name of the parameter (25 characters or less)
- *
- **************************************************************************/
-void checkvector(const mxArray *param, char *fname, char *pname);
-
-
-/**************************************************************************
- * Function checkscalar:
- *
- * Verify that the specified mxArray represents a real double scalar value. 
- * If not, an error message is printed and the mex file terminates.
- * 
- * Parameters:
- *   param - the mxArray to be checked
- *   fname - the name of the function where the error occured (15 characters or less)
- *   pname - the name of the parameter (25 characters or less)
- *
- **************************************************************************/
-void checkscalar(const mxArray *param, char *fname, char *pname);
-
-
-/**************************************************************************
- * Function checksparse:
- *
- * Verify that the specified mxArray contains a sparse matrix. If not,
- * an error message is printed and the mex file terminates.
- * 
- * Parameters:
- *   param - the mxArray to be checked
- *   fname - the name of the function where the error occured (15 characters or less)
- *   pname - the name of the parameter (25 characters or less)
- *
- **************************************************************************/
-void checksparse(const mxArray *param, char *fname, char *pname);
-
-
-/**************************************************************************
- * Function checkcell_1d:
- *
- * Verify that the specified mxArray is a 1-D cell array. The cell array 
- * may be arranged as either a column or a row. If not, an error message 
- * is printed and the mex file terminates.
- * 
- * Parameters:
- *   param - the mxArray to be checked
- *   fname - the name of the function where the error occured (15 characters or less)
- *   pname - the name of the parameter (25 characters or less)
- *
- **************************************************************************/
-void checkcell_1d(const mxArray *param, char *fname, char *pname);
-
-
-#endif
-
--- a/util/ksvd utils/ompbox utils/myblas.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,673 +0,0 @@
-/**************************************************************************
- *
- * File name: myblas.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Version: 1.1
- * Last updated: 13.8.2009
- *
- *************************************************************************/
-
-
-#include "myblas.h"
-#include <ctype.h>
-
-
-/* find maximum of absolute values */
-
-mwIndex maxabs(double c[], mwSize m)
-{
-  mwIndex maxid=0, k;
-  double absval, maxval = SQR(*c);   /* use square which is quicker than absolute value */
-
-  for (k=1; k<m; ++k) {
-    absval = SQR(c[k]);
-    if (absval > maxval) {
-      maxval = absval;
-      maxid = k;
-    }
-  }
-  return maxid;
-}
-
-
-/* compute y := alpha*x + y */
-
-void vec_sum(double alpha, double x[], double y[], mwSize n)
-{
-  mwIndex i;
-
-  for (i=0; i<n; ++i) {
-    y[i] += alpha*x[i];
-  }
-}
-
-/* compute y := alpha*x .* y */
-
-void vec_smult(double alpha, double x[], double y[], mwSize n)
-{
-  mwIndex i;
-
-  for (i=0; i<n; ++i) {
-    y[i] *= alpha*x[i];
-  }
-}
-
-/* compute y := alpha*A*x */
-
-void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
-{
-  mwIndex i, j, i_n;
-  double *Ax;
-
-  Ax = mxCalloc(n,sizeof(double));
-
-  for (i=0; i<m; ++i) {
-    i_n = i*n;
-    for (j=0; j<n; ++j) {
-      Ax[j] += A[i_n+j] * x[i];
-    }
-  }
-
-  for (j=0; j<n; ++j) {
-    y[j] = alpha*Ax[j];
-  }
-
-  mxFree(Ax);
-}
-
-
-/* compute y := alpha*A'*x */
-
-void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
-{
-  mwIndex i, j, n_i;
-  double sum0, sum1, sum2, sum3;
-
-  for (j=0; j<m; ++j) {
-    y[j] = 0;
-  }
-
-  /* use loop unrolling to accelerate computation */
-
-  for (i=0; i<m; ++i) {
-    n_i = n*i;
-    sum0 = sum1 = sum2 = sum3 = 0;
-    for (j=0; j+4<n; j+=4) {
-      sum0 += A[n_i+j]*x[j];
-      sum1 += A[n_i+j+1]*x[j+1];
-      sum2 += A[n_i+j+2]*x[j+2];
-      sum3 += A[n_i+j+3]*x[j+3];
-    }
-    y[i] += alpha * ((sum0 + sum1) + (sum2 + sum3));
-    while (j<n) {
-      y[i] += alpha*A[n_i+j]*x[j];
-      j++;
-    }
-  }
-}
-
-
-/* compute y := alpha*A*x */
-
-void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, j1, j2;
-
-  for (i=0; i<n; ++i) {
-    y[i] = 0;
-  }
-  
-  j2 = jc[0];
-  for (i=0; i<m; ++i) {
-    j1 = j2; j2 = jc[i+1];
-    for (j=j1; j<j2; ++j) {
-      y[ir[j]] += alpha * pr[j] * x[i];
-    }
-  }
-  
-}
-
-
-/* compute y := alpha*A'*x */
-
-void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, j1, j2;
-  
-  for (i=0; i<m; ++i) {
-    y[i] = 0;
-  }
-  
-  j2 = jc[0];
-  for (i=0; i<m; ++i) {
-    j1 = j2; j2 = jc[i+1];
-    for (j=j1; j<j2; ++j) {
-      y[i] += alpha * pr[j] * x[ir[j]];
-    }
-  }
-  
-}
-
-
-/* compute y := alpha*A*x */
-
-void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, j_n, k, kend;
-  
-  for (i=0; i<n; ++i) {
-    y[i] = 0;
-  }
-  
-  kend = jc[1];
-  if (kend==0) {   /* x is empty */
-    return;
-  }
-  
-  for (k=0; k<kend; ++k) {
-    j = ir[k];
-    j_n = j*n;
-    for (i=0; i<n; ++i) {
-      y[i] += alpha * A[i+j_n] * pr[k];
-    }
-  }
-
-}
-
-
-/* compute y := alpha*A'*x */
-
-void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, j_n, k, kend;
-  
-  for (i=0; i<m; ++i) {
-    y[i] = 0;
-  }
-  
-  kend = jc[1];
-  if (kend==0) {   /* x is empty */
-    return;
-  }
-  
-  for (j=0; j<m; ++j) {
-    j_n = j*n;
-    for (k=0; k<kend; ++k) {
-      i = ir[k];
-      y[j] += alpha * A[i+j_n] * pr[k];
-    }
-  }
-  
-}
-
-
-/* compute y := alpha*A*x */
-
-void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, k, kend, j1, j2;
-
-  for (i=0; i<n; ++i) {
-    y[i] = 0;
-  }
-  
-  kend = jcx[1]; 
-  if (kend==0) {   /* x is empty */
-    return;
-  }
-  
-  for (k=0; k<kend; ++k) {
-    i = irx[k];
-    j1 = jc[i]; j2 = jc[i+1];
-    for (j=j1; j<j2; ++j) {
-      y[ir[j]] += alpha * pr[j] * prx[k];
-    }
-  }
-  
-}
-
-
-/* compute y := alpha*A'*x */
-
-void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
-{
-  
-  mwIndex i, j, k, jend, kend, jadd, kadd, delta;
-  
-  for (i=0; i<m; ++i) {
-    y[i] = 0;
-  }
-  
-  kend = jcx[1];
-  if (kend==0) {   /* x is empty */
-    return;
-  }
-  
-  for (i=0; i<m; ++i) {
-    j = jc[i]; 
-    jend = jc[i+1];
-    k = 0;
-    while (j<jend && k<kend) {
-      
-      delta = ir[j] - irx[k];
-      
-      if (delta) { /* if indices differ - increment the smaller one */
-        jadd = delta<0;
-        kadd = 1-jadd;
-        j += jadd;
-        k += kadd;
-      }
-      
-      else {    /* indices are equal - add to result and increment both */
-        y[i] += alpha * pr[j] * prx[k];
-        j++; k++;
-      }
-    }
-  }
-  
-}
-
-
-/* matrix-matrix multiplication */
-
-void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
-{
-  mwIndex i1, i2, i3, iX, iA, i2_n;
-  double b;
-  
-  for (i1=0; i1<n*k; i1++) {
-    X[i1] = 0;
-  }
-
-  for (i2=0; i2<m; ++i2) {
-    i2_n = i2*n;
-    iX = 0;
-    for (i3=0; i3<k; ++i3) {
-      iA = i2_n;
-      b = B[i2+i3*m];
-      for (i1=0; i1<n; ++i1) {
-        X[iX++] += A[iA++]*b;
-      }
-    }
-  }
-  
-  for (i1=0; i1<n*k; i1++) {
-    X[i1] *= alpha;
-  }
-}
-
-
-/* matrix-transpose-matrix multiplication */
-
-void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
-{
-  mwIndex i1, i2, i3, iX, iA, i2_n;
-  double *x, sum0, sum1, sum2, sum3;
-
-  for (i2=0; i2<m; ++i2) {
-    for (i3=0; i3<k; ++i3) {
-      sum0 = sum1 = sum2 = sum3 = 0;
-      for (i1=0; i1+4<n; i1+=4) {
-        sum0 += A[i1+0+i2*n]*B[i1+0+i3*n];
-        sum1 += A[i1+1+i2*n]*B[i1+1+i3*n];
-        sum2 += A[i1+2+i2*n]*B[i1+2+i3*n];
-        sum3 += A[i1+3+i2*n]*B[i1+3+i3*n];
-      }
-      X[i2+i3*m] = (sum0+sum1) + (sum2+sum3);
-      while(i1<n) {
-        X[i2+i3*m] += A[i1+i2*n]*B[i1+i3*n];
-        i1++;
-      }
-    }
-  }
-  
-  for (i1=0; i1<m*k; i1++) {
-    X[i1] *= alpha;
-  }
-}
-
-
-/* tensor-matrix product */
-
-void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
-{
-  mwIndex i1, i2, i3, i4, i2_n, nml;
-  double b;
-  
-  nml = n*m*l;
-  for (i1=0; i1<nml; ++i1) {
-    X[i1] = 0;
-  }
-
-  for (i2=0; i2<m; ++i2) {
-    i2_n = i2*n;
-    for (i3=0; i3<k; ++i3) {
-      for (i4=0; i4<l; ++i4) {
-        b = B[i4+i3*l];
-        for (i1=0; i1<n; ++i1) {
-          X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
-        }
-      }
-    }
-  }
-  
-  for (i1=0; i1<nml; ++i1) {
-    X[i1] *= alpha;
-  }
-}
-
-
-/* tensor-matrix-transpose product */
-
-void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
-{
-  mwIndex i1, i2, i3, i4, i2_n, nml;
-  double b;
-  
-  nml = n*m*l;
-  for (i1=0; i1<nml; ++i1) {
-    X[i1] = 0;
-  }
-
-  for (i2=0; i2<m; ++i2) {
-    i2_n = i2*n;
-    for (i4=0; i4<l; ++i4) {
-      for (i3=0; i3<k; ++i3) {
-        b = B[i3+i4*k];
-        for (i1=0; i1<n; ++i1) {
-          X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
-        }
-      }
-    }
-  }
-  
-  for (i1=0; i1<nml; ++i1) {
-    X[i1] *= alpha;
-  }
-}
-
-
-/* dot product */
-
-double dotprod(double a[], double b[], mwSize n)
-{
-  double sum = 0;
-  mwIndex i;
-  for (i=0; i<n; ++i)
-    sum += a[i]*b[i];
-  return sum;
-}
-
-
-/* find maximum of vector */
-
-mwIndex maxpos(double c[], mwSize m)
-{
-  mwIndex maxid=0, k;
-  double val, maxval = *c;
-
-  for (k=1; k<m; ++k) {
-    val = c[k];
-    if (val > maxval) {
-      maxval = val;
-      maxid = k;
-    }
-  }
-  return maxid;
-}
-
-
-/* solve L*x = b */
-
-void backsubst_L(double L[], double b[], double x[], mwSize n, mwSize k)
-{
-  mwIndex i, j;
-  double rhs;
-
-  for (i=0; i<k; ++i) {
-    rhs = b[i];
-    for (j=0; j<i; ++j) {
-      rhs -= L[j*n+i]*x[j];
-    }
-    x[i] = rhs/L[i*n+i];
-  }
-}
-
-
-/* solve L'*x = b */
-
-void backsubst_Lt(double L[], double b[], double x[], mwSize n, mwSize k)
-{
-  mwIndex i, j;
-  double rhs;
-
-  for (i=k; i>=1; --i) {
-    rhs = b[i-1];
-    for (j=i; j<k; ++j) {
-      rhs -= L[(i-1)*n+j]*x[j];
-    }
-    x[i-1] = rhs/L[(i-1)*n+i-1];
-  }
-}
-
-
-/* solve U*x = b */
-
-void backsubst_U(double U[], double b[], double x[], mwSize n, mwSize k)
-{
-  mwIndex i, j;
-  double rhs;
-
-  for (i=k; i>=1; --i) {
-    rhs = b[i-1];
-    for (j=i; j<k; ++j) {
-      rhs -= U[j*n+i-1]*x[j];
-    }
-    x[i-1] = rhs/U[(i-1)*n+i-1];
-  }
-}
-
-
-/* solve U'*x = b */
-
-void backsubst_Ut(double U[], double b[], double x[], mwSize n, mwSize k)
-{
-  mwIndex i, j;
-  double rhs;
-
-  for (i=0; i<k; ++i) {
-    rhs = b[i];
-    for (j=0; j<i; ++j) {
-      rhs -= U[i*n+j]*x[j];
-    }
-    x[i] = rhs/U[i*n+i];
-  }
-}
-
-
-/* back substitution solver */
-
-void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
-{
-  if (tolower(ul) == 'u') {
-    backsubst_U(A, b, x, n, k);
-  }
-  else if (tolower(ul) == 'l') {
-    backsubst_L(A, b, x, n, k);
-  }
-  else {
-    mexErrMsgTxt("Invalid triangular matrix type: must be ''U'' or ''L''");
-  }
-}
-
-
-/* solve equation set using cholesky decomposition */
-
-void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
-{
-  double *tmp;
-
-  tmp = mxMalloc(k*sizeof(double));
-
-  if (tolower(ul) == 'l') {
-    backsubst_L(A, b, tmp, n, k);
-    backsubst_Lt(A, tmp, x, n, k);
-  }
-  else if (tolower(ul) == 'u') {
-    backsubst_Ut(A, b, tmp, n, k);
-    backsubst_U(A, tmp, x, n, k);
-  }
-  else {
-    mexErrMsgTxt("Invalid triangular matrix type: must be either ''U'' or ''L''");
-  }
-
-  mxFree(tmp);
-}
-
-
-/* perform a permutation assignment y := x(ind(1:k)) */
-
-void vec_assign(double y[], double x[], mwIndex ind[], mwSize k)
-{
-  mwIndex i;
-
-  for (i=0; i<k; ++i)
-    y[i] = x[ind[i]];
-}
-
-
-/* matrix transpose */
-
-void transpose(double X[], double Y[], mwSize n, mwSize m)
-{
-  mwIndex i, j, i_m, j_n;
-  
-  if (n<m) {
-    for (j=0; j<m; ++j) {
-      j_n = j*n;
-      for (i=0; i<n; ++i) {
-        Y[j+i*m] = X[i+j_n];
-      }
-    }
-  }
-  else {
-    for (i=0; i<n; ++i) {
-      i_m = i*m;
-      for (j=0; j<m; ++j) {
-        Y[j+i_m] = X[i+j*n];
-      }
-    }
-  }
-}
-
-
-/* print contents of matrix */
-
-void printmat(double A[], int n, int m, char* matname)
-{
-  int i, j;
-  mexPrintf("\n%s = \n\n", matname);
-
-  if (n*m==0) {
-    mexPrintf("   Empty matrix: %d-by-%d\n\n", n, m);
-    return;
-  }
-
-  for (i=0; i<n; ++i) {
-    for (j=0; j<m; ++j)
-      mexPrintf("   %lf", A[j*n+i]);
-    mexPrintf("\n");
-  }
-  mexPrintf("\n");
-}
-
-
-/* print contents of sparse matrix */
-
-void printspmat(mxArray *a, char* matname)
-{
-  mwIndex *aJc = mxGetJc(a);
-  mwIndex *aIr = mxGetIr(a);
-  double *aPr = mxGetPr(a);
-
-  int i;
-
-  mexPrintf("\n%s = \n\n", matname);
-
-  for (i=0; i<aJc[1]; ++i)
-    printf("   (%d,1) = %lf\n", aIr[i]+1,aPr[i]);
-
-  mexPrintf("\n");
-}
-
-
-
-/* matrix multiplication using Winograd's algorithm */
-
-/*
-void mat_mat2(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
-{
-  
-  mwIndex i1, i2, i3, iX, iA, i2_n;
-  double b, *AA, *BB;
-  
-  AA = mxCalloc(n,sizeof(double));
-  BB = mxCalloc(k,sizeof(double));
-  
-  for (i1=0; i1<n*k; i1++) {
-    X[i1] = 0;
-  }
-  
-  for (i1=0; i1<n; ++i1) {
-    for (i2=0; i2<m/2; ++i2) {
-      AA[i1] += A[i1+2*i2*n]*A[i1+(2*i2+1)*n];
-    }
-  }
-
-  for (i2=0; i2<k; ++i2) {
-    for (i1=0; i1<m/2; ++i1) {
-      BB[i2] += B[2*i1+i2*m]*B[2*i1+1+i2*m];
-    }
-  }
-
-  for (i2=0; i2<k; ++i2) {
-    for (i3=0; i3<m/2; ++i3) {
-      for (i1=0; i1<n; ++i1) {
-        X[i1+i2*n] += (A[i1+(2*i3)*n]+B[2*i3+1+i2*m])*(A[i1+(2*i3+1)*n]+B[2*i3+i2*m]);
-      }
-    }
-  }
-  
-  if (m%2) {
-    for (i2=0; i2<k; ++i2) {
-      for (i1=0; i1<n; ++i1) {
-        X[i1+i2*n] += A[i1+(m-1)*n]*B[m-1+i2*m];
-      }
-    }
-  }
-  
-  for (i2=0; i2<k; ++i2) {
-    for (i1=0; i1<n; ++i1) {
-      X[i1+i2*n] -= (AA[i1] + BB[i2]);
-      X[i1+i2*n] *= alpha;
-    }
-  }
-  
-  mxFree(AA);
-  mxFree(BB);
-}
-*/
-
-
-
-
--- a/util/ksvd utils/ompbox utils/myblas.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/**************************************************************************
- *
- * File name: myblas.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Version: 1.1
- * Last updated: 17.8.2009
- *
- * A collection of basic linear algebra functions, in the spirit of the
- * BLAS/LAPACK libraries.
- *
- *************************************************************************/
-
-
-
-#ifndef __MY_BLAS_H__
-#define __MY_BLAS_H__
-
-
-#include "mex.h"
-#include <math.h>
-
-
-
-/**************************************************************************
- * Squared value.
- **************************************************************************/
-#define SQR(X) ((X)*(X))
-
-
-
-/**************************************************************************
- * Matrix-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A*x
- *
- * Parameters:
- *   A - matrix of size n X m
- *   x - vector of length m
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Matrix-transpose-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A'*x
- *
- * Parameters:
- *   A - matrix of size n X m
- *   x - vector of length n
- *   y - output vector of length m
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Sparse-matrix-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A*x
- *
- * where A is a sparse matrix.
- *
- * Parameters:
- *   pr,ir,jc - sparse representation of the matrix A, of size n x m
- *   x - vector of length m
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Sparse-matrix-transpose-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A'*x
- *
- * where A is a sparse matrix.
- *
- * Parameters:
- *   pr,ir,jc - sparse representation of the matrix A, of size n x m
- *   x - vector of length m
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Matrix-sparse-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A*x
- *
- * where A is a matrix and x is a sparse vector.
- *
- * Parameters:
- *   A - matrix of size n X m
- *   pr,ir,jc - sparse representation of the vector x, of length m
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Matrix-transpose-sparse-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A'*x
- *
- * where A is a matrix and x is a sparse vector.
- *
- * Parameters:
- *   A - matrix of size n X m
- *   pr,ir,jc - sparse representation of the vector x, of length n
- *   y - output vector of length m
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Sparse-matrix-sparse-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A*x
- *
- * where A is a sparse matrix and x is a sparse vector.
- *
- * Parameters:
- *   pr,ir,jc - sparse representation of the matrix A, of size n x m
- *   prx,irx,jcx - sparse representation of the vector x (of length m)
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Sparse-matrix-transpose-sparse-vector multiplication. 
- *
- * Computes an operation of the form:
- *
- *   y := alpha*A'*x
- *
- * where A is a sparse matrix and x is a sparse vector.
- *
- * Importnant note: this function is provided for completeness, but is NOT efficient.
- * If possible, convert x to non-sparse representation and use matT_vec_sp instead.
- *
- * Parameters:
- *   pr,ir,jc - sparse representation of the matrix A, of size n x m
- *   prx,irx,jcx - sparse representation of the vector x (of length n)
- *   y - output vector of length n
- *   alpha - real constant
- *   n, m - dimensions of A
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Matrix-matrix multiplication. 
- *
- * Computes an operation of the form:
- *
- *   X := alpha*A*B
- *
- * Parameters:
- *   A - matrix of size n X m
- *   B - matrix of size m X k
- *   X - output matrix of size n X k
- *   alpha - real constant
- *   n, m, k - dimensions of A, B
- *
- * Note: This function re-writes the contents of X.
- *
- **************************************************************************/
-void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k);
-
-
-
-/**************************************************************************
- * Matrix-transpose-matrix multiplication. 
- *
- * Computes an operation of the form:
- *
- *   X := alpha*A*B
- *
- * Parameters:
- *   A - matrix of size n X m
- *   B - matrix of size m X k
- *   X - output matrix of size n X k
- *   alpha - real constant
- *   n, m, k - dimensions of A, B
- *
- * Note: This function re-writes the contents of X.
- *
- **************************************************************************/
-void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k);
-
-
-
-/**************************************************************************
- * Tensor-matrix multiplication. 
- *
- * This function accepts a 3-D tensor A of size n X m X k
- * and a 2-D matrix B of size l X k.
- * The function computes the 3-D tensor X of size n X m X l, where
- *
- *   X(i,j,:) = B*A(i,j,:)
- *
- * for all i,j.
- *
- * Parameters:
- *   A - tensor of size n X m X k
- *   B - matrix of size l X k
- *   X - output tensor of size n X m X l
- *   alpha - real constant
- *   n, m, k, l - dimensions of A, B
- *
- * Note: This function re-writes the contents of X.
- *
- **************************************************************************/
-void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l);
-
-
-
-/**************************************************************************
- * Tensor-matrix-transpose multiplication. 
- *
- * This function accepts a 3-D tensor A of size n X m X k
- * and a 2-D matrix B of size k X l.
- * The function computes the 3-D tensor X of size n X m X l, where
- *
- *   X(i,j,:) = B'*A(i,j,:)
- *
- * for all i,j.
- *
- * Parameters:
- *   A - tensor of size n X m X k
- *   B - matrix of size k X l
- *   X - output tensor of size n X m X l
- *   alpha - real constant
- *   n, m, k, l - dimensions of A, B
- *
- * Note: This function re-writes the contents of X.
- *
- **************************************************************************/
-void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l);
-
-
-
-/**************************************************************************
- * Vector-vector sum.
- *
- * Computes an operation of the form:
- *
- *   y := alpha*x + y
- *
- * Parameters:
- *   x - vector of length n
- *   y - output vector of length n
- *   alpha - real constant
- *   n - length of x,y
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-void vec_sum(double alpha, double x[], double y[], mwSize n);
-
-/**************************************************************************
- * Vector-vector scalar multiply.
- *
- * Computes an operation of the form:
- *
- *   y := alpha* x.*y
- *
- * Parameters:
- *   x - vector of length n
- *   y - output vector of length n
- *   alpha - real constant
- *   n - length of x,y
- *
- * Note: This function re-writes the contents of y.
- *
- **************************************************************************/
-
-
-void vec_smult(double alpha, double x[], double y[], mwSize n);
-
-
-/**************************************************************************
- * Triangular back substitution.
- *
- * Solve the set of linear equations
- *
- *   T*x = b
- *
- * where T is lower or upper triangular.
- *
- * Parameters:
- *   ul - 'U' for upper triangular, 'L' for lower triangular
- *   A  - matrix of size n x m containing T
- *   b  - vector of length k
- *   x  - output vector of length k
- *   n  - size of first dimension of A
- *   k  - the size of the equation set, k<=n,m
- *
- * Note:
- *   The matrix A can be of any size n X m, as long as n,m >= k. 
- *   Only the lower/upper triangle of the submatrix A(1:k,1:k) defines the
- *   matrix T (depending on the parameter ul).
- *
- **************************************************************************/
-void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k);
-
-
-
-/**************************************************************************
- * Solve a set of equations using a Cholesky decomposition.
- *
- * Solve the set of linear equations
- *
- *   M*x = b
- *
- * where M is positive definite with a known Cholesky decomposition:
- * either M=L*L' (L lower triangular) or M=U'*U (U upper triangular).
- *
- * Parameters:
- *   ul - 'U' for upper triangular, 'L' for lower triangular decomposition
- *   A  - matrix of size n x m with the Cholesky decomposition of M
- *   b  - vector of length k
- *   x  - output vector of length k
- *   n  - size of first dimension of A
- *   k  - the size of the equation set, k<=n,m
- *
- * Note:
- *   The matrix A can be of any size n X m, as long as n,m >= k. 
- *   Only the lower/upper triangle of the submatrix A(1:k,1:k) is used as
- *   the Cholesky decomposition of M (depending on the parameter ul).
- *
- **************************************************************************/
-void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k);
-
-
-
-/**************************************************************************
- * Maximum absolute value.
- *
- * Returns the index of the coefficient with maximal absolute value in a vector.
- *
- * Parameters:
- *   x - vector of length n
- *   n - length of x
- *
- **************************************************************************/
-mwIndex maxabs(double x[], mwSize n);
-
-
-
-/**************************************************************************
- * Maximum vector element.
- *
- * Returns the index of the maximal coefficient in a vector.
- *
- * Parameters:
- *   x - vector of length n
- *   n - length of x
- *
- **************************************************************************/
-mwIndex maxpos(double x[], mwSize n);
-
-
-
-/**************************************************************************
- * Vector-vector dot product.
- *
- * Computes an operation of the form:
- *
- *   c = a'*b
- *
- * Parameters:
- *   a, b - vectors of length n
- *   n - length of a,b
- *
- * Returns: The dot product c.
- *
- **************************************************************************/
-double dotprod(double a[], double b[], mwSize n);
-
-
-
-/**************************************************************************
- * Indexed vector assignment.
- *
- * Perform a permutation assignment of the form
- *
- *   y = x(ind)
- *
- * where ind is an array of indices to x.
- *
- * Parameters:
- *   y - output vector of length k
- *   x - input vector of arbitrary length
- *   ind - array of indices into x (indices begin at 0)
- *   k - length of the array ind
- *
- **************************************************************************/
-void vec_assign(double y[], double x[], mwIndex ind[], mwSize k);
-
-
-
-/**************************************************************************
- * Matrix transpose.
- *
- * Computes Y := X'
- *
- * Parameters:
- *   X - input matrix of size n X m
- *   Y - output matrix of size m X n
- *   n, m - dimensions of X
- *
- **************************************************************************/
-void transpose(double X[], double Y[], mwSize n, mwSize m);
-
-
-
-/**************************************************************************
- * Print a matrix.
- *
- * Parameters:
- *   A - matrix of size n X m
- *   n, m - dimensions of A
- *   matname - name of matrix to display
- *
- **************************************************************************/
-void printmat(double A[], int n, int m, char* matname);
-
-
-
-/**************************************************************************
- * Print a sparse matrix.
- *
- * Parameters:
- *   A - sparse matrix of type double
- *   matname - name of matrix to display
- *
- **************************************************************************/
-void printspmat(mxArray *A, char* matname);
-
-
-#endif
-
--- a/util/ksvd utils/ompbox utils/omp2Gabor.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-function gamma = omp2(varargin)
-%OMP2 Error-constrained Orthogonal Matching Pursuit.
-%  GAMMA = OMP2(D,X,G,EPSILON) solves the optimization problem
-%
-%       min  |GAMMA|_0     s.t.  |X - D*GAMMA|_2 <= EPSILON
-%      gamma
-%
-%  for each of the signals in X, using Batch Orthogonal Matching Pursuit.
-%  Here, D is a dictionary with normalized columns, X is a matrix
-%  containing column signals, EPSILON is the error target for each signal,
-%  and G is the Gramm matrix D'*D. The output GAMMA is a matrix containing
-%  the sparse representations as its columns. 
-%
-%  GAMMA = OMP2(D,X,[],EPSILON) performs the same operation, but without
-%  the matrix G, using OMP-Cholesky. This call produces the same output as
-%  Batch-OMP, but is significantly slower. Using this syntax is only
-%  recommended when available memory is too small to store G.
-%
-%  GAMMA = OMP2(DtX,XtX,G,EPSILON) is the fastest implementation of OMP2,
-%  but also requires the most memory. Here, DtX stores the projections
-%  D'*X, and XtX is a row vector containing the squared norms of the
-%  signals, sum(X.*X). In this case Batch-OMP is used, but without having
-%  to compute D'*X and XtX in advance, which slightly improves runtime.
-%  Note that in general, the call
-%
-%    GAMMA = OMP2(D'*X, sum(X.*X), G, EPSILON);
-%
-%  will be faster than the call
-%
-%    GAMMA = OMP2(D,X,G,EPSILON);
-%
-%  due to optimized matrix multiplications in Matlab. However, when the
-%  entire matrix D'*X cannot be stored in memory, one of the other two
-%  versions can be used. Both compute D'*X for just one signal at a time,
-%  and thus require much less memory.
-%
-%  GAMMA = OMP2(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional
-%  parameters for OMP2. Available parameters are:
-%
-%    'gammamode' - Specifies the representation mode for GAMMA. Can be
-%                  either 'full' or 'sparse', corresponding to a full or
-%                  sparse matrix, respectively. By default, GAMMA is
-%                  returned as a sparse matrix.
-%    'maxatoms' -  Limits the number of atoms in the representation of each
-%                  signal. If specified, the number of atoms in each
-%                  representation does not exceed this number, even if the
-%                  error target is not met. Specifying maxatoms<0 implies
-%                  no limit (default).
-%    'messages'  - Specifies whether progress messages should be displayed.
-%                  When positive, this is the number of seconds between
-%                  status prints. When negative, indicates that no messages
-%                  should be displayed (this is the default).
-%    'checkdict' - Specifies whether dictionary normalization should be
-%                  verified. When set to 'on' (default) the dictionary
-%                  atoms are verified to be of unit L2-norm. Setting this
-%                  parameter to 'off' disables verification and accelerates
-%                  function performance. Note that an unnormalized
-%                  dictionary will produce invalid results.
-%    'profile'   - Can be either 'on' or 'off'. When 'on', profiling
-%                  information is displayed at the end of the funciton
-%                  execution.
-%
-%
-%  Summary of OMP2 versions:
-%
-%    version                 |   speed     |   memory
-%  -------------------------------------------------------------
-%   OMP2(DtX,XtX,G,EPSILON)  |  very fast  |  very large
-%   OMP2(D,X,G,EPSILON)      |  fast       |  moderate
-%   OMP2(D,X,[],EPSILON)     |  very slow  |  small
-%  -------------------------------------------------------------
-%
-%
-%  References:
-%  [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation
-%      of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit",
-%      Technical Report - CS, Technion, April 2008.
-%
-%  See also OMP.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
-
-
-% default options
-
-sparse_gamma = 1;
-msgdelta = -1;
-maxatoms = -1;
-checkdict = 1;
-profile = 0;
-
-
-% determine number of parameters
-
-paramnum = 1;
-while (paramnum<=nargin && ~ischar(varargin{paramnum}))
-  paramnum = paramnum+1;
-end
-paramnum = paramnum-1;
-
-
-% parse options
-
-for i = paramnum+1:2:length(varargin)
-  paramname = varargin{i};
-  paramval = varargin{i+1};
-
-  switch lower(paramname)
-
-    case 'gammamode'
-      if (strcmpi(paramval,'sparse'))
-        sparse_gamma = 1;
-      elseif (strcmpi(paramval,'full'))
-        sparse_gamma = 0;
-      else
-        error('Invalid GAMMA mode');
-      end
-      
-    case 'maxatoms'
-      maxatoms = paramval;
-      
-    case 'messages'
-      msgdelta = paramval;
-
-    case 'checkdict'
-      if (strcmpi(paramval,'on'))
-        checkdict = 1;
-      elseif (strcmpi(paramval,'off'))
-        checkdict = 0;
-      else
-        error('Invalid checkdict option');
-      end
-
-    case 'profile'
-      if (strcmpi(paramval,'on'))
-        profile = 1;
-      elseif (strcmpi(paramval,'off'))
-        profile = 0;
-      else
-        error('Invalid profile mode');
-      end
-
-    otherwise
-      error(['Unknown option: ' paramname]);
-  end
-  
-end
-
-
-% determine call type
-
-if (paramnum==4)
-  
-  n1 = size(varargin{1},1);
-  n2 = size(varargin{2},1);
-  n3 = size(varargin{3},1);
-  
-  if ( (n1>1 && n2==1) || (n1==1 && n2==1 && n3==1) )  %  DtX,XtX,G,EPSILON
-    
-    DtX = varargin{1};
-    XtX = varargin{2};
-    G = varargin{3};
-    epsilon = varargin{4};
-    D = [];
-    X = [];
-    
-  else  % D,X,G,EPSILON
-    
-    D = varargin{1};
-    X = varargin{2};
-    G = varargin{3};
-    epsilon = varargin{4};
-    DtX = [];
-    XtX = [];
-    
-  end
-  
-else
-  error('Invalid number of parameters');
-end
-
-G=[];
-
-% verify dictionary normalization
-
-if (checkdict)
-  if (isempty(G))
-    atomnorms = sum(D.*D);
-  else
-    atomnorms = diag(G);
-  end
-  if (any(abs(atomnorms-1) > 1e-2))
-    error('Dictionary columns must be normalized to unit length');
-  end
-end
-
-
-% omp
-
-gamma = omp2mexGabor(D,X,DtX,XtX,G,epsilon,sparse_gamma,msgdelta,maxatoms,profile);
--- a/util/ksvd utils/ompbox utils/omp2mex.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/**************************************************************************
- *
- * File name: omp2mex.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- *************************************************************************/
-
-#include "ompcore.h"
-#include "omputils.h"
-#include "mexutils.h"
-
-
-/* Input Arguments */
-
-#define	IN_D	        prhs[0]
-#define IN_X          prhs[1]
-#define IN_DtX        prhs[2]
-#define IN_XtX        prhs[3]
-#define IN_G          prhs[4]
-#define IN_EPS        prhs[5]
-#define IN_SPARSE_G   prhs[6]
-#define IN_MSGDELTA   prhs[7]
-#define IN_MAXATOMS   prhs[8]
-#define IN_PROFILE    prhs[9]
-
-
-/* Output Arguments */
-
-#define	GAMMA_OUT     plhs[0]
-
-
-/***************************************************************************************/
-
-
-void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
-
-{
-  double *D, *x, *DtX, *XtX, *G, eps, msgdelta;
-  int gmode, maxatoms, profile;
-  mwSize m, n, L;    /* D is n x m , X is n x L, DtX is m x L */
-
-  
-  /* check parameters */
-  
-  checkmatrix(IN_D, "OMP2", "D");
-  checkmatrix(IN_X, "OMP2", "X");
-  checkmatrix(IN_DtX, "OMP2", "DtX");
-  checkmatrix(IN_XtX, "OMP2", "XtX");
-  checkmatrix(IN_G, "OMP2", "G");
-  
-  checkscalar(IN_EPS, "OMP2", "EPSILON");
-  checkscalar(IN_SPARSE_G, "OMP2", "sparse_g");
-  checkscalar(IN_MSGDELTA, "OMP2", "msgdelta");
-  checkscalar(IN_MAXATOMS, "OMP2", "maxatoms");
-  checkscalar(IN_PROFILE, "OMP2", "profile");
-  
-  
-  /* get parameters */
-  
-  x = D = DtX = XtX = G = 0;
-  
-  if (!mxIsEmpty(IN_D))
-    D = mxGetPr(IN_D);
-  
-  if (!mxIsEmpty(IN_X))
-    x = mxGetPr(IN_X);
-  
-  if (!mxIsEmpty(IN_DtX))
-    DtX = mxGetPr(IN_DtX);
-  
-  if (!mxIsEmpty(IN_XtX))
-    XtX = mxGetPr(IN_XtX);
-  
-  if (!mxIsEmpty(IN_G))
-    G = mxGetPr(IN_G);
-  
-  eps = mxGetScalar(IN_EPS);
-  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
-    gmode = SPARSE_GAMMA;
-  }
-  else {
-    gmode = FULL_GAMMA;
-  }
-  msgdelta = mxGetScalar(IN_MSGDELTA);
-  if (mxGetScalar(IN_MAXATOMS) < -1e-5) {
-    maxatoms = -1;
-  }
-  else {
-    maxatoms = (int)(mxGetScalar(IN_MAXATOMS)+1e-2);
-  }
-  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
-  
-  
-  /* check sizes */
-  
-  if (D && x) {
-    n = mxGetM(IN_D);
-    m = mxGetN(IN_D);
-    L = mxGetN(IN_X);
-    
-    if (mxGetM(IN_X) != n) {
-      mexErrMsgTxt("D and X have incompatible sizes.");
-    }
-    
-    if (G) {
-      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-        mexErrMsgTxt("G must be a square matrix.");
-      }
-      if (mxGetN(IN_G) != m) {
-        mexErrMsgTxt("D and G have incompatible sizes.");
-      }
-    }
-  }
-  
-  else if (DtX && XtX) {
-    m = mxGetM(IN_DtX);
-    L = mxGetN(IN_DtX);
-    
-    /* set n to an arbitrary value that is at least the max possible number of selected atoms */
-    
-    if (maxatoms>0) {
-      n = maxatoms;
-    }
-    else {
-      n = m;
-    }
-    
-    if ( !(mxGetM(IN_XtX)==L && mxGetN(IN_XtX)==1) && !(mxGetM(IN_XtX)==1 && mxGetN(IN_XtX)==L) ) {
-      mexErrMsgTxt("DtX and XtX have incompatible sizes.");
-    }
-    
-    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-      mexErrMsgTxt("G must be a square matrix.");
-    }
-    if (mxGetN(IN_G) != m) {
-      mexErrMsgTxt("DtX and G have incompatible sizes.");
-    }
-  }
-  
-  else {
-    mexErrMsgTxt("Either D and X, or DtX and XtX, must be specified.");
-  }
-  
-  
-  /* Do OMP! */
-  
-  GAMMA_OUT = ompcore(D, x, DtX, XtX, G, n, m, L, maxatoms, eps, gmode, profile, msgdelta, 1);
-  
-  return;
-}
--- a/util/ksvd utils/ompbox utils/omp2mex.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-%This is the Matlab interface to the OMP2 MEX implementation.
-%The function is not for independent use, only through omp2.m.
-
-
-%OMP2MEX Matlab interface to the OMP2 MEX implementation.
-%  GAMMA = OMP2MEX(D,X,DtX,XtX,G,EPSILON,SPARSE_G,MSGDELTA,MAXATOMS,PROFILE)
-%  invokes the OMP2 MEX function according to the specified parameters. Not
-%  all the parameters are required. Those among D, X, DtX, XtX and G which
-%  are not specified should be passed as [].
-%
-%  EPSILON - the target error.
-%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
-%  MSGDELTA - the delay in secs between messages. Zero means no messages.
-%  MAXATOMS - the max number of atoms per signal, negative for no max.
-%  PROFILE - nonzero means that profiling information should be printed.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
--- a/util/ksvd utils/ompbox utils/omp2mexGabor.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/**************************************************************************
- *
- * File name: omp2mex.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- *************************************************************************/
-
-#include "ompcoreGabor.h"
-#include "omputils.h"
-#include "mexutils.h"
-
-
-/* Input Arguments */
-
-#define	IN_D	        prhs[0]
-#define IN_X          prhs[1]
-#define IN_DtX        prhs[2]
-#define IN_XtX        prhs[3]
-#define IN_G          prhs[4]
-#define IN_EPS        prhs[5]
-#define IN_SPARSE_G   prhs[6]
-#define IN_MSGDELTA   prhs[7]
-#define IN_MAXATOMS   prhs[8]
-#define IN_PROFILE    prhs[9]
-
-
-/* Output Arguments */
-
-#define	GAMMA_OUT     plhs[0]
-
-
-/***************************************************************************************/
-
-
-void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
-
-{
-  double *D, *x, *DtX, *XtX, *G, eps, msgdelta;
-  int gmode, maxatoms, profile;
-  mwSize m, n, L;    /* D is n x m , X is n x L, DtX is m x L */
-
-  
-  /* check parameters */
-  
-  checkmatrix(IN_D, "OMP2", "D");
-  checkmatrix(IN_X, "OMP2", "X");
-  checkmatrix(IN_DtX, "OMP2", "DtX");
-  checkmatrix(IN_XtX, "OMP2", "XtX");
-  checkmatrix(IN_G, "OMP2", "G");
-  
-  checkscalar(IN_EPS, "OMP2", "EPSILON");
-  checkscalar(IN_SPARSE_G, "OMP2", "sparse_g");
-  checkscalar(IN_MSGDELTA, "OMP2", "msgdelta");
-  checkscalar(IN_MAXATOMS, "OMP2", "maxatoms");
-  checkscalar(IN_PROFILE, "OMP2", "profile");
-  
-  
-  /* get parameters */
-  
-  x = D = DtX = XtX = G = 0;
-  
-  if (!mxIsEmpty(IN_D))
-    D = mxGetPr(IN_D);
-  
-  if (!mxIsEmpty(IN_X))
-    x = mxGetPr(IN_X);
-  
-  if (!mxIsEmpty(IN_DtX))
-    DtX = mxGetPr(IN_DtX);
-  
-  if (!mxIsEmpty(IN_XtX))
-    XtX = mxGetPr(IN_XtX);
-  
-  if (!mxIsEmpty(IN_G))
-    G = mxGetPr(IN_G);
-  
-  eps = mxGetScalar(IN_EPS);
-  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
-    gmode = SPARSE_GAMMA;
-  }
-  else {
-    gmode = FULL_GAMMA;
-  }
-  msgdelta = mxGetScalar(IN_MSGDELTA);
-  if (mxGetScalar(IN_MAXATOMS) < -1e-5) {
-    maxatoms = -1;
-  }
-  else {
-    maxatoms = (int)(mxGetScalar(IN_MAXATOMS)+1e-2);
-  }
-  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
-  
-  
-  /* check sizes */
-  
-  if (D && x) {
-    n = mxGetM(IN_D);
-    m = mxGetN(IN_D);
-    L = mxGetN(IN_X);
-    
-    if (mxGetM(IN_X) != n) {
-      mexErrMsgTxt("D and X have incompatible sizes.");
-    }
-    
-    if (G) {
-      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-        mexErrMsgTxt("G must be a square matrix.");
-      }
-      if (mxGetN(IN_G) != m) {
-        mexErrMsgTxt("D and G have incompatible sizes.");
-      }
-    }
-  }
-  
-  else if (DtX && XtX) {
-    m = mxGetM(IN_DtX);
-    L = mxGetN(IN_DtX);
-    
-    /* set n to an arbitrary value that is at least the max possible number of selected atoms */
-    
-    if (maxatoms>0) {
-      n = maxatoms;
-    }
-    else {
-      n = m;
-    }
-    
-    if ( !(mxGetM(IN_XtX)==L && mxGetN(IN_XtX)==1) && !(mxGetM(IN_XtX)==1 && mxGetN(IN_XtX)==L) ) {
-      mexErrMsgTxt("DtX and XtX have incompatible sizes.");
-    }
-    
-    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-      mexErrMsgTxt("G must be a square matrix.");
-    }
-    if (mxGetN(IN_G) != m) {
-      mexErrMsgTxt("DtX and G have incompatible sizes.");
-    }
-  }
-  
-  else {
-    mexErrMsgTxt("Either D and X, or DtX and XtX, must be specified.");
-  }
-  
-  
-  /* Do OMP! */
-  
-  GAMMA_OUT = ompcoreGabor(D, x, DtX, XtX, G, n, m, L, maxatoms, eps, gmode, profile, msgdelta, 1);
-  
-  return;
-}
--- a/util/ksvd utils/ompbox utils/omp2mexGabor.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-%This is the Matlab interface to the OMP2 MEX implementation.
-%The function is not for independent use, only through omp2.m.
-
-
-%OMP2MEX Matlab interface to the OMP2 MEX implementation.
-%  GAMMA = OMP2MEXGABOR(D,X,DtX,XtX,G,EPSILON,SPARSE_G,MSGDELTA,MAXATOMS,PROFILE)
-%  invokes the OMP2 MEX function according to the specified parameters. Not
-%  all the parameters are required. Those among D, X, DtX, XtX and G which
-%  are not specified should be passed as [].
-%
-%  EPSILON - the target error.
-%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
-%  MSGDELTA - the delay in secs between messages. Zero means no messages.
-%  MAXATOMS - the max number of atoms per signal, negative for no max.
-%  PROFILE - nonzero means that profiling information should be printed.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
--- a/util/ksvd utils/ompbox utils/ompGabor.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-function gamma = omp(varargin)
-%OMP Sparsity-constrained Orthogonal Matching Pursuit.
-%  GAMMA = OMP(D,X,G,T) solves the optimization problem
-%
-%       min  |X - D*GAMMA|_2     s.t.  |GAMMA|_0 <= T
-%      gamma
-%
-%  for each of the signals in X, using Batch Orthogonal Matching Pursuit.
-%  Here, D is a dictionary with normalized columns, X is a matrix
-%  containing column signals, T is the # of non-zeros in each signal
-%  representation, and G is the Gramm matrix D'*D. The output GAMMA is a
-%  matrix containing the sparse representations as its columns. 
-%
-%  GAMMA = OMP(D,X,[],T) performs the same operation, but without the
-%  matrix G, using OMP-Cholesky. This call produces the same output as
-%  Batch-OMP, but is significantly slower. Using this syntax is only
-%  recommended when available memory is too small to store G.
-%
-%  GAMMA = OMP(DtX,G,T) is the fastest implementation of OMP, but also
-%  requires the most memory. Here, DtX stores the projections D'*X. In this
-%  case Batch-OMP is used, but without having to compute D'*X in advance,
-%  which slightly improves runtime. Note that in general, the call
-%
-%    GAMMA = OMP(D'*X,G,T);
-%
-%  will be faster than the call
-%
-%    GAMMA = OMP(D,X,G,T);
-%
-%  due to optimized matrix multiplications in Matlab. However, when the
-%  entire matrix D'*X cannot be stored in memory, one of the other two
-%  versions can be used. Both compute D'*X for just one signal at a time,
-%  and thus require much less memory.
-%
-%  GAMMA = OMP(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional
-%  parameters for OMP. Available parameters are:
-%
-%    'gammamode' - Specifies the representation mode for GAMMA. Can be
-%                  either 'full' or 'sparse', corresponding to a full or
-%                  sparse matrix, respectively. By default, GAMMA is
-%                  returned as a sparse matrix.
-%    'messages'  - Specifies whether progress messages should be displayed.
-%                  When positive, this is the number of seconds between
-%                  status prints. When negative, indicates that no messages
-%                  should be displayed (this is the default).
-%    'checkdict' - Specifies whether dictionary normalization should be
-%                  verified. When set to 'on' (default) the dictionary
-%                  atoms are verified to be of unit L2-norm. Setting this
-%                  parameter to 'off' disables verification and accelerates
-%                  function performance. Note that an unnormalized
-%                  dictionary will produce invalid results.
-%    'profile'   - Can be either 'on' or 'off'. When 'on', profiling
-%                  information is displayed at the end of the funciton
-%                  execution.
-%
-%
-%  Summary of OMP versions:
-%
-%    version      |   speed     |   memory
-%  --------------------------------------------------
-%   OMP(DtX,G,T)  |  very fast  |  very large
-%   OMP(D,X,G,T)  |  fast       |  moderate
-%   OMP(D,X,[],T) |  very slow  |  small
-%  --------------------------------------------------
-%
-%
-%  References:
-%  [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation
-%      of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit",
-%      Technical Report - CS, Technion, April 2008.
-%
-%  See also OMP2.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
-
-
-% default options
-
-sparse_gamma = 1;
-msgdelta = -1;
-checkdict = 1;
-profile = 0;
-
-
-% determine number of parameters
-
-paramnum = 1;
-while (paramnum<=nargin && ~ischar(varargin{paramnum}))
-  paramnum = paramnum+1;
-end
-paramnum = paramnum-1;
-
-
-% parse options
-
-for i = paramnum+1:2:length(varargin)
-  paramname = varargin{i};
-  paramval = varargin{i+1};
-
-  switch lower(paramname)
-
-    case 'gammamode'
-      if (strcmpi(paramval,'sparse'))
-        sparse_gamma = 1;
-      elseif (strcmpi(paramval,'full'))
-        sparse_gamma = 0;
-      else
-        error('Invalid GAMMA mode');
-      end
-      
-    case 'messages'
-      msgdelta = paramval;
-
-    case 'checkdict'
-      if (strcmpi(paramval,'on'))
-        checkdict = 1;
-      elseif (strcmpi(paramval,'off'))
-        checkdict = 0;
-      else
-        error('Invalid checkdict option');
-      end
-
-    case 'profile'
-      if (strcmpi(paramval,'on'))
-        profile = 1;
-      elseif (strcmpi(paramval,'off'))
-        profile = 0;
-      else
-        error('Invalid profile mode');
-      end
-
-    otherwise
-      error(['Unknown option: ' paramname]);
-  end
-  
-end
-
-
-% determine call type
-
-if (paramnum==3)
-  DtX = varargin{1};
-  G = varargin{2};
-  T = varargin{3};
-  D = [];
-  X = [];
-elseif (paramnum==4)
-  D = varargin{1};
-  X = varargin{2};
-  G = varargin{3};
-  T = varargin{4};
-  DtX = [];
-else
-  error('Invalid number of parameters');
-end
-
-
-% verify dictionary normalization
-
-if (checkdict)
-  if (isempty(G))
-    atomnorms = sum(D.*D);
-  else
-    atomnorms = diag(G);
-  end
-  if (any(abs(atomnorms-1) > 1e-2))
-    error('Dictionary columns must be normalized to unit length');
-  end
-end
-
-
-% omp
-
-gamma = ompmexGabor(D,X,DtX,G,T,sparse_gamma,msgdelta,profile);
--- a/util/ksvd utils/ompbox utils/ompcore.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,409 +0,0 @@
-/**************************************************************************
- *
- * File name: ompcore.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 25.8.2009
- *
- *************************************************************************/
-
-
-#include "ompcore.h"
-#include "omputils.h"
-#include "ompprof.h"
-#include "myblas.h"
-#include <math.h>
-#include <string.h>
-
-
-
-/******************************************************************************
- *                                                                            *
- *                           Batch-OMP Implementation                         *
- *                                                                            *
- ******************************************************************************/  
-
-mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
-                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp)
-{
-  
-  profdata pd;
-  mxArray *Gamma;
-  mwIndex i, j, signum, pos, *ind, *gammaIr, *gammaJc, gamma_count;
-  mwSize allocated_coefs, allocated_cols;
-  int DtX_specified, XtX_specified, batchomp, standardomp, *selected_atoms;
-  double *alpha, *r, *Lchol, *c, *Gsub, *Dsub, sum, *gammaPr, *tempvec1, *tempvec2; 
-  double eps2, resnorm, delta, deltaprev, secs_remain;
-  int mins_remain, hrs_remain;
-  clock_t lastprint_time, starttime;
- 
-  
-  
-  /*** status flags ***/
-  
-  DtX_specified = (DtX!=0);   /* indicates whether D'*x was provided */
-  XtX_specified = (XtX!=0);   /* indicates whether sum(x.*x) was provided */
-  
-  standardomp = (G==0);       /* batch-omp or standard omp are selected depending on availability of G */
-  batchomp = !standardomp;
-  
-  
-  
-  /*** allocate output matrix ***/
-  
-  
-  if (gamma_mode == FULL_GAMMA) {
-    
-    /* allocate full matrix of size m X L */
-    
-    Gamma = mxCreateDoubleMatrix(m, L, mxREAL);
-    gammaPr = mxGetPr(Gamma);
-    gammaIr = 0;
-    gammaJc = 0;
-  }
-  else {
-    
-    /* allocate sparse matrix with room for allocated_coefs nonzeros */
-    
-    /* for error-omp, begin with L*sqrt(n)/2 allocated nonzeros, otherwise allocate L*T nonzeros */
-    allocated_coefs = erroromp ? (mwSize)(ceil(L*sqrt((double)n)/2.0) + 1.01) : L*T;
-    Gamma = mxCreateSparse(m, L, allocated_coefs, mxREAL);
-    gammaPr = mxGetPr(Gamma);
-    gammaIr = mxGetIr(Gamma);
-    gammaJc = mxGetJc(Gamma);
-    gamma_count = 0;
-    gammaJc[0] = 0;
-  }
-  
-  
-  /*** helper arrays ***/
-  
-  alpha = (double*)mxMalloc(m*sizeof(double));        /* contains D'*residual */
-  ind = (mwIndex*)mxMalloc(n*sizeof(mwIndex));        /* indices of selected atoms */
-  selected_atoms = (int*)mxMalloc(m*sizeof(int));     /* binary array with 1's for selected atoms */
-  c = (double*)mxMalloc(n*sizeof(double));            /* orthogonal projection result */
-  
-  /* current number of columns in Dsub / Gsub / Lchol */
-  allocated_cols = erroromp ? (mwSize)(ceil(sqrt((double)n)/2.0) + 1.01) : T;
-  
-  /* Cholesky decomposition of D_I'*D_I */
-  Lchol = (double*)mxMalloc(n*allocated_cols*sizeof(double));
-
-  /* temporary vectors for various computations */
-  tempvec1 = (double*)mxMalloc(m*sizeof(double));
-  tempvec2 = (double*)mxMalloc(m*sizeof(double));
-  
-  if (batchomp) {
-    /* matrix containing G(:,ind) - the columns of G corresponding to the selected atoms, in order of selection */
-    Gsub = (double*)mxMalloc(m*allocated_cols*sizeof(double));
-  }
-  else {
-    /* matrix containing D(:,ind) - the selected atoms from D, in order of selection */
-    Dsub = (double*)mxMalloc(n*allocated_cols*sizeof(double));
-    
-    /* stores the residual */
-    r = (double*)mxMalloc(n*sizeof(double));        
-  }
-  
-  if (!DtX_specified) {
-    /* contains D'*x for the current signal */
-    DtX = (double*)mxMalloc(m*sizeof(double));  
-  }
-  
-  
-  
-  /*** initializations for error omp ***/
-  
-  if (erroromp) {
-    eps2 = eps*eps;        /* compute eps^2 */
-    if (T<0 || T>n) {      /* unspecified max atom num - set max atoms to n */
-      T = n;
-    }
-  }
-  
-  
-  
-  /*** initialize timers ***/
-  
-  initprofdata(&pd);             /* initialize profiling counters */
-  starttime = clock();           /* record starting time for eta computations */
-  lastprint_time = starttime;    /* time of last status display */
-  
-  
-  
-  /**********************   perform omp for each signal   **********************/
-  
-  
-  
-  for (signum=0; signum<L; ++signum) {
-    
-    
-    /* initialize residual norm and deltaprev for error-omp */
-    
-    if (erroromp) {
-      if (XtX_specified) {
-        resnorm = XtX[signum];
-      }
-      else {
-        resnorm = dotprod(x+n*signum, x+n*signum, n);
-        addproftime(&pd, XtX_TIME);
-      }
-      deltaprev = 0;     /* delta tracks the value of gamma'*G*gamma */
-    }
-    else {
-      /* ignore residual norm stopping criterion */
-      eps2 = 0;
-      resnorm = 1;
-    }
-    
-    
-    if (resnorm>eps2 && T>0) {
-      
-      /* compute DtX */
-      
-      if (!DtX_specified) {
-        matT_vec(1, D, x+n*signum, DtX, n, m);
-        addproftime(&pd, DtX_TIME);
-      }
-      
-      
-      /* initialize alpha := DtX */
-      
-      memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double));
-      
-      
-      /* mark all atoms as unselected */
-      
-      for (i=0; i<m; ++i) {
-        selected_atoms[i] = 0;
-      }
-      
-    }
-    
-
-    /* main loop */
-    
-    i=0;
-    while (resnorm>eps2 && i<T) {
-
-      /* index of next atom */
-      
-      pos = maxabs(alpha, m);
-      addproftime(&pd, MAXABS_TIME);
-      
-      
-      /* stop criterion: selected same atom twice, or inner product too small */
-      
-      if (selected_atoms[pos] || alpha[pos]*alpha[pos]<1e-14) {
-        break;
-      }
-      
-      
-      /* mark selected atom */
-      
-      ind[i] = pos;
-      selected_atoms[pos] = 1;
-      
-      
-      /* matrix reallocation */
-      
-      if (erroromp && i>=allocated_cols) {
-        
-        allocated_cols = (mwSize)(ceil(allocated_cols*MAT_INC_FACTOR) + 1.01);
-        
-        Lchol = (double*)mxRealloc(Lchol,n*allocated_cols*sizeof(double));
-        
-        batchomp ? (Gsub = (double*)mxRealloc(Gsub,m*allocated_cols*sizeof(double))) :
-                   (Dsub = (double*)mxRealloc(Dsub,n*allocated_cols*sizeof(double))) ;
-      }
-      
-      
-      /* append column to Gsub or Dsub */
-      
-      if (batchomp) {
-        memcpy(Gsub+i*m, G+pos*m, m*sizeof(double));
-      }
-      else {
-        memcpy(Dsub+i*n, D+pos*n, n*sizeof(double));
-      }
-      
-      
-      /*** Cholesky update ***/
-      
-      if (i==0) {
-        *Lchol = 1;
-      }
-      else {
-        
-        /* incremental Cholesky decomposition: compute next row of Lchol */
-        
-        if (standardomp) {
-          matT_vec(1, Dsub, D+n*pos, tempvec1, n, i);      /* compute tempvec1 := Dsub'*d where d is new atom */
-          addproftime(&pd, DtD_TIME);
-        }
-        else {
-          vec_assign(tempvec1, Gsub+i*m, ind, i);          /* extract tempvec1 := Gsub(ind,i) */
-        }
-        backsubst('L', Lchol, tempvec1, tempvec2, n, i);   /* compute tempvec2 = Lchol \ tempvec1 */
-        for (j=0; j<i; ++j) {                              /* write tempvec2 to end of Lchol */
-          Lchol[j*n+i] = tempvec2[j];
-        }
-        
-        /* compute Lchol(i,i) */
-        sum = 0;
-        for (j=0; j<i; ++j) {         /* compute sum of squares of last row without Lchol(i,i) */
-          sum += SQR(Lchol[j*n+i]);
-        }
-        if ( (1-sum) <= 1e-14 ) {     /* Lchol(i,i) is zero => selected atoms are dependent */
-          break;
-        }
-        Lchol[i*n+i] = sqrt(1-sum);
-      }
-      
-      addproftime(&pd, LCHOL_TIME);
-
-      i++;
-      
-      
-      /* perform orthogonal projection and compute sparse coefficients */
-      
-      vec_assign(tempvec1, DtX + m*signum*DtX_specified, ind, i);   /* extract tempvec1 = DtX(ind) */
-      cholsolve('L', Lchol, tempvec1, c, n, i);                     /* solve LL'c = tempvec1 for c */
-      addproftime(&pd, COMPCOEF_TIME);
-      
-
-      /* update alpha = D'*residual */
-      
-      if (standardomp) {
-        mat_vec(-1, Dsub, c, r, n, i);             /* compute r := -Dsub*c */
-        vec_sum(1, x+n*signum, r, n);              /* compute r := x+r */
-        
-        
-        /*memcpy(r, x+n*signum, n*sizeof(double));   /* assign r := x */
-        /*mat_vec1(-1, Dsub, c, 1, r, n, i);         /* compute r := r-Dsub*c */
-        
-        addproftime(&pd, COMPRES_TIME);
-        matT_vec(1, D, r, alpha, n, m);            /* compute alpha := D'*r */
-        addproftime(&pd, DtR_TIME);
-        
-        /* update residual norm */
-        if (erroromp) {
-          resnorm = dotprod(r, r, n);
-          addproftime(&pd, UPDATE_RESNORM_TIME);
-        }
-      }
-      else {
-        mat_vec(1, Gsub, c, tempvec1, m, i);                              /* compute tempvec1 := Gsub*c */
-        memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double));    /* set alpha = D'*x */
-        vec_sum(-1, tempvec1, alpha, m);                                  /* compute alpha := alpha - tempvec1 */
-        addproftime(&pd, UPDATE_DtR_TIME);
-        
-        /* update residual norm */
-        if (erroromp) {
-          vec_assign(tempvec2, tempvec1, ind, i);      /* assign tempvec2 := tempvec1(ind) */
-          delta = dotprod(c,tempvec2,i);               /* compute c'*tempvec2 */
-          resnorm = resnorm - delta + deltaprev;       /* residual norm update */
-          deltaprev = delta;
-          addproftime(&pd, UPDATE_RESNORM_TIME);
-        }
-      }
-    }
-    
-    
-    /*** generate output vector gamma ***/
-
-    if (gamma_mode == FULL_GAMMA) {    /* write the coefs in c to their correct positions in gamma */
-      for (j=0; j<i; ++j) {
-        gammaPr[m*signum + ind[j]] = c[j];
-      }
-    }
-    else {
-      /* sort the coefs by index before writing them to gamma */
-      quicksort(ind,c,i);
-      addproftime(&pd, INDEXSORT_TIME);
-      
-      /* gamma is full - reallocate */
-      if (gamma_count+i >= allocated_coefs) {
-        
-        while(gamma_count+i >= allocated_coefs) {
-          allocated_coefs = (mwSize)(ceil(GAMMA_INC_FACTOR*allocated_coefs) + 1.01);
-        }
-        
-        mxSetNzmax(Gamma, allocated_coefs);
-        mxSetPr(Gamma, mxRealloc(gammaPr, allocated_coefs*sizeof(double)));
-        mxSetIr(Gamma, mxRealloc(gammaIr, allocated_coefs*sizeof(mwIndex)));
-        
-        gammaPr = mxGetPr(Gamma);
-        gammaIr = mxGetIr(Gamma);
-      }
-      
-      /* append coefs to gamma and update the indices */
-      for (j=0; j<i; ++j) {
-        gammaPr[gamma_count] = c[j];
-        gammaIr[gamma_count] = ind[j];
-        gamma_count++;
-      }
-      gammaJc[signum+1] = gammaJc[signum] + i;
-    }
-    
-    
-    
-    /*** display status messages ***/
-    
-    if (msg_delta>0 && (clock()-lastprint_time)/(double)CLOCKS_PER_SEC >= msg_delta)
-    {
-      lastprint_time = clock();
-      
-      /* estimated remainig time */
-      secs2hms( ((L-signum-1)/(double)(signum+1)) * ((lastprint_time-starttime)/(double)CLOCKS_PER_SEC) ,
-        &hrs_remain, &mins_remain, &secs_remain);
-      
-      mexPrintf("omp: signal %d / %d, estimated remaining time: %02d:%02d:%05.2f\n",        
-        signum+1, L, hrs_remain, mins_remain, secs_remain);
-      mexEvalString("drawnow;");
-    }
-    
-  }
-  
-  /* end omp */
-  
-  
-  
-  /*** print final messages ***/
-  
-  if (msg_delta>0) {
-    mexPrintf("omp: signal %d / %d\n", signum, L);
-  }
-  
-  if (profile) {
-    printprofinfo(&pd, erroromp, batchomp, L);
-  }
-  
-  
-  
-  /* free memory */
-  
-  if (!DtX_specified) {
-    mxFree(DtX);
-  }
-  if (standardomp) {
-    mxFree(r);
-    mxFree(Dsub);
-  }
-  else {
-    mxFree(Gsub);
-  }  
-  mxFree(tempvec2);
-  mxFree(tempvec1);
-  mxFree(Lchol);
-  mxFree(c);
-  mxFree(selected_atoms);
-  mxFree(ind);
-  mxFree(alpha);
-  
-  return Gamma;
-}
--- a/util/ksvd utils/ompbox utils/ompcore.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**************************************************************************
- *
- * File name: ompcore.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- * Contains the core implementation of Batch-OMP / OMP-Cholesky.
- *
- *************************************************************************/
-
-
-#ifndef __OMP_CORE_H__
-#define __OMP_CORE_H__
-
-
-#include "mex.h"
-
-
-
-/**************************************************************************
- * Perform Batch-OMP or OMP-Cholesky on a specified set of signals, using
- * either a fixed number of atoms or an error bound.
- *
- * Parameters (not all required):
- *
- *   D - the dictionary, of size n X m
- *   x - the signals, of size n X L
- *   DtX - D'*x, of size m X L
- *   XtX - squared norms of the signals in x, sum(x.*x), of length L
- *   G - D'*D, of size m X m
- *   T - target sparsity, or maximal number of atoms for error-based OMP
- *   eps - target residual norm for error-based OMP
- *   gamma_mode - one of the constants FULL_GAMMA or SPARSE_GAMMA
- *   profile - if non-zero, profiling info is printed
- *   msg_delta - positive: the # of seconds between status prints, otherwise: nothing is printed
- *   erroromp - if nonzero indicates error-based OMP, otherwise fixed sparsity OMP
- *
- * Usage:
- *
- *   The function can be called using different parameters, and will have
- *   different complexity depending on the parameters specified. Arrays which
- *   are not specified should be passed as null (0). When G is specified, 
- *   Batch-OMP is performed. Otherwise, OMP-Cholesky is performed.
- *
- *   Fixed-sparsity usage:
- *   ---------------------
- *   Either DtX, or D and x, must be specified. Specifying DtX is more efficient.
- *   XtX does not need to be specified.
- *   When D and x are specified, G is not required. However, not providing G
- *   will significantly degrade efficiency.
- *   The number of atoms must be specified in T. The value of eps is ignored.
- *   Finally, set erroromp to 0.
- *
- *   Error-OMP usage:
- *   ----------------
- *   Either DtX and Xtx, or D and x, must be specified. Specifying DtX and XtX
- *   is more efficient.
- *   When D and x are specified, G is not required. However, not providing G
- *   will significantly degrade efficiency.
- *   The target error must be specified in eps. A hard limit on the number
- *   of atoms can also be specified via the parameter T. Otherwise, T should 
- *   be negative. Finally, set erroromp to nonzero.
- *
- *
- * Returns: 
- *   An mxArray containing the sparse representations of the signals in x
- *   (allocated using the appropriate mxCreateXXX() function).
- *   The array is either full or sparse, depending on gamma_mode.
- *
- **************************************************************************/
-mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
-                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp);
-
-
-#endif
--- a/util/ksvd utils/ompbox utils/ompcoreGabor.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,465 +0,0 @@
-/**************************************************************************
- * 
- * File name: ompcoreGabor.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 25.8.2009
- *
- * Modified by Ivan damnjanovic July 2011
- * Takes to atoms per iteration. It should be used for Gabor dictionaries
- * as specified in 
- * "Audio Inpainting" Amir Adler, Valentin Emiya, Maria G. Jafari, 
- * Michael Elad, Remi Gribonval and Mark D. Plumbley
- * Draft version: March 6, 2011
- *
- *************************************************************************/
-
-
-#include "ompcoreGabor.h"
-#include "omputils.h"
-#include "ompprof.h"
-#include "myblas.h"
-#include <math.h>
-#include <string.h>
-
-
-
-/******************************************************************************
- *                                                                            *
- *                           Batch-OMP Implementation                         *
- *                                                                            *
- ******************************************************************************/  
-
-mxArray* ompcoreGabor(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
-                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp)
-{
-  
-  profdata pd;
-  mxArray *Gamma;
-  mwIndex i, j, k, signum, pos, *ind, *gammaIr, *gammaJc, gamma_count;
-  mwSize allocated_coefs, allocated_cols;
-  int DtX_specified, XtX_specified, batchomp, standardomp, *selected_atoms;
-  double *proj, *proj1, *proj2, *D1, *D2, *D1D2, *n12, *alpha, *beta, *error;
-  double *r, *Lchol, *c, *Gsub, *Dsub, sum, *gammaPr, *tempvec1, *tempvec2; 
-  double eps2, resnorm, delta, deltaprev, secs_remain;
-  int mins_remain, hrs_remain;
-  clock_t lastprint_time, starttime;
- 
-  
-  
-  /*** status flags ***/
-  
-  DtX_specified = (DtX!=0);   /* indicates whether D'*x was provided */
-  XtX_specified = (XtX!=0);   /* indicates whether sum(x.*x) was provided */
-  
-  standardomp = 1;//(G==0);       /* batch-omp or standard omp are selected depending on availability of G */
-  batchomp = !standardomp;
-  
-  
-  
-  /*** allocate output matrix ***/
-  
-  
-  if (gamma_mode == FULL_GAMMA) {
-    
-    /* allocate full matrix of size m X L */
-    
-    Gamma = mxCreateDoubleMatrix(m, L, mxREAL);
-    gammaPr = mxGetPr(Gamma);
-    gammaIr = 0;
-    gammaJc = 0;
-  }
-  else {
-    
-    /* allocate sparse matrix with room for allocated_coefs nonzeros */
-    
-    /* for error-omp, begin with L*sqrt(n)/2 allocated nonzeros, otherwise allocate L*T nonzeros */
-    allocated_coefs = erroromp ? (mwSize)(ceil(L*sqrt((double)n)/2.0) + 1.01) : L*T;
-    Gamma = mxCreateSparse(m, L, allocated_coefs, mxREAL);
-    gammaPr = mxGetPr(Gamma);
-    gammaIr = mxGetIr(Gamma);
-    gammaJc = mxGetJc(Gamma);
-    gamma_count = 0;
-    gammaJc[0] = 0;
-  }
-  
-  
-  /*** helper arrays ***/
- /* Ivan Damnjanovic July 2011*/ 
-  proj = (double*)mxMalloc(m*sizeof(double));
-  proj1 = (double*)mxMalloc(m/2*sizeof(double));
-  proj2 = (double*)mxMalloc(m/2*sizeof(double)); 
-  D1 = (double*)mxMalloc(n*m/2*sizeof(double));
-  D2 = (double*)mxMalloc(n*m/2*sizeof(double));
-  memcpy(D1, D      , n*m/2*sizeof(double));
-  memcpy(D2, D+n*m/2, n*m/2*sizeof(double)); 
-  
-  D1D2 = (double*)mxMalloc(m/2*sizeof(double));
-  n12  = (double*)mxMalloc(m/2*sizeof(double));
-  
-  vec_smult(1,D2, D1, n*m/2);
-       
-  for (i=0; i<m/2; i++) {
-	D1D2[i]=0;
-	n12[i]=0;
-    for (j=0; j<n; j++) {
-          D1D2[i] += D1[i*n+j];
-    }
-    n12[i]=1/(1-D1D2[i]*D1D2[i]);
-  }
-  
-  memcpy(D1, D      , n*m/2*sizeof(double));
-  
-  alpha = (double*)mxMalloc(m/2*sizeof(double));  /* contains D'*residual */
-  beta  = (double*)mxMalloc(m/2*sizeof(double));  
-  error = (double*)mxMalloc(m/2*sizeof(double));
-  
-  ind = (mwIndex*)mxMalloc(m*sizeof(mwIndex));        /* indices of selected atoms */
-  selected_atoms = (int*)mxMalloc(m*sizeof(int));     /* binary array with 1's for selected atoms */
-  c = (double*)mxMalloc(n*sizeof(double));            /* orthogonal projection result */
-  
-  /* current number of columns in Dsub / Gsub / Lchol */
-  allocated_cols = erroromp ? (mwSize)(ceil(sqrt((double)n)/2.0) + 1.01) : T;
-  
-  /* Cholesky decomposition of D_I'*D_I */
-  Lchol = (double*)mxMalloc(n*allocated_cols*sizeof(double));
-
-  /* temporary vectors for various computations */
-  tempvec1 = (double*)mxMalloc(m*sizeof(double));
-  tempvec2 = (double*)mxMalloc(m*sizeof(double));
-  
-  if (batchomp) {
-    /* matrix containing G(:,ind) - the columns of G corresponding to the selected atoms, in order of selection */
-    Gsub = (double*)mxMalloc(m*allocated_cols*sizeof(double));
-  }
-  else {
-    /* matrix containing D(:,ind) - the selected atoms from D, in order of selection */
-    Dsub = (double*)mxMalloc(n*allocated_cols*sizeof(double));
-    
-    /* stores the residual */
-    r = (double*)mxMalloc(n*sizeof(double));        
-  }
-  
-  if (!DtX_specified) {
-    /* contains D'*x for the current signal */
-    DtX = (double*)mxMalloc(m*sizeof(double));  
-  }
-  
-  
-  
-  /*** initializations for error omp ***/
-  
-  if (erroromp) {
-    eps2 = eps*eps;        /* compute eps^2 */
-    if (T<0 || T>n) {      /* unspecified max atom num - set max atoms to n */
-      T = n;
-    }
-  }
-  
-  
-  
-  /*** initialize timers ***/
-  
-  initprofdata(&pd);             /* initialize profiling counters */
-  starttime = clock();           /* record starting time for eta computations */
-  lastprint_time = starttime;    /* time of last status display */
-  
-  
-  
-  /**********************   perform omp for each signal   **********************/
-  
-  
-  
-  for (signum=0; signum<L; ++signum) {
-    
-    
-    /* initialize residual norm and deltaprev for error-omp */
-    
-    if (erroromp) {
-      if (XtX_specified) {
-        resnorm = XtX[signum];
-      }
-      else {
-        resnorm = dotprod(x+n*signum, x+n*signum, n);
-        addproftime(&pd, XtX_TIME);
-      }
-      deltaprev = 0;     /* delta tracks the value of gamma'*G*gamma */
-    }
-    else {
-      /* ignore residual norm stopping criterion */
-      eps2 = 0;
-      resnorm = 1;
-    }
-    
-    
-    if (resnorm>eps2 && T>0) {
-      
-      /* compute DtX */
-      
-      if (!DtX_specified) {
-        matT_vec(1, D, x+n*signum, DtX, n, m);
-        addproftime(&pd, DtX_TIME);
-        memcpy(r , x+n*signum, n*sizeof(double));
-      }
-      
-      
-      /* initialize projections to D1 and D2 := DtX */
-      
-      memcpy(proj, DtX + m*signum*DtX_specified, m*sizeof(double));
-      
-      
-      /* mark all atoms as unselected */
-      
-      for (i=0; i<m; ++i) {
-        selected_atoms[i] = 0;
-      }
-      
-    }
-    
-
-    /* main loop */
-    
-    i=0;
-    while (resnorm>eps2 && i<T) {
-
-      /* index of next atom */
-      memcpy(proj1, proj, m/2*sizeof(double));
-      memcpy(proj2, proj + m/2, m/2*sizeof(double));
-      for (k=0; k<m/2; k++){
-        alpha[k] = (proj1[k] - D1D2[k]*proj2[k])*n12[k];
-        beta[k]  = (proj2[k] - D1D2[k]*proj1[k])*n12[k];
-      }
-      for (k=0; k<m/2; k++){
-		  error[k]=0;
-          for (j=0; j<n; j++){
-                  error[k]+= (abs(r[j])-D1[k*n+j]*alpha[k]-D2[k*n+j]*beta[k])*(abs(r[j])-D1[k*n+j]*alpha[k]-D2[k*n+j]*beta[k]);
-          }
-      }
-      pos = maxabs(error, m/2);
-      addproftime(&pd, MAXABS_TIME);
-      
-      
-      /* stop criterion: selected same atom twice, or inner product too small */
-      
-      if (selected_atoms[pos] || alpha[pos]*alpha[pos]<1e-14) {
-        break;
-      }
-      
-      for (k=0;k<2;k++){
-      /* mark selected atom */
-      
-      ind[i] = pos+k*m/2;
-      selected_atoms[pos+k*m/2] = 1;
-      
-      
-      /* matrix reallocation */
-      
-      if (erroromp && i>=allocated_cols) {
-        
-        allocated_cols = (mwSize)(ceil(allocated_cols*MAT_INC_FACTOR) + 1.01);
-        
-        Lchol = (double*)mxRealloc(Lchol,n*allocated_cols*sizeof(double));
-        
-        batchomp ? (Gsub = (double*)mxRealloc(Gsub,m*allocated_cols*sizeof(double))) :
-                   (Dsub = (double*)mxRealloc(Dsub,n*allocated_cols*sizeof(double))) ;
-      }
-      
-      
-      /* append column to Gsub or Dsub */
-      
-      if (batchomp) {
-        memcpy(Gsub+i*m, G+(pos+k*m/2)*m, m*sizeof(double));
-      }
-      else {
-        memcpy(Dsub+(i)*n, D+(pos+k*m/2)*n, n*sizeof(double));
-      }
-      
-      
-      /*** Cholesky update ***/
-      
-      if (i==0) {
-        *Lchol = 1;
-      }
-      else {
-        
-        /* incremental Cholesky decomposition: compute next row of Lchol */
-        
-        if (standardomp) {
-          matT_vec(1, Dsub, D+n*(pos+k*m/2), tempvec1, n, i);      /* compute tempvec1 := Dsub'*d where d is new atom */
-          addproftime(&pd, DtD_TIME);
-        }
-        else {
-          vec_assign(tempvec1, Gsub+i*m, ind, i);          /* extract tempvec1 := Gsub(ind,i) */
-        }
-        backsubst('L', Lchol, tempvec1, tempvec2, n, i);   /* compute tempvec2 = Lchol \ tempvec1 */
-        for (j=0; j<i; ++j) {                              /* write tempvec2 to end of Lchol */
-          Lchol[j*n+i] = tempvec2[j];
-        }
-        
-        /* compute Lchol(i,i) */
-        sum = 0;
-        for (j=0; j<i; ++j) {         /* compute sum of squares of last row without Lchol(i,i) */
-          sum += SQR(Lchol[j*n+i]);
-        }
-        if ( (1-sum) <= 1e-14 ) {     /* Lchol(i,i) is zero => selected atoms are dependent */
-          break;
-        }
-        Lchol[i*n+i] = sqrt(1-sum);
-      }
-      
-      addproftime(&pd, LCHOL_TIME);
-
-      i++;
-      
-      }
-      /* perform orthogonal projection and compute sparse coefficients */
-      
-      vec_assign(tempvec1, DtX + m*signum*DtX_specified, ind, i);   /* extract tempvec1 = DtX(ind) */
-      cholsolve('L', Lchol, tempvec1, c, n, i);                     /* solve LL'c = tempvec1 for c */
-      addproftime(&pd, COMPCOEF_TIME);
-      
-
-      /* update alpha = D'*residual */
-      
-      if (standardomp) {
-        mat_vec(-1, Dsub, c, r, n, i);             /* compute r := -Dsub*c */
-        vec_sum(1, x+n*signum, r, n);              /* compute r := x+r */
-        
-        
-        /*memcpy(r, x+n*signum, n*sizeof(double));   /* assign r := x */
-        /*mat_vec1(-1, Dsub, c, 1, r, n, i);         /* compute r := r-Dsub*c */
-        
-        addproftime(&pd, COMPRES_TIME);
-        matT_vec(1, D, r, proj, n, m);            /* compute proj := D'*r */
-        addproftime(&pd, DtR_TIME);
-        
-        /* update residual norm */
-        if (erroromp) {
-          resnorm = dotprod(r, r, n);
-          addproftime(&pd, UPDATE_RESNORM_TIME);
-        }
-      }
-      else {
-        mat_vec(1, Gsub, c, tempvec1, m, i);                              /* compute tempvec1 := Gsub*c */
-        memcpy(proj, DtX + m*signum*DtX_specified, m*sizeof(double));    /* set proj = D'*x */
-        vec_sum(-1, tempvec1, proj, m);                                  /* compute proj := proj - tempvec1 */
-        addproftime(&pd, UPDATE_DtR_TIME);
-        
-        /* update residual norm */
-        if (erroromp) {
-          vec_assign(tempvec2, tempvec1, ind, i);      /* assign tempvec2 := tempvec1(ind) */
-          delta = dotprod(c,tempvec2,i);               /* compute c'*tempvec2 */
-          resnorm = resnorm - delta + deltaprev;       /* residual norm update */
-          deltaprev = delta;
-          addproftime(&pd, UPDATE_RESNORM_TIME);
-        }
-      }
-    }
-    
-    
-    /*** generate output vector gamma ***/
-
-    if (gamma_mode == FULL_GAMMA) {    /* write the coefs in c to their correct positions in gamma */
-      for (j=0; j<i; ++j) {
-        gammaPr[m*signum + ind[j]] = c[j];
-      }
-    }
-    else {
-      /* sort the coefs by index before writing them to gamma */
-      quicksort(ind,c,i);
-      addproftime(&pd, INDEXSORT_TIME);
-      
-      /* gamma is full - reallocate */
-      if (gamma_count+i >= allocated_coefs) {
-        
-        while(gamma_count+i >= allocated_coefs) {
-          allocated_coefs = (mwSize)(ceil(GAMMA_INC_FACTOR*allocated_coefs) + 1.01);
-        }
-        
-        mxSetNzmax(Gamma, allocated_coefs);
-        mxSetPr(Gamma, mxRealloc(gammaPr, allocated_coefs*sizeof(double)));
-        mxSetIr(Gamma, mxRealloc(gammaIr, allocated_coefs*sizeof(mwIndex)));
-        
-        gammaPr = mxGetPr(Gamma);
-        gammaIr = mxGetIr(Gamma);
-      }
-      
-      /* append coefs to gamma and update the indices */
-      for (j=0; j<i; ++j) {
-        gammaPr[gamma_count] = c[j];
-        gammaIr[gamma_count] = ind[j];
-        gamma_count++;
-      }
-      gammaJc[signum+1] = gammaJc[signum] + i;
-    }
-    
-    
-    
-    /*** display status messages ***/
-    
-    if (msg_delta>0 && (clock()-lastprint_time)/(double)CLOCKS_PER_SEC >= msg_delta)
-    {
-      lastprint_time = clock();
-      
-      /* estimated remainig time */
-      secs2hms( ((L-signum-1)/(double)(signum+1)) * ((lastprint_time-starttime)/(double)CLOCKS_PER_SEC) ,
-        &hrs_remain, &mins_remain, &secs_remain);
-      
-      mexPrintf("omp: signal %d / %d, estimated remaining time: %02d:%02d:%05.2f\n",        
-        signum+1, L, hrs_remain, mins_remain, secs_remain);
-      mexEvalString("drawnow;");
-    }
-    
-  }
-  
-  /* end omp */
-  
-  
-  
-  /*** print final messages ***/
-  
-  if (msg_delta>0) {
-    mexPrintf("omp: signal %d / %d\n", signum, L);
-  }
-  
-  if (profile) {
-    printprofinfo(&pd, erroromp, batchomp, L);
-  }
-  
-  
-  
-  /* free memory */
-  
-  if (!DtX_specified) {
-    mxFree(DtX);
-  }
-  if (standardomp) {
-    mxFree(r);
-    mxFree(Dsub);
-  }
-  else {
-    mxFree(Gsub);
-  }  
-  mxFree(tempvec2);
-  mxFree(tempvec1);
-  mxFree(Lchol);
-  mxFree(c);
-  mxFree(selected_atoms);
-  mxFree(ind);
-  mxFree(proj);
-  mxFree(proj1);
-  mxFree(proj2);
-  mxFree(D1);
-  mxFree(D2);
-  mxFree(D1D2);
-  mxFree(n12);
-  mxFree(alpha);
-  mxFree(beta);
-  mxFree(error);
-  
-  return Gamma;
-}
--- a/util/ksvd utils/ompbox utils/ompcoreGabor.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**************************************************************************
- *
- * File name: ompcore.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- * Contains the core implementation of Batch-OMP / OMP-Cholesky.
- *
- *************************************************************************/
-
-
-#ifndef __OMP_CORE_H__
-#define __OMP_CORE_H__
-
-
-#include "mex.h"
-
-
-
-/**************************************************************************
- * Perform Batch-OMP or OMP-Cholesky on a specified set of signals, using
- * either a fixed number of atoms or an error bound.
- *
- * Parameters (not all required):
- *
- *   D - the dictionary, of size n X m
- *   x - the signals, of size n X L
- *   DtX - D'*x, of size m X L
- *   XtX - squared norms of the signals in x, sum(x.*x), of length L
- *   G - D'*D, of size m X m
- *   T - target sparsity, or maximal number of atoms for error-based OMP
- *   eps - target residual norm for error-based OMP
- *   gamma_mode - one of the constants FULL_GAMMA or SPARSE_GAMMA
- *   profile - if non-zero, profiling info is printed
- *   msg_delta - positive: the # of seconds between status prints, otherwise: nothing is printed
- *   erroromp - if nonzero indicates error-based OMP, otherwise fixed sparsity OMP
- *
- * Usage:
- *
- *   The function can be called using different parameters, and will have
- *   different complexity depending on the parameters specified. Arrays which
- *   are not specified should be passed as null (0). When G is specified, 
- *   Batch-OMP is performed. Otherwise, OMP-Cholesky is performed.
- *
- *   Fixed-sparsity usage:
- *   ---------------------
- *   Either DtX, or D and x, must be specified. Specifying DtX is more efficient.
- *   XtX does not need to be specified.
- *   When D and x are specified, G is not required. However, not providing G
- *   will significantly degrade efficiency.
- *   The number of atoms must be specified in T. The value of eps is ignored.
- *   Finally, set erroromp to 0.
- *
- *   Error-OMP usage:
- *   ----------------
- *   Either DtX and Xtx, or D and x, must be specified. Specifying DtX and XtX
- *   is more efficient.
- *   When D and x are specified, G is not required. However, not providing G
- *   will significantly degrade efficiency.
- *   The target error must be specified in eps. A hard limit on the number
- *   of atoms can also be specified via the parameter T. Otherwise, T should 
- *   be negative. Finally, set erroromp to nonzero.
- *
- *
- * Returns: 
- *   An mxArray containing the sparse representations of the signals in x
- *   (allocated using the appropriate mxCreateXXX() function).
- *   The array is either full or sparse, depending on gamma_mode.
- *
- **************************************************************************/
-mxArray* ompcoreGabor(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L,
-                 int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp);
-
-
-#endif
--- a/util/ksvd utils/ompbox utils/ompmex.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/**************************************************************************
- *
- * File name: ompmex.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- *************************************************************************/
-
-#include "ompcore.h"
-#include "omputils.h"
-#include "mexutils.h"
-
-
-/* Input Arguments */
-
-#define IN_D          prhs[0]
-#define IN_X          prhs[1]
-#define IN_DtX        prhs[2]
-#define IN_G          prhs[3]
-#define IN_T          prhs[4]
-#define IN_SPARSE_G   prhs[5]
-#define IN_MSGDELTA   prhs[6]
-#define IN_PROFILE    prhs[7]
-
-
-/* Output Arguments */
-
-#define	GAMMA_OUT     plhs[0]
-
-
-/***************************************************************************************/
-
-
-void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
-
-{
-  double *D, *x, *DtX, *G, msgdelta;
-  int gmode, profile, T;
-  mwSize m, n, L;   /* D is n x m , X is n x L, DtX is m x L */
-  
-  
-  /* check parameters */
-  
-  checkmatrix(IN_D, "OMP", "D");
-  checkmatrix(IN_X, "OMP", "X");
-  checkmatrix(IN_DtX, "OMP", "DtX");
-  checkmatrix(IN_G, "OMP", "G");
-  
-  checkscalar(IN_T, "OMP", "T");
-  checkscalar(IN_SPARSE_G, "OMP", "sparse_g");
-  checkscalar(IN_MSGDELTA, "OMP", "msgdelta");
-  checkscalar(IN_PROFILE, "OMP", "profile");
-
-  
-  /* get parameters */
-  
-  x = D = DtX = G = 0;
-  
-  if (!mxIsEmpty(IN_D))
-    D = mxGetPr(IN_D);
-  
-  if (!mxIsEmpty(IN_X))
-    x = mxGetPr(IN_X);
-  
-  if (!mxIsEmpty(IN_DtX))
-    DtX = mxGetPr(IN_DtX);
-  
-  if (!mxIsEmpty(IN_G))
-    G = mxGetPr(IN_G);
-  
-  T = (int)(mxGetScalar(IN_T)+1e-2);
-  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
-    gmode = SPARSE_GAMMA;
-  }
-  else {
-    gmode = FULL_GAMMA;
-  }
-  msgdelta = mxGetScalar(IN_MSGDELTA);
-  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
-  
-  
-  /* check sizes */
-  
-  if (D && x) {
-    n = mxGetM(IN_D);
-    m = mxGetN(IN_D);
-    L = mxGetN(IN_X);
-    
-    if (mxGetM(IN_X) != n) {
-      mexErrMsgTxt("D and X have incompatible sizes.");
-    }
-    
-    if (G) {
-      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-        mexErrMsgTxt("G must be a square matrix.");
-      }
-      if (mxGetN(IN_G) != m) {
-        mexErrMsgTxt("D and G have incompatible sizes.");
-      }
-    }
-  }
-  
-  else if (DtX) {
-    m = mxGetM(IN_DtX);
-    L = mxGetN(IN_DtX);
-    
-    n = T;  /* arbitrary - it is enough to assume signal length is T */
-    
-    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-      mexErrMsgTxt("G must be a square matrix.");
-    }
-    if (mxGetN(IN_G) != m) {
-      mexErrMsgTxt("DtX and G have incompatible sizes.");
-    }
-  }
-  
-  else {
-    mexErrMsgTxt("Either D and X, or DtX, must be specified.");
-  }
-  
-  
-  /* Do OMP! */
-  
-  GAMMA_OUT = ompcore(D, x, DtX, 0, G, n, m, L, T, 0, gmode, profile, msgdelta, 0);
-  
-  return;
-}
-
--- a/util/ksvd utils/ompbox utils/ompmex.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-%This is the Matlab interface to the OMP MEX implementation.
-%The function is not for independent use, only through omp.m.
-
-
-%OMPMEX Matlab interface to the OMP MEX implementation.
-%  GAMMA = OMPMEX(D,X,DtX,G,L,SPARSE_G,MSGDELTA,PROFILE) invokes the OMP
-%  MEX function according to the specified parameters. Not all the
-%  parameters are required. Those among D, X, DtX and G which are not
-%  specified should be passed as [].
-%
-%  L - the target sparsity.
-%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
-%  MSGDELTA - the delay in secs between messages. Zero means no messages.
-%  PROFILE - nonzero means that profiling information should be printed.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
--- a/util/ksvd utils/ompbox utils/ompmexGabor.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/**************************************************************************
- *
- * File name: ompmex.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- *************************************************************************/
-
-#include "ompcoreGabor.h"
-#include "omputils.h"
-#include "mexutils.h"
-
-
-/* Input Arguments */
-
-#define IN_D          prhs[0]
-#define IN_X          prhs[1]
-#define IN_DtX        prhs[2]
-#define IN_G          prhs[3]
-#define IN_T          prhs[4]
-#define IN_SPARSE_G   prhs[5]
-#define IN_MSGDELTA   prhs[6]
-#define IN_PROFILE    prhs[7]
-
-
-/* Output Arguments */
-
-#define	GAMMA_OUT     plhs[0]
-
-
-/***************************************************************************************/
-
-
-void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
-
-{
-  double *D, *x, *DtX, *G, msgdelta;
-  int gmode, profile, T;
-  mwSize m, n, L;   /* D is n x m , X is n x L, DtX is m x L */
-  
-  
-  /* check parameters */
-  
-  checkmatrix(IN_D, "OMP", "D");
-  checkmatrix(IN_X, "OMP", "X");
-  checkmatrix(IN_DtX, "OMP", "DtX");
-  checkmatrix(IN_G, "OMP", "G");
-  
-  checkscalar(IN_T, "OMP", "T");
-  checkscalar(IN_SPARSE_G, "OMP", "sparse_g");
-  checkscalar(IN_MSGDELTA, "OMP", "msgdelta");
-  checkscalar(IN_PROFILE, "OMP", "profile");
-
-  
-  /* get parameters */
-  
-  x = D = DtX = G = 0;
-  
-  if (!mxIsEmpty(IN_D))
-    D = mxGetPr(IN_D);
-  
-  if (!mxIsEmpty(IN_X))
-    x = mxGetPr(IN_X);
-  
-  if (!mxIsEmpty(IN_DtX))
-    DtX = mxGetPr(IN_DtX);
-  
-  if (!mxIsEmpty(IN_G))
-    G = mxGetPr(IN_G);
-  
-  T = (int)(mxGetScalar(IN_T)+1e-2);
-  if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) {
-    gmode = SPARSE_GAMMA;
-  }
-  else {
-    gmode = FULL_GAMMA;
-  }
-  msgdelta = mxGetScalar(IN_MSGDELTA);
-  profile = (int)(mxGetScalar(IN_PROFILE)+1e-2);
-  
-  
-  /* check sizes */
-  
-  if (D && x) {
-    n = mxGetM(IN_D);
-    m = mxGetN(IN_D);
-    L = mxGetN(IN_X);
-    
-    if (mxGetM(IN_X) != n) {
-      mexErrMsgTxt("D and X have incompatible sizes.");
-    }
-    
-    if (G) {
-      if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-        mexErrMsgTxt("G must be a square matrix.");
-      }
-      if (mxGetN(IN_G) != m) {
-        mexErrMsgTxt("D and G have incompatible sizes.");
-      }
-    }
-  }
-  
-  else if (DtX) {
-    m = mxGetM(IN_DtX);
-    L = mxGetN(IN_DtX);
-    
-    n = T;  /* arbitrary - it is enough to assume signal length is T */
-    
-    if (mxGetN(IN_G)!=mxGetM(IN_G)) {
-      mexErrMsgTxt("G must be a square matrix.");
-    }
-    if (mxGetN(IN_G) != m) {
-      mexErrMsgTxt("DtX and G have incompatible sizes.");
-    }
-  }
-  
-  else {
-    mexErrMsgTxt("Either D and X, or DtX, must be specified.");
-  }
-  
-  
-  /* Do OMP! */
-  
-  GAMMA_OUT = ompcoreGabor(D, x, DtX, 0, G, n, m, L, T, 0, gmode, profile, msgdelta, 0);
-  
-  return;
-}
-
--- a/util/ksvd utils/ompbox utils/ompmexGabor.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-%This is the Matlab interface to the OMP MEX implementation.
-%The function is not for independent use, only through omp.m.
-
-
-%OMPMEX Matlab interface to the OMP MEX implementation.
-%  GAMMA = OMPMEXGABOR(D,X,DtX,G,L,SPARSE_G,MSGDELTA,PROFILE) invokes the OMP
-%  MEX function according to the specified parameters. Not all the
-%  parameters are required. Those among D, X, DtX and G which are not
-%  specified should be passed as [].
-%
-%  L - the target sparsity.
-%  SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero.
-%  MSGDELTA - the delay in secs between messages. Zero means no messages.
-%  PROFILE - nonzero means that profiling information should be printed.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2009
--- a/util/ksvd utils/ompbox utils/ompprof.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/**************************************************************************
- *
- * File name: ompprof.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 11.4.2009
- *
- *************************************************************************/
-
-
-#include "ompprof.h"
-
-
-/* initialize profiling information */
-
-void initprofdata(profdata *pd)
-{
-  pd->DtX_time = 0;
-  pd->XtX_time = 0;
-  pd->DtR_time = 0;
-  pd->maxabs_time = 0;
-  pd->DtD_time = 0;
-  pd->Lchol_time = 0;
-  pd->compcoef_time = 0;
-  pd->update_DtR_time = 0;
-  pd->update_resnorm_time = 0;
-  pd->compres_time = 0;
-  pd->indexsort_time = 0;
-  
-  pd->DtX_time_counted = 0;
-  pd->XtX_time_counted = 0;
-  pd->DtR_time_counted = 0;
-  pd->DtD_time_counted = 0;
-  pd->update_DtR_time_counted = 0;
-  pd->resnorm_time_counted = 0;
-  pd->compres_time_counted = 0;
-  pd->indexsort_time_counted = 0;
-  
-  pd->prevtime = clock();
-}
-
-
-/* add elapsed time to profiling data according to specified computation */
-
-void addproftime(profdata *pd, int comptype)
-{
-  switch(comptype) {
-    case DtX_TIME:            pd->DtX_time            += clock()-pd->prevtime; pd->DtX_time_counted = 1; break;
-    case XtX_TIME:            pd->XtX_time            += clock()-pd->prevtime; pd->XtX_time_counted = 1; break;
-    case DtR_TIME:            pd->DtR_time            += clock()-pd->prevtime; pd->DtR_time_counted = 1; break;
-    case DtD_TIME:            pd->DtD_time            += clock()-pd->prevtime; pd->DtD_time_counted = 1; break;
-    case COMPRES_TIME:        pd->compres_time        += clock()-pd->prevtime; pd->compres_time_counted = 1; break;
-    case UPDATE_DtR_TIME:     pd->update_DtR_time     += clock()-pd->prevtime; pd->update_DtR_time_counted = 1; break;
-    case UPDATE_RESNORM_TIME: pd->update_resnorm_time += clock()-pd->prevtime; pd->resnorm_time_counted = 1; break;
-    case INDEXSORT_TIME:      pd->indexsort_time      += clock()-pd->prevtime; pd->indexsort_time_counted = 1; break;
-    case MAXABS_TIME:         pd->maxabs_time         += clock()-pd->prevtime; break;
-    case LCHOL_TIME:          pd->Lchol_time          += clock()-pd->prevtime; break;
-    case COMPCOEF_TIME:       pd->compcoef_time       += clock()-pd->prevtime; break;
-  }
-  pd->prevtime = clock();
-}
-
-
-/* print profiling info */
-
-void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum)
-{
-  clock_t tottime;
-  
-  tottime = pd->DtX_time + pd->XtX_time + pd->DtR_time + pd->DtD_time + pd->compres_time + pd->maxabs_time + 
-            pd->Lchol_time + pd->compcoef_time + pd->update_DtR_time + pd->update_resnorm_time + pd->indexsort_time;
-  
-  mexPrintf("\n\n*****  Profiling information for %s  *****\n\n", erroromp? "OMP2" : "OMP");
-  
-  mexPrintf("OMP mode: %s\n\n", batchomp? "Batch-OMP" : "OMP-Cholesky");
-  
-  mexPrintf("Total signals processed: %d\n\n", signum);
-  
-  if (pd->DtX_time_counted) {
-    mexPrintf("Compute DtX time:      %7.3lf seconds\n", pd->DtX_time/(double)CLOCKS_PER_SEC);
-  }
-  if (pd->XtX_time_counted) {
-    mexPrintf("Compute XtX time:      %7.3lf seconds\n", pd->XtX_time/(double)CLOCKS_PER_SEC);
-  }
-  mexPrintf("Max abs time:          %7.3lf seconds\n", pd->maxabs_time/(double)CLOCKS_PER_SEC);
-  if (pd->DtD_time_counted) {
-    mexPrintf("Compute DtD time:      %7.3lf seconds\n", pd->DtD_time/(double)CLOCKS_PER_SEC);
-  }
-  mexPrintf("Lchol update time:     %7.3lf seconds\n", pd->Lchol_time/(double)CLOCKS_PER_SEC);
-  mexPrintf("Compute coef time:     %7.3lf seconds\n", pd->compcoef_time/(double)CLOCKS_PER_SEC);
-  if (pd->compres_time_counted) {
-    mexPrintf("Compute R time:        %7.3lf seconds\n", pd->compres_time/(double)CLOCKS_PER_SEC);
-  }
-  if (pd->DtR_time_counted) {
-    mexPrintf("Compute DtR time:      %7.3lf seconds\n", pd->DtR_time/(double)CLOCKS_PER_SEC);
-  }
-  if (pd->update_DtR_time_counted) {
-    mexPrintf("Update DtR time:       %7.3lf seconds\n", pd->update_DtR_time/(double)CLOCKS_PER_SEC);
-  }
-  if (pd->resnorm_time_counted) {
-    mexPrintf("Update resnorm time:   %7.3lf seconds\n", pd->update_resnorm_time/(double)CLOCKS_PER_SEC);
-  }
-  if (pd->indexsort_time_counted) {
-    mexPrintf("Index sort time:       %7.3lf seconds\n", pd->indexsort_time/(double)CLOCKS_PER_SEC);
-  }
-  mexPrintf("---------------------------------------\n");
-  mexPrintf("Total time:            %7.3lf seconds\n\n", tottime/(double)CLOCKS_PER_SEC);
-}
-
--- a/util/ksvd utils/ompbox utils/ompprof.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/**************************************************************************
- *
- * File name: ompprof.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- * Collection of definitions and functions for profiling the OMP method.
- *
- *************************************************************************/
-
-
-#ifndef __OMP_PROF_H__
-#define __OMP_PROF_H__
-
-#include "mex.h"
-#include <time.h>
-
-
-
-/**************************************************************************
- *
- * Constants and data types.
- *
- **************************************************************************/
-
-
-/* constants denoting the various parts of the algorithm */
-
-enum { DtX_TIME, XtX_TIME, DtR_TIME, MAXABS_TIME, DtD_TIME, LCHOL_TIME, COMPCOEF_TIME, 
-       UPDATE_DtR_TIME, UPDATE_RESNORM_TIME, COMPRES_TIME, INDEXSORT_TIME };
-
-       
-       
-/* profiling data container with counters for each part of the algorithm */
-       
-typedef struct profdata 
-{
-  clock_t prevtime;  /* the time when last initialization/call to addproftime() was performed */
-  
-  clock_t DtX_time;
-  clock_t XtX_time;
-  clock_t DtR_time;
-  clock_t maxabs_time;
-  clock_t DtD_time;
-  clock_t Lchol_time;
-  clock_t compcoef_time;
-  clock_t update_DtR_time;
-  clock_t update_resnorm_time;
-  clock_t compres_time;
-  clock_t indexsort_time;
-  
-  /* flags indicating whether profiling data was gathered */
-  int DtX_time_counted;
-  int XtX_time_counted;
-  int DtR_time_counted;
-  int DtD_time_counted;
-  int update_DtR_time_counted;
-  int resnorm_time_counted;
-  int compres_time_counted;
-  int indexsort_time_counted;
-  
-} profdata;
-
-
-
-/**************************************************************************
- *
- * Initialize a profdata structure, zero all counters, and start its timer.
- *
- **************************************************************************/
-void initprofdata(profdata *pd);
-
-
-/**************************************************************************
- *
- * Add elapsed time from last call to addproftime(), or from initialization
- * of profdata, to the counter specified by comptype. comptype must be one
- * of the constants in the enumeration above.
- *
- **************************************************************************/
-void addproftime(profdata *pd, int comptype);
-
-
-/**************************************************************************
- *
- * Print the current contents of the counters in profdata.
- *
- * Parameters:
- *   pd - the profdata to print
- *   erroromp - indicates whether error-based (nonzero) or sparsity-based (zero)
- *              omp was performed.
- *   batchomp - indicates whether batch-omp (nonzero) or omp-cholesky (zero)
- *              omp was performed.
- *   signum   - number of signals processed by omp
- *
- **************************************************************************/
-void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum);
-
-
-#endif
-
--- a/util/ksvd utils/ompbox utils/omputils.c	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/**************************************************************************
- *
- * File name: omputils.c
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- *************************************************************************/
-
-#include "omputils.h"
-#include <math.h>
-
-
-const char FULL_GAMMA_STR[] = "full";
-const char SPARSE_GAMMA_STR[] = "sparse";
-
-
-/* convert seconds to hours, minutes and seconds */
-
-void secs2hms(double sectot, int *hrs, int *mins, double *secs)
-{
-  *hrs = (int)(floor(sectot/3600)+1e-2);
-  sectot = sectot - 3600*(*hrs);
-  *mins = (int)(floor(sectot/60)+1e-2);
-  *secs = sectot - 60*(*mins);
-}
-
-
-/* quicksort, public-domain C implementation by Darel Rex Finley. */
-/* modification: sorts the array data[] as well, according to the values in the array vals[] */
-
-#define  MAX_LEVELS  300
-
-void quicksort(mwIndex vals[], double data[], mwIndex n) {
-  
-  long piv, beg[MAX_LEVELS], end[MAX_LEVELS], i=0, L, R, swap ;
-  double datapiv;
-  
-  beg[0]=0;
-  end[0]=n;
-  
-  while (i>=0) {
-    
-    L=beg[i]; 
-    R=end[i]-1;
-    
-    if (L<R) {
-      
-      piv=vals[L];
-      datapiv=data[L];
-      
-      while (L<R) 
-      {
-        while (vals[R]>=piv && L<R) 
-          R--;
-        if (L<R) {
-          vals[L]=vals[R];
-          data[L++]=data[R];
-        }
-        
-        while (vals[L]<=piv && L<R) 
-          L++;
-        if (L<R) { 
-          vals[R]=vals[L];
-          data[R--]=data[L];
-        }
-      }
-      
-      vals[L]=piv;
-      data[L]=datapiv;
-      
-      beg[i+1]=L+1;
-      end[i+1]=end[i];
-      end[i++]=L;
-      
-      if (end[i]-beg[i] > end[i-1]-beg[i-1]) {
-        swap=beg[i]; beg[i]=beg[i-1]; beg[i-1]=swap;
-        swap=end[i]; end[i]=end[i-1]; end[i-1]=swap;
-      }
-    }
-    else {
-      i--;
-    }
-  }
-}
--- a/util/ksvd utils/ompbox utils/omputils.h	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/**************************************************************************
- *
- * File name: omputils.h
- *
- * Ron Rubinstein
- * Computer Science Department
- * Technion, Haifa 32000 Israel
- * ronrubin@cs
- *
- * Last Updated: 18.8.2009
- *
- * Utility definitions and functions for the OMP library.
- *
- *************************************************************************/
-
-
-#ifndef __OMP_UTILS_H__
-#define __OMP_UTILS_H__
-
-#include "mex.h"
-
-
-/* constants for the representation mode of gamma */
-
-extern const char FULL_GAMMA_STR[];      /* "full" */
-extern const char SPARSE_GAMMA_STR[];    /* "sparse" */
-
-
-#define FULL_GAMMA 1
-#define SPARSE_GAMMA 2
-#define INVALID_MODE 3
-
-
-
-/**************************************************************************
- * Memory management for OMP2.
- *
- * GAMMA_INC_FACTOR:
- * The matrix GAMMA is allocated with sqrt(n)/2 coefficients per signal,
- * for a total of nzmax = L*sqrt(n)/2 nonzeros. Whenever GAMMA needs to be
- * increased, it is increased by a factor of GAMMA_INC_FACTOR.
- *
- * MAT_INC_FACTOR:
- * The matrices Lchol, Gsub and Dsub are allocated with sqrt(n)/2
- * columns each. If additional columns are needed, this number is 
- * increased by a factor of MAT_INC_FACTOR.
- **************************************************************************/
-
-#define GAMMA_INC_FACTOR (1.4)
-#define MAT_INC_FACTOR (1.6)
-
-
-
-/**************************************************************************
- * Convert number of seconds to hour, minute and second representation.
- *
- * Parameters:
- *   sectot - total number of seconds
- *   hrs, mins, secs - output hours (whole) and minutes (whole) and seconds
- *
- **************************************************************************/
-void secs2hms(double sectot, int *hrs, int *mins, double *secs);
-
-
-
-/**************************************************************************
- * QuickSort - public-domain C implementation by Darel Rex Finley.
- *
- * Modified to sort both the array vals[] and the array data[] according 
- * to the values in the array vals[].
- *
- **************************************************************************/
-void quicksort(mwIndex vals[], double data[], mwIndex n);
-
-
-#endif
-
--- a/util/ksvd utils/ompbox utils/printf.m	Thu Jul 21 16:37:14 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-function str = printf(varargin)
-%PRINTF Print formatted text to screen.
-%  PRINTF(FMT,VAL1,VAL2,...) formats the data in VAL1,VAL2,... according to
-%  the format string FMT, and prints the result to the screen.
-%
-%  The call to PRINTF(FMT,VAL1,VAL2,...) simply invokes the call
-%  DISP(SPRINTF(FMT,VAL1,VAL2,...)). For a complete description of the
-%  format string options see function SPRINTF.
-%
-%  STR = PRINTF(...) also returns the formatted string.
-
-
-%  Ron Rubinstein
-%  Computer Science Department
-%  Technion, Haifa 32000 Israel
-%  ronrubin@cs
-%
-%  April 2008
-
-
-if (nargout>0)
-  str = sprintf(varargin{:});
-  disp(str);
-else
-  disp(sprintf(varargin{:}));
-end