# HG changeset patch # User luisf # Date 1334156199 -3600 # Node ID 0d30f9074dd966a4ecbaebc40c3e2042bb66de25 # Parent 775caafd565152cd397195b2a9f09083b0d853d3# Parent 4337e28183f1c813aee627c94bfcc92e73e6ae3d Merge diff -r 775caafd5651 -r 0d30f9074dd9 DL/Majorization Minimization DL/wrapper_mm_DL.m --- a/DL/Majorization Minimization DL/wrapper_mm_DL.m Wed Sep 07 14:17:55 2011 +0100 +++ b/DL/Majorization Minimization DL/wrapper_mm_DL.m Wed Apr 11 15:56:39 2012 +0100 @@ -1,4 +1,55 @@ function DL = wrapper_mm_DL(Problem, DL) +%% SMALL wrapper for Majorization Minimization Dictionary Learning Algorithm +% +% Function gets as input Problem and Dictionary Learning (DL) structures +% and outputs the learned Dictionary. +% +% In Problem structure field b with the training set needs to be defined. +% +% In DL structure field with name of the Dictionary update method needs +% to be present. For the orignal version of MM algorithm the update +% method should be: +% - 'mm_cn' Regularized DL with column norm contraint +% - 'mm_fn' Regularized DL with Frobenius norm contraint +% Alternatively, for comparison purposes the following Dictioanry update +% methods (which do not represent the optimised version of the algorithm) +% be used: +% - 'mod_cn' Method of Optimized Direction +% - 'map-cn' Maximum a Posteriory Dictionary update +% - 'ksvd-cn' KSVD update +% +% The structure DL.param with parameters is also required. These are: +% - solver structure with fields toolbox, solver and parameters. +% For the original version of the algorithm toolbox +% should be 'MMbox' and solver field should be left +% empty ''. Type HELP WRAPPER_MM_SOLVER for more +% details on how to set the parameters. +% - initdict Initial Dictionary +% - dictsize Dictionary size (optional) +% - iternum Number of iterations (default is 40) +% - iterDictUpdate Number of iterations for Dictionary Update (default is 1000) +% - epsDictUpdate Stopping criterion for MM dictionary update (default = 1e-7) +% - cvset Dictionary constraint - 0 = Non convex ||d|| = 1, 1 = Convex ||d||<=1 +% (default is 0) +% - coherence Set at 1 if to perform decorrelation in every iteration +% (default is 0) +% - show_dict Show dictonary every specified number of iterations +% +% +% - MM-DL - Yaghoobi, M.; Blumensath, T,; Davies M.; , "Dictionary +% Learning for Sparse Approximation with Majorization Method," IEEE +% Transactions on Signal Processing, vol.57, no.6, pp.2178-2191, 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. +%% % determine which solver is used for sparse representation % diff -r 775caafd5651 -r 0d30f9074dd9 DL/Majorization Minimization DL/wrapper_mm_solver.m --- a/DL/Majorization Minimization DL/wrapper_mm_solver.m Wed Sep 07 14:17:55 2011 +0100 +++ b/DL/Majorization Minimization DL/wrapper_mm_solver.m Wed Apr 11 15:56:39 2012 +0100 @@ -1,14 +1,27 @@ function [X , cost] = wrapper_mm_solver(b, A, param) -%% SMALL wrapper for Majorization Maximization toolbos solver +%% SMALL wrapper for Majorization Minimization toolbox solver % % Function gets as input % b - measurement vector % A - dictionary -% param - structure containing additional parameters +% param - structure containing additional parameters. These are: +% - initcoeff Initial guess for the coefficients +% (optional) +% - to 1/(step size). It is larger than spectral norm +% of dictionary A (default is 0.1+(svds(A,1))^2) +% - lambda Lagrangian multiplier. Regulates shrinkage +% (default is 0.4) +% - iternum Inner-loop maximum iteration number +% (default is 1000) +% - epsilon Stopping criterion for iterative softthresholding +% (default is 1e-7) +% - map Debiasing. 0 = No, 1 = Yes (default is 0) +% % Output: % x - sparse solution % cost - Objective cost +% % Centre for Digital Music, Queen Mary, University of London. % This file copyright 2011 Ivan Damnjanovic. % diff -r 775caafd5651 -r 0d30f9074dd9 DL/RLS-DLA/SMALL_rlsdla.m --- a/DL/RLS-DLA/SMALL_rlsdla.m Wed Sep 07 14:17:55 2011 +0100 +++ b/DL/RLS-DLA/SMALL_rlsdla.m Wed Apr 11 15:56:39 2012 +0100 @@ -26,9 +26,8 @@ % - RLS-DLA - Skretting, K.; Engan, K.; , "Recursive Least Squares % Dictionary Learning Algorithm," Signal Processing, IEEE Transactions on, % vol.58, no.4, pp.2121-2130, April 2010 + % - - % Centre for Digital Music, Queen Mary, University of London. % This file copyright 2011 Ivan Damnjanovic. % diff -r 775caafd5651 -r 0d30f9074dd9 DL/two-step DL/SMALL_two_step_DL.m --- a/DL/two-step DL/SMALL_two_step_DL.m Wed Sep 07 14:17:55 2011 +0100 +++ b/DL/two-step DL/SMALL_two_step_DL.m Wed Apr 11 15:56:39 2012 +0100 @@ -1,10 +1,22 @@ function DL=SMALL_two_step_DL(Problem, DL) + + %% DL=SMALL_two_step_DL(Problem, DL) learn a dictionary using two_step_DL + % The specific parameters of the DL structure are: + % -name: can be either 'ols', 'opt', 'MOD', KSVD' or 'LGD'. + % -param.learningRate: a step size used by 'ols' and 'opt'. Default: 0.1 + % for 'ols', 1 for 'opt'. + % -param.flow: can be either 'sequential' or 'parallel'. De fault: + % 'sequential'. Not used by MOD. + % -param.coherence: a real number between 0 and 1. If present, then + % a low-coherence constraint is added to the learning. + % + % See dico_update.m for more details. % determine which solver is used for sparse representation % solver = DL.param.solver; -% determine which type of udate to use ('KSVD', 'MOD', 'ols' or 'mailhe') % +% determine which type of udate to use ('KSVD', 'MOD', 'ols', 'opt' or 'LGD') % typeUpdate = DL.name; @@ -57,14 +69,19 @@ end % learningRate. If the type is 'ols', it is the descent step of -% the gradient (typical choice: 0.1). If the type is 'mailhe', the -% descent step is the optimal step*rho (typical choice: 1, although 2 -% or 3 seems to work better). Not used for MOD and KSVD. +% the gradient (default: 0.1). If the type is 'mailhe', the +% descent step is the optimal step*rho (default: 1, although 2 works +% better). Not used for MOD and KSVD. if isfield(DL.param,'learningRate') learningRate = DL.param.learningRate; else - learningRate = 0.1; + switch typeUpdate + case 'ols' + learningRate = 0.1; + otherwise + learningRate = 1; + end end % number of iterations (default is 40) % @@ -113,7 +130,7 @@ [dico, solver.solution] = dico_update(dico, sig, solver.solution, ... typeUpdate, flow, learningRate); if (decorrelate) - dico = dico_decorr(dico, mu, solver.solution); + dico = dico_decorr_symetric(dico, mu, solver.solution); end if ((show_dictionary)&&(mod(i,show_iter)==0)) diff -r 775caafd5651 -r 0d30f9074dd9 DL/two-step DL/dico_color_separate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DL/two-step DL/dico_color_separate.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,95 @@ +function [colors nbColors] = dico_color_separate(dico, mu) + % DICO_COLOR cluster several dictionaries in pairs of high correlation + % atoms. Called by dico_decorr. + % + % Parameters: + % -dico: the dictionaries + % -mu: the correlation threshold + % + % Result: + % -colors: a cell array of indices. Two atoms with the same color have + % a correlation greater than mu + + + numDico = length(dico); + colors = cell(numDico,1); + for i = 1:numDico + colors{i} = zeros(length(dico{i}),1); + end + + G = cell(numDico); + + % compute the correlations + for i = 1:numDico + for j = i+1:numDico + G{i,j} = abs(dico{i}'*dico{j}); + end + end + + % iterate on the correlations higher than mu + c = 1; + [maxCorr, i, j, m, n] = findMaxCorr(G); + while maxCorr > mu + % find the highest correlated pair + + % color them + colors{i}(m) = c; + colors{j}(n) = c; + c = c+1; + + % make sure these atoms never get selected again + % Set to zero relevant lines in the Gram Matrix + for j2 = i+1:numDico + G{i,j2}(m,:) = 0; + end + + for i2 = 1:i-1 + G{i2,i}(:,m) = 0; + end + + for j2 = j+1:numDico + G{j,j2}(n,:) = 0; + end + + for i2 = 1:j-1 + G{i2,j}(:,n) = 0; + end + + % find the next correlation + [maxCorr, i, j, m, n] = findMaxCorr(G); + end + + % complete the coloring with singletons + % index = find(colors==0); + % colors(index) = c:c+length(index)-1; + nbColors = c-1; +end + +function [val, i, j, m, n] = findMaxCorr(G) + %FINDMAXCORR find the maximal correlation in the cellular Gram matrix + % + % Input: + % -G: the Gram matrix + % + % Output: + % -val: value of the correlation + % -i,j,m,n: indices of the argmax. The maximal correlation is reached + % for the m^th atom of the i^th dictionary and the n^h atom of the + % j^h dictionary + + val = -1; + for tmpI = 1:length(G) + for tmpJ = tmpI+1:length(G) + [tmpVal tmpM] = max(G{tmpI,tmpJ},[],1); + [tmpVal tmpN] = max(tmpVal); + if tmpVal > val + val = tmpVal; + i = tmpI; + j = tmpJ; + n = tmpN; + m = tmpM(n); + end + end + end +end + \ No newline at end of file diff -r 775caafd5651 -r 0d30f9074dd9 DL/two-step DL/dico_decorr_symetric.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DL/two-step DL/dico_decorr_symetric.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,139 @@ +function dico = dico_decorr_symetric(dico, mu) + %DICO_DECORR decorrelate a dictionary + % Parameters: + % dico: the dictionary, either a matrix or a cell array of matrices. + % mu: the coherence threshold + % + % Result: + % dico: if the input dico was a matrix, then a matrix close to the + % input one with coherence mu. + % If the input was a cell array, a cell array of the same size + % containing matrices such that the coherence between different cells + % is lower than mu. + + eps = 1e-3; % define tolerance for normalisation term alpha + + % convert mu to the to the mean direction + theta = acos(mu)/2; + ctheta = cos(theta); + stheta = sin(theta); + + % compute atom weights + % if nargin > 2 + % rank = sum(amp.*amp, 2); + % else + % rank = randperm(length(dico)); + % end + + % if only one dictionary is provided, then decorrelate it + if ~iscell(dico) + % several decorrelation iterations might be needed to reach global + % coherence mu. niter can be adjusted to needs. + niter = 1; + while max(max(abs(dico'*dico -eye(length(dico))))) > mu + eps + % find pairs of high correlation atoms + colors = dico_color(dico, mu); + + % iterate on all pairs + nbColors = max(colors); + for c = 1:nbColors + index = find(colors==c); + if numel(index) == 2 + if dico(:,index(1))'*dico(:,index(2)) > 0 + %build the basis vectors + v1 = dico(:,index(1))+dico(:,index(2)); + v1 = v1/norm(v1); + v2 = dico(:,index(1))-dico(:,index(2)); + v2 = v2/norm(v2); + + dico(:,index(1)) = ctheta*v1+stheta*v2; + dico(:,index(2)) = ctheta*v1-stheta*v2; + else + v1 = dico(:,index(1))-dico(:,index(2)); + v1 = v1/norm(v1); + v2 = dico(:,index(1))+dico(:,index(2)); + v2 = v2/norm(v2); + + dico(:,index(1)) = ctheta*v1+stheta*v2; + dico(:,index(2)) = -ctheta*v1+stheta*v2; + end + end + end + niter = niter+1; + end + %if a cell array of dictionaries is provided, decorrelate among + %different dictionaries only + else + niter = 1; + numDicos = length(dico); + G = cell(numDicos); + maxCorr = 0; + for i = 1:numDicos + for j = i+1:numDicos + G{i,j} = dico{i}'*dico{j}; + maxCorr = max(maxCorr,max(max(abs(G{i,j})))); + end + end + + while maxCorr > mu + eps + % find pairs of high correlation atoms + [colors nbColors] = dico_color_separate(dico, mu); + + % iterate on all pairs + for c = 1:nbColors + for tmpI = 1:numDicos + index = find(colors{tmpI}==c); + if ~isempty(index) + i = tmpI; + m = index; + break; + end + end + for tmpJ = i+1:numDicos + index = find(colors{tmpJ}==c); + if ~isempty(index) + j = tmpJ; + n = index; + break; + end + end + + if dico{i}(:,m)'*dico{j}(:,n) > 0 + %build the basis vectors + v1 = dico{i}(:,m)+dico{j}(:,n); + v1 = v1/norm(v1); + v2 = dico{i}(:,m)-dico{j}(:,n); + v2 = v2/norm(v2); + + dico{i}(:,m) = ctheta*v1+stheta*v2; + dico{j}(:,n) = ctheta*v1-stheta*v2; + else + v1 = dico{i}(:,m)-dico{j}(:,n); + v1 = v1/norm(v1); + v2 = dico{i}(:,m)+dico{j}(:,n); + v2 = v2/norm(v2); + + dico{i}(:,m) = ctheta*v1+stheta*v2; + dico{j}(:,n) = -ctheta*v1+stheta*v2; + end + end + niter = niter+1; + + % Remove noegative components and renormalize + for i = 1:length(dico) + dico{i} = max(dico{i},0); + for m = 1:size(dico{i},2) + dico{i}(:,m) = dico{i}(:,m)/norm(dico{i}(:,m)); + end + end + + maxCorr = 0; + for i = 1:numDicos + for j = i+1:numDicos + G{i,j} = dico{i}'*dico{j}; + maxCorr = max(maxCorr,max(max(abs(G{i,j})))); + end + end + end + end +end diff -r 775caafd5651 -r 0d30f9074dd9 DL/two-step DL/dico_update.m --- a/DL/two-step DL/dico_update.m Wed Sep 07 14:17:55 2011 +0100 +++ b/DL/two-step DL/dico_update.m Wed Apr 11 15:56:39 2012 +0100 @@ -1,5 +1,5 @@ function [dico, amp] = dico_update(dico, sig, amp, type, flow, rho) - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [dico, amp] = dico_update(dico, sig, amp, type, flow, rho) % @@ -10,44 +10,56 @@ % - sig: the training data % - amp: the amplitude coefficients as a sparse matrix % - type: the algorithm can be one of the following - % - ols: fixed step gradient descent - % - mailhe: optimal step gradient descent (can be implemented as a - % default for ols?) - % - MOD: pseudo-inverse of the coefficients - % - KSVD: already implemented by Elad + % - ols: fixed step gradient descent, as described in Olshausen & + % Field95 + % - opt: optimal step gradient descent, as described in Mailhe et + % al.08 + % - MOD: pseudo-inverse of the coefficients, as described in Engan99 + % - KSVD: PCA update as described in Aharon06. For fast applications, + % use KSVDbox rather than this code. + % - LGD: large step gradient descent. Equivalent to 'opt' with + % rho=2. % - flow: 'sequential' or 'parallel'. If sequential, the residual is % updated after each atom update. If parallel, the residual is only - % updated once the whole dictionary has been computed. Sequential works - % better, there may be no need to implement parallel. Not used with + % updated once the whole dictionary has been computed. + % Default: Sequential (sequential usually works better). Not used with % MOD. % - rho: learning rate. If the type is 'ols', it is the descent step of - % the gradient (typical choice: 0.1). If the type is 'mailhe', the - % descent step is the optimal step*rho (typical choice: 1, although 2 - % or 3 seems to work better). Not used for MOD and KSVD. + % the gradient (default: 0.1). If the type is 'opt', the + % descent step is the optimal step*rho (default: 1, although 2 works + % better. See LGD for more details). Not used for MOD and KSVD. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if ~ exist( 'rho', 'var' ) || isempty(rho) - rho = 0.1; - end if ~ exist( 'flow', 'var' ) || isempty(flow) - flow = sequential; + flow = 'sequential'; end res = sig - dico*amp; nb_pattern = size(dico, 2); + % if the type is random, then randomly pick another type switch type case 'rand' x = rand(); if x < 1/3 type = 'MOD'; elseif type < 2/3 - type = 'mailhe'; + type = 'opt'; else type = 'KSVD'; end end + % set the learning rate to default if not provided + if ~ exist( 'rho', 'var' ) || isempty(rho) + switch type + case 'ols' + rho = 0.1; + case 'opt' + rho = 1; + end + end + switch type case 'MOD' G = amp*amp'; @@ -72,14 +84,30 @@ dico(:,p) = pat; end end - case 'mailhe' + case 'opt' for p = 1:nb_pattern - grad = res*amp(p,:)'; + index = find(amp(p,:)~=0); + vec = amp(p,index); + grad = res(:,index)*vec'; if norm(grad) > 0 - pat = (amp(p,:)*amp(p,:)')*dico(:,p) + rho*grad; + pat = (vec*vec')*dico(:,p) + rho*grad; pat = pat/norm(pat); if nargin >5 && strcmp(flow, 'sequential') - res = res + (dico(:,p)-pat)*amp(p,:); + res(:,index) = res(:,index) + (dico(:,p)-pat)*vec; + end + dico(:,p) = pat; + end + end + case 'LGD' + for p = 1:nb_pattern + index = find(amp(p,:)~=0); + vec = amp(p,index); + grad = res(:,index)*vec'; + if norm(grad) > 0 + pat = (vec*vec')*dico(:,p) + 2*grad; + pat = pat/norm(pat); + if nargin >5 && strcmp(flow, 'sequential') + res(:,index) = res(:,index) + (dico(:,p)-pat)*vec; end dico(:,p) = pat; end @@ -89,7 +117,7 @@ index = find(amp(p,:)~=0); if ~isempty(index) patch = res(:,index)+dico(:,p)*amp(p,index); - [U,S,V] = svd(patch); + [U,~,V] = svd(patch); if U(:,1)'*dico(:,p) > 0 dico(:,p) = U(:,1); else diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generateAMTProblem.m --- a/Problems/generateAMTProblem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generateAMTProblem.m Wed Apr 11 15:56:39 2012 +0100 @@ -40,10 +40,10 @@ %% %ask for file name TMPpath=pwd; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'audio']); [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.name=name; data.notesOriginal=[]; diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generateAMT_Learning_Problem.m --- a/Problems/generateAMT_Learning_Problem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generateAMT_Learning_Problem.m Wed Apr 11 15:56:39 2012 +0100 @@ -40,10 +40,10 @@ %% %ask for file name TMPpath=pwd; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'audio']); [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.name=name; data.notesOriginal=[]; diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generateAudioDeclippingProblem.m --- a/Problems/generateAudioDeclippingProblem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generateAudioDeclippingProblem.m Wed Apr 11 15:56:39 2012 +0100 @@ -58,10 +58,10 @@ if ~ exist( 'soundfile', 'var' ) || isempty(soundfile) %ask for file name - [pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); + [pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'audio']); [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe'); - [pathstr, name, ext, versn] = fileparts(filename); + [pathstr, name, ext] = fileparts(filename); data.name=name; if strcmp(ext,'.mid') @@ -92,7 +92,7 @@ end else [x.signal, x.fs, x.nbits]=wavread(soundfile); - [pathstr, name, ext, versn] = fileparts(soundfile); + [pathstr, name, ext] = fileparts(soundfile); data.name=name; end diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generateAudioDenoiseProblem.m --- a/Problems/generateAudioDenoiseProblem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generateAudioDenoiseProblem.m Wed Apr 11 15:56:39 2012 +0100 @@ -57,10 +57,10 @@ TMPpath=pwd; if ~ exist( 'soundfile', 'var' ) || isempty(soundfile) %ask for file name - [pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); + [pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'audio']); [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe'); - [pathstr, name, ext, versn] = fileparts(filename); + [pathstr, name, ext] = fileparts(filename); data.name=name; if strcmp(ext,'.mid') @@ -91,7 +91,7 @@ end else [x.signal, x.fs, x.nbits]=wavread(soundfile); - [pathstr, name, ext, versn] = fileparts(soundfile); + [pathstr, name, ext] = fileparts(soundfile); data.name=name; end diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generateImageDenoiseProblem.m --- a/Problems/generateImageDenoiseProblem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generateImageDenoiseProblem.m Wed Apr 11 15:56:39 2012 +0100 @@ -63,10 +63,10 @@ FS=filesep; TMPpath=pwd; if ~ exist( 'im', 'var' ) || isempty(im) - [pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); + [pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); [filename,pathname] = uigetfile({'*.png;'},'Select an image'); - [pathstr, name, ext, versn] = fileparts(filename); + [pathstr, name, ext] = fileparts(filename); data.name=name; im = imread(filename); %im = double(im); diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generatePierreProblem.m --- a/Problems/generatePierreProblem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generatePierreProblem.m Wed Apr 11 15:56:39 2012 +0100 @@ -45,10 +45,10 @@ TMPpath=pwd; FS=filesep; if ~ exist( 'src', 'var' ) || isempty(src) -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); [filename,pathname] = uigetfile({'*.png;'},'Select a source image'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.srcname=name; src = imread(filename); src = double(src); @@ -58,7 +58,7 @@ if ~ exist( 'trg', 'var' ) || isempty(trg) [filename,pathname] = uigetfile({'*.png;'},'Select a target image'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.trgname=name; trg = imread(filename); trg = double(trg); diff -r 775caafd5651 -r 0d30f9074dd9 Problems/generatePierre_Problem.m --- a/Problems/generatePierre_Problem.m Wed Sep 07 14:17:55 2011 +0100 +++ b/Problems/generatePierre_Problem.m Wed Apr 11 15:56:39 2012 +0100 @@ -45,10 +45,10 @@ TMPpath=pwd; FS=filesep; if ~ exist( 'src', 'var' ) || isempty(src) -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); [filename,pathname] = uigetfile({'*.png;'},'Select a source image'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.srcname=name; src = imread(filename); src = double(src); @@ -58,7 +58,7 @@ if ~ exist( 'trg', 'var' ) || isempty(trg) [filename,pathname] = uigetfile({'*.png;'},'Select a target image'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); data.trgname=name; trg = imread(filename); trg = double(trg); diff -r 775caafd5651 -r 0d30f9074dd9 SMALLboxInit.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SMALLboxInit.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,25 @@ +%% SMALLboxInit +% +% SMALLbox Initialization +% +% Important: If running SMALLBox for the first time, +% please run SMALLboxSetup instead + +% +% Centre for Digital Music, Queen Mary, University of London. +% This file copyright 2009 Ivan Damnjanovic, Matthew Davies. +% +% 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. +% +%% + +global SMALL_path; +SMALL_path = fileparts(mfilename('fullpath')); + +addpath(genpath(SMALL_path)); + + diff -r 775caafd5651 -r 0d30f9074dd9 SMALLboxSetup.m --- a/SMALLboxSetup.m Wed Sep 07 14:17:55 2011 +0100 +++ b/SMALLboxSetup.m Wed Apr 11 15:56:39 2012 +0100 @@ -66,14 +66,11 @@ end - - - -SMALL_path=pwd; +global SMALL_path; +SMALL_path=fileparts(mfilename('fullpath')); SMALL_p=genpath(SMALL_path); addpath(SMALL_p); - %% diff -r 775caafd5651 -r 0d30f9074dd9 config/SMALL_learn_config.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/SMALL_learn_config.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,97 @@ +%% Configuration file used in SMALL_learn +% +% Use this file to change the dictionary learning algorithms in SMALLBox +% Please refer to the documentation before editing this file + +% Centre for Digital Music, Queen Mary, University of London. +% This file copyright 2009 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. +% +%% + +if strcmpi(DL.toolbox,'KSVD') + param=DL.param; + param.data=Problem.b; + + D = eval([DL.name,'(param)']);%, ''t'', 5);']); +elseif strcmpi(DL.toolbox,'KSVDS') + param=DL.param; + param.data=Problem.b; + + D = eval([DL.name,'(param, ''t'', 5);']); +elseif strcmpi(DL.toolbox,'SPAMS') + + X = Problem.b; + param=DL.param; + + D = eval([DL.name,'(X, param);']); + % As some versions of SPAMS does not produce unit norm column + % dictionaries, we need to make sure that columns are normalised to + % unit lenght. + + for i = 1: size(D,2) + D(:,i)=D(:,i)/norm(D(:,i)); + end +elseif strcmpi(DL.toolbox,'SMALL') + + X = Problem.b; + param=DL.param; + + D = eval([DL.name,'(X, param);']); + % we need to make sure that columns are normalised to + % unit lenght. + + for i = 1: size(D,2) + D(:,i)=D(:,i)/norm(D(:,i)); + end + +elseif strcmpi(DL.toolbox,'TwoStepDL') + + DL=SMALL_two_step_DL(Problem, DL); + + % we need to make sure that columns are normalised to + % unit lenght. + + for i = 1: size(DL.D,2) + DL.D(:,i)=DL.D(:,i)/norm(DL.D(:,i)); + end + D = DL.D; + +elseif strcmpi(DL.toolbox,'MMbox') + + DL = wrapper_mm_DL(Problem, DL); + + % we need to make sure that columns are normalised to + % unit lenght. + + for i = 1: size(DL.D,2) + DL.D(:,i)=DL.D(:,i)/norm(DL.D(:,i)); + end + D = DL.D; + +% To introduce new dictionary learning technique put the files in +% your Matlab path. Next, unique name for your toolbox needs +% to be defined and also prefferd API for toolbox functions +% +% elseif strcmpi(DL.toolbox,'') +% % This is an example of API that can be used: +% % - get training set from Problem part of structure +% % - assign parameters defined in the main program +% +% X = Problem.b; +% param=DL.param; +% +% % - Evaluate the function (DL.name - defined in the main) with +% % parameters given above +% +% D = eval([DL.name,'();']); + +else + printf('\nToolbox has not been registered. Please change SMALL_learn file.\n'); + return +end diff -r 775caafd5651 -r 0d30f9074dd9 config/SMALL_solve_config.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/SMALL_solve_config.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,80 @@ +%% Configuration file used in SMALL_solve +% +% Use this file to change the solvers in SMALLBox +% Please refer to the documentation before editing this file + +% Centre for Digital Music, Queen Mary, University of London. +% This file copyright 2009 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. +% +%% + +if strcmpi(solver.toolbox,'sparselab') + y = eval([solver.name,'(SparseLab_A, b, n,',solver.param,');']); +elseif strcmpi(solver.toolbox,'sparsify') + if isa(Problem.A,'float') + y = eval([solver.name,'(b, A, n,',solver.param,');']); + else + y = eval([solver.name,'(b, A, n, ''P_trans'', AT,',solver.param,');']); + end +elseif (strcmpi(solver.toolbox,'spgl1')||strcmpi(solver.toolbox,'gpsr')) + y = eval([solver.name,'(b, A,',solver.param,');']); +elseif (strcmpi(solver.toolbox,'SPAMS')) + y = eval([solver.name,'(b, A, solver.param);']); +elseif (strcmpi(solver.toolbox,'SMALL')) + if isa(Problem.A,'float') + y = eval([solver.name,'(A, b, n,',solver.param,');']); + else + y = eval([solver.name,'(A, b, n,',solver.param,',AT);']); + end +elseif (strcmpi(solver.toolbox, 'ompbox')) + G=A'*A; + epsilon=solver.param.epsilon; + maxatoms=solver.param.maxatoms; + y = eval([solver.name,'(A, b, G,epsilon,''maxatoms'',maxatoms,''checkdict'',''off'');']); +elseif (strcmpi(solver.toolbox, 'ompsbox')) + basedict = Problem.basedict; + if issparse(Problem.A) + A = Problem.A; + else + A = sparse(Problem.A); + end + G = dicttsep(basedict,A,dictsep(basedict,A,speye(size(A,2)))); + epsilon=solver.param.epsilon; + maxatoms=solver.param.maxatoms; + y = eval([solver.name,'(basedict, A, b, G,epsilon,''maxatoms'',maxatoms,''checkdict'',''off'');']); + Problem.sparse=1; +elseif (strcmpi(solver.toolbox, 'ALPS')) + if ~isa(Problem.A,'float') + % ALPS does not accept implicit dictionary definition + A = opToMatrix(Problem.A, 1); + end + [y, numiter, time, y_path] = wrapper_ALPS_toolbox(b, A, solver.param); +elseif (strcmpi(solver.toolbox, 'MMbox')) + if ~isa(Problem.A,'float') + % MMbox does not accept implicit dictionary definition + A = opToMatrix(Problem.A, 1); + end + + [y, cost] = wrapper_mm_solver(b, A, solver.param); + + % To introduce new sparse representation algorithm put the files in + % your Matlab path. Next, unique name for your toolbox and + % prefferd API needs to be defined. + % + % elseif strcmpi(solver.toolbox,'') + % + % % - Evaluate the function (solver.name - defined in the main) with + % % parameters given above + % + % y = eval([solver.name,'();']); + +else + printf('\nToolbox has not been registered. Please change SMALL_solver file.\n'); + return +end diff -r 775caafd5651 -r 0d30f9074dd9 examples/ALPS solvers tests/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepALPSandMahile.m --- a/examples/ALPS solvers tests/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepALPSandMahile.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/ALPS solvers tests/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepALPSandMahile.m Wed Apr 11 15:56:39 2012 +0100 @@ -36,7 +36,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/AudioInpainting/Audio_Declipping_Example.m --- a/examples/AudioInpainting/Audio_Declipping_Example.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/AudioInpainting/Audio_Declipping_Example.m Wed Apr 11 15:56:39 2012 +0100 @@ -24,7 +24,7 @@ % %% -clear all; +clear; % Defining the solvers to test in Audio declipping scenario % First solver omp2 - DCT+DST dictionary with no additional constraints diff -r 775caafd5651 -r 0d30f9074dd9 examples/AudioInpainting/CVX_add_const_Audio_declipping.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AudioInpainting/CVX_add_const_Audio_declipping.m Wed Apr 11 15:56:39 2012 +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; + b_ineq_neg_upper_limit = -wa_neg(:)*Problem.Upper_Limit; + 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 diff -r 775caafd5651 -r 0d30f9074dd9 examples/Automatic Music Transcription/SMALL_AMT_DL_test.m --- a/examples/Automatic Music Transcription/SMALL_AMT_DL_test.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Automatic Music Transcription/SMALL_AMT_DL_test.m Wed Apr 11 15:56:39 2012 +0100 @@ -210,7 +210,7 @@ FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'results']); [filename,pathname] = uiputfile({' *.mid;' },'Save KSVD result midi'); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Automatic Music Transcription/SMALL_AMT_KSVD_Err_test.m --- a/examples/Automatic Music Transcription/SMALL_AMT_KSVD_Err_test.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Automatic Music Transcription/SMALL_AMT_KSVD_Err_test.m Wed Apr 11 15:56:39 2012 +0100 @@ -130,7 +130,7 @@ title('False Positives vs Edata'); FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'results']); [filename,pathname] = uiputfile({' *.mid;' },'Save midi'); if filename~=0 writemidi(BLmidi, [pathname,FS,filename]);end diff -r 775caafd5651 -r 0d30f9074dd9 examples/Automatic Music Transcription/SMALL_AMT_KSVD_Sparsity_test.m --- a/examples/Automatic Music Transcription/SMALL_AMT_KSVD_Sparsity_test.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Automatic Music Transcription/SMALL_AMT_KSVD_Sparsity_test.m Wed Apr 11 15:56:39 2012 +0100 @@ -141,7 +141,7 @@ title('False Positives vs Tdata'); FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'results']); [filename,pathname] = uiputfile({' *.mid;' },'Save midi'); if filename~=0 writemidi(BLmidi, [pathname,FS,filename]);end diff -r 775caafd5651 -r 0d30f9074dd9 examples/Automatic Music Transcription/SMALL_AMT_SPAMS_test.m --- a/examples/Automatic Music Transcription/SMALL_AMT_SPAMS_test.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Automatic Music Transcription/SMALL_AMT_SPAMS_test.m Wed Apr 11 15:56:39 2012 +0100 @@ -142,7 +142,7 @@ title('False Positives vs lambda'); FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'results']); [filename,pathname] = uiputfile({' *.mid;' },'Save midi'); if filename~=0 writemidi(BLmidi, [pathname,FS,filename]);end diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLA.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLA.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLA.m Wed Apr 11 15:56:39 2012 +0100 @@ -36,7 +36,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLAvsTwoStepMOD.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLAvsTwoStepMOD.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsRLSDLAvsTwoStepMOD.m Wed Apr 11 15:56:39 2012 +0100 @@ -33,7 +33,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsSPAMS.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsSPAMS.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsSPAMS.m Wed Apr 11 15:56:39 2012 +0100 @@ -41,10 +41,10 @@ % TMPpath=pwd; % FS=filesep; -% [pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +% [pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); % cd([pathstr1,FS,'data',FS,'images']); % [filename,pathname] = uigetfile({'*.png;'},'Select a file containin pre-calculated notes'); -% [pathstr, name, ext, versn] = fileparts(filename); +% [pathstr, name, ext] = fileparts(filename); % test_image = imread(filename); % test_image = double(test_image); % cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepKSVD.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepKSVD.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_KSVDvsTwoStepKSVD.m Wed Apr 11 15:56:39 2012 +0100 @@ -36,7 +36,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_SPAMS_lambda.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_SPAMS_lambda.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_SPAMS_lambda.m Wed Apr 11 15:56:39 2012 +0100 @@ -22,15 +22,15 @@ % COPYING included with this distribution for more information. %% -clear all; +clear; %% Load an image TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); [filename,pathname] = uigetfile({'*.png;'},'Select a file containin pre-calculated notes'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); test_image = imread(filename); test_image = double(test_image); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_Training_size.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_Training_size.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_Training_size.m Wed Apr 11 15:56:39 2012 +0100 @@ -33,15 +33,15 @@ % COPYING included with this distribution for more information.%% %% -clear all; +clear; %% Load an image TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); [filename,pathname] = uigetfile({'*.png;'},'Select a file containin pre-calculated notes'); -[pathstr, name, ext, versn] = fileparts(filename); +[pathstr, name, ext] = fileparts(filename); test_image = imread(filename); test_image = double(test_image); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Image Denoising/SMALL_ImgDenoise_DL_test_TwoStep_KSVD_MOD_OLS_Mailhe.m --- a/examples/Image Denoising/SMALL_ImgDenoise_DL_test_TwoStep_KSVD_MOD_OLS_Mailhe.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Image Denoising/SMALL_ImgDenoise_DL_test_TwoStep_KSVD_MOD_OLS_Mailhe.m Wed Apr 11 15:56:39 2012 +0100 @@ -36,7 +36,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); @@ -262,7 +262,7 @@ % Setting Dictionary structure fields (toolbox, name, param, D and time) % to zero values -SMALL.DL(4)=SMALL_init_DL('TwoStepDL', 'mailhe', '', 1); +SMALL.DL(4)=SMALL_init_DL('TwoStepDL', 'opt', '', 1); % Defining the parameters for KSVD diff -r 775caafd5651 -r 0d30f9074dd9 examples/MajorizationMinimization tests/SMALL_AMT_DL_test_KSVD_MM.m --- a/examples/MajorizationMinimization tests/SMALL_AMT_DL_test_KSVD_MM.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/MajorizationMinimization tests/SMALL_AMT_DL_test_KSVD_MM.m Wed Apr 11 15:56:39 2012 +0100 @@ -254,7 +254,7 @@ FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'results']); [filename,pathname] = uiputfile({' *.mid;' },'Save KSVD result midi'); diff -r 775caafd5651 -r 0d30f9074dd9 examples/MajorizationMinimization tests/SMALL_AudioDenoise_DL_test_KSVDvsSPAMS.m --- a/examples/MajorizationMinimization tests/SMALL_AudioDenoise_DL_test_KSVDvsSPAMS.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/MajorizationMinimization tests/SMALL_AudioDenoise_DL_test_KSVDvsSPAMS.m Wed Apr 11 15:56:39 2012 +0100 @@ -4,7 +4,7 @@ % It calls generateAudioDenoiseProblem that will let you to choose audio file, % add noise and use noisy audio to generate training set for dictionary % learning. -% + % % Centre for Digital Music, Queen Mary, University of London. % This file copyright 2011 Ivan Damnjanovic. diff -r 775caafd5651 -r 0d30f9074dd9 examples/MajorizationMinimization tests/SMALL_ImgDenoise_DL_test_KSVDvsMajorizationMinimization.m --- a/examples/MajorizationMinimization tests/SMALL_ImgDenoise_DL_test_KSVDvsMajorizationMinimization.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/MajorizationMinimization tests/SMALL_ImgDenoise_DL_test_KSVDvsMajorizationMinimization.m Wed Apr 11 15:56:39 2012 +0100 @@ -37,7 +37,7 @@ clear; TMPpath=pwd; FS=filesep; -[pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m')); +[pathstr1, name, ext] = fileparts(which('SMALLboxSetup.m')); cd([pathstr1,FS,'data',FS,'images']); load('test_image.mat'); cd(TMPpath); diff -r 775caafd5651 -r 0d30f9074dd9 examples/Pierre Villars/Pierre_Villars_Example.m --- a/examples/Pierre Villars/Pierre_Villars_Example.m Wed Sep 07 14:17:55 2011 +0100 +++ b/examples/Pierre Villars/Pierre_Villars_Example.m Wed Apr 11 15:56:39 2012 +0100 @@ -19,7 +19,7 @@ % %% -clear all; +clear; % Defining the Problem structure @@ -44,14 +44,10 @@ psnr = zeros(1,n); for i=1:n - - % Set reconstruction function SMALL.Problem.reconstruct=@(x) Pierre_reconstruct(x, SMALL.Problem); - - % Defining the parameters sparse representation SMALL.solver(i)=SMALL_init_solver; SMALL.solver(i).toolbox='SMALL'; diff -r 775caafd5651 -r 0d30f9074dd9 examples/SMALL_DL_test.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SMALL_DL_test.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,76 @@ +function SMALL_DL_test +clear, clc, close all +% Create a 2-dimensional dataset of points that are oriented in 3 +% directions on a x/y plane + +% +% Centre for Digital Music, Queen Mary, University of London. +% This file copyright 2012 Daniele Barchiesi. +% +% 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. + +nData = 10000; %number of data +theta = [pi/6 pi/3 4*pi/6]; %angles +nAngles = length(theta); %number of angles +Q = [cos(theta); sin(theta)]; %rotation matrix +X = Q*randmog(nAngles,nData); %training data + +% find principal directions using PCA +XXt = X*X'; %cross correlation matrix +[U ~] = svd(XXt); %svd of XXt + +scale = 3; %scale factor for plots +subplot(1,2,1), hold on +title('Principal Component Analysis') +scatter(X(1,:), X(2,:),'.'); %scatter training data +O = zeros(size(U)); %origin +quiver(O(1,1:2),O(2,1:2),scale*U(1,:),scale*U(2,:),... + 'LineWidth',2,'Color','k') %plot atoms +axis equal %scale axis + +subplot(1,2,2), hold on +title('K-SVD Dictionary') +scatter(X(1,:), X(2,:),'.'); +axis equal + +nAtoms = 3; %number of atoms in the dictionary +nIter = 1; %number of dictionary learning iterations +initDict = normc(randn(2,nAtoms)); %random initial dictionary +O = zeros(size(initDict)); %origin + +% apply dictionary learning algorithm +ksvd_params = struct('data',X,... %training data + 'Tdata',1,... %sparsity level + 'dictsize',nAtoms,... %number of atoms + 'initdict',initDict,...%initial dictionary + 'iternum',10); %number of iterations +DL = SMALL_init_DL('ksvd','ksvd',ksvd_params); %dictionary learning structure +DL.D = initDict; %copy initial dictionary in solution variable +problem = struct('b',X); %copy training data in problem structure + +xdata = DL.D(1,:); +ydata = DL.D(2,:); +qPlot = quiver(O(1,:),O(2,:),scale*initDict(1,:),scale*initDict(2,:),... + 'LineWidth',2,'Color','k','UDataSource','xdata','VDataSource','ydata'); + +for iIter=1:nIter + DL.ksvd_params.initdict = DL.D; + pause + DL = SMALL_learn(problem,DL); %learn dictionary + xdata = scale*DL.D(1,:); + ydata = scale*DL.D(2,:); + refreshdata(gcf,'caller'); +end + + +function X = randmog(m, n) +% RANDMOG - Generate mixture of Gaussians +s = [0.2 2]; +% Choose which Gaussian +G1 = (rand(m, n) < 0.9); +% Make them +X = (G1.*s(1) + (1-G1).*s(2)) .* randn(m,n); diff -r 775caafd5651 -r 0d30f9074dd9 solvers/CVX_add_const_Audio_declipping.m --- a/solvers/CVX_add_const_Audio_declipping.m Wed Sep 07 14:17:55 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -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; - b_ineq_neg_upper_limit = -wa_neg(:)*Problem.Upper_Limit; - 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 diff -r 775caafd5651 -r 0d30f9074dd9 toolboxes/alps/wrapper_ALPS_toolbox.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/alps/wrapper_ALPS_toolbox.m Wed Apr 11 15:56:39 2012 +0100 @@ -0,0 +1,106 @@ +function [x , numiter, time, x_path] = wrapper_ALPS_toolbox(b, A, param) +%% SMALL wrapper for ALPS toolbox +% +% Function gets as input +% b - measurement vector +% A - dictionary +% K - desired sparsity level +% param - structure containing additional parameters. These are: +% - memory Memory (momentum) of proposed algorithm. +% Possible values are 0,1,'infty' for memoryless, +% one memory and infinity memory ALPS, +% respectively. Default value: memory = 0. +% - tol Early stopping tolerance. Default value: tol = +% 1-e5. +% - ALPSiters Maximum number of algorithm iterations. Default +% value: 300. +% - mod According to [1], possible values are +% [0,1,2,4,5,6]. This value comes from the binary +% representation of the parameters: +% (solveNewtob, gradientDescentx, solveNewtonx), +% which are explained next. Default value = 0. +% - mu Variable that controls the step size selection. +% When mu = 0, step size is computed adaptively +% per iteration. Default value: mu = 0. +% - tau Variable that controls the momentum in +% non-memoryless case. Ignored in memoryless +% case. User can insert as value a function handle on tau. +% Description given below. Default value: tau = -1. +% - CGiters Maximum iterations for Conjugate-Gradients method. +% - CGtol Tolerance variable for Conjugate-Gradients method. +% - verbose verbose = 1 prints out execution infromation. +% Output: +% x - sparse solution +% numiter - number of iterations +% time - time needed to solve the problem# +% x_path - matrix containing x after every iteration +% +% For more details see AlgebraicPursuit.m. + +% +% 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. +% +%% + +if isfield(param, 'sparsity') + sparsity = param.sparsity; +else + printf('\nAlebraic Pursuit algorithms require desired sparsity level.\n("sparsity" field in solver parameters structure)\n '); + return +end + +if isfield(param, 'memory') + memory = param.memory; +else + memory = 0; +end + +if isfield(param, 'mode') + mode = param.mode; +else + mode = 0; +end +if isfield(param, 'tolerance') + tolerance = param.tolerance; +else + tolerance = 1e-5; +end +if isfield(param, 'iternum') + iternum = param.iternum; +else + iternum = 300; +end +if isfield(param, 'verbose') + verbose = param.verbose; +else + verbose = 0; +end +if isfield(param, 'tau') + tau = param.tau; +else + tau = 1/2; +end +if isfield(param, 'useCG') + useCG = param.useCG; +else + useCG = 0; +end +if isfield(param, 'mu') + mu = param.mu; +else + mu = 0; +end +training_size = size(b,2); +x=zeros(size(A,2),training_size); +for i = 1:training_size + [x(:,i), numiter, time, x_path] = AlgebraicPursuit(b(:,i), A, sparsity, 'memory', memory,... + 'mode', mode, 'tolerance', tolerance, 'ALPSiterations', iternum, ... + 'verbose', verbose, 'tau', tau, 'useCG', useCG, 'mu', mu); +end \ No newline at end of file diff -r 775caafd5651 -r 0d30f9074dd9 toolboxes/wrapper_ALPS_toolbox.m --- a/toolboxes/wrapper_ALPS_toolbox.m Wed Sep 07 14:17:55 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -function [x , numiter, time, x_path] = wrapper_ALPS_toolbox(b, A, param) -%% SMALL wrapper for ALPS toolbox -% -% Function gets as input -% b - measurement vector -% A - dictionary -% K - desired sparsity level -% param - structure containing additional parameters -% Output: -% x - sparse solution -% numiter - number of iterations -% time - time needed to solve the problem# -% x_path - matrix containing x after every iteration - -% 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. -% -%% - -if isfield(param, 'sparsity') - sparsity = param.sparsity; -else - printf('\nAlebraic Pursuit algorithms require desired sparsity level.\n("sparsity" field in solver parameters structure)\n '); - return -end - -if isfield(param, 'memory') - memory = param.memory; -else - memory = 0; -end - -if isfield(param, 'mode') - mode = param.mode; -else - mode = 0; -end -if isfield(param, 'tolerance') - tolerance = param.tolerance; -else - tolerance = 1e-5; -end -if isfield(param, 'iternum') - iternum = param.iternum; -else - iternum = 300; -end -if isfield(param, 'verbose') - verbose = param.verbose; -else - verbose = 0; -end -if isfield(param, 'tau') - tau = param.tau; -else - tau = 1/2; -end -if isfield(param, 'useCG') - useCG = param.useCG; -else - useCG = 0; -end -if isfield(param, 'mu') - mu = param.mu; -else - mu = 0; -end -training_size = size(b,2); -x=zeros(size(A,2),training_size); -for i = 1:training_size - [x(:,i), numiter, time, x_path] = AlgebraicPursuit(b(:,i), A, sparsity, 'memory', memory,... - 'mode', mode, 'tolerance', tolerance, 'ALPSiterations', iternum, ... - 'verbose', verbose, 'tau', tau, 'useCG', useCG, 'mu', mu); -end \ No newline at end of file diff -r 775caafd5651 -r 0d30f9074dd9 util/SMALL_learn.m --- a/util/SMALL_learn.m Wed Sep 07 14:17:55 2011 +0100 +++ b/util/SMALL_learn.m Wed Apr 11 15:56:39 2012 +0100 @@ -1,9 +1,9 @@ function DL = SMALL_learn(Problem,DL) -%% SMALL Dictionary Learning -% -% Function gets as input Problem and Dictionary Learning (DL) structures +%% SMALL Dictionary Learning +% +% Function gets as input Problem and Dictionary Learning (DL) structures % In Problem structure field b with the training set needs to be defined -% In DL fields with name of the toolbox and solver, and parameters file +% In DL fields with name of the toolbox and solver, and parameters file % for particular dictionary learning technique needs to be present. % % Outputs are Learned dictionary and time spent as a part of DL structure @@ -18,105 +18,31 @@ % License, or (at your option) any later version. See the file % COPYING included with this distribution for more information. %% + +SMALLboxInit + if (DL.profile) - fprintf('\nStarting Dictionary Learning %s... \n', DL.name); + fprintf('\nStarting Dictionary Learning %s... \n', DL.name); end - start=cputime; - tStart=tic; - if strcmpi(DL.toolbox,'KSVD') - param=DL.param; - param.data=Problem.b; - - D = eval([DL.name,'(param)']);%, ''t'', 5);']); - elseif strcmpi(DL.toolbox,'KSVDS') - param=DL.param; - param.data=Problem.b; - - D = eval([DL.name,'(param, ''t'', 5);']); - elseif strcmpi(DL.toolbox,'SPAMS') - - X = Problem.b; - param=DL.param; - - D = eval([DL.name,'(X, param);']); - % As some versions of SPAMS does not produce unit norm column - % dictionaries, we need to make sure that columns are normalised to - % unit lenght. - - for i = 1: size(D,2) - D(:,i)=D(:,i)/norm(D(:,i)); - end - elseif strcmpi(DL.toolbox,'SMALL') - - X = Problem.b; - param=DL.param; - - D = eval([DL.name,'(X, param);']); - % we need to make sure that columns are normalised to - % unit lenght. - - for i = 1: size(D,2) - D(:,i)=D(:,i)/norm(D(:,i)); - end - - elseif strcmpi(DL.toolbox,'TwoStepDL') - - DL=SMALL_two_step_DL(Problem, DL); - - % we need to make sure that columns are normalised to - % unit lenght. - - for i = 1: size(DL.D,2) - DL.D(:,i)=DL.D(:,i)/norm(DL.D(:,i)); - end - D = DL.D; - -elseif strcmpi(DL.toolbox,'MMbox') - - DL = wrapper_mm_DL(Problem, DL); - - % we need to make sure that columns are normalised to - % unit lenght. - - for i = 1: size(DL.D,2) - DL.D(:,i)=DL.D(:,i)/norm(DL.D(:,i)); - end - D = DL.D; - -% To introduce new dictionary learning technique put the files in -% your Matlab path. Next, unique name for your toolbox needs -% to be defined and also prefferd API for toolbox functions -% -% elseif strcmpi(DL.toolbox,'') -% % This is an example of API that can be used: -% % - get training set from Problem part of structure -% % - assign parameters defined in the main program -% -% X = Problem.b; -% param=DL.param; -% -% % - Evaluate the function (DL.name - defined in the main) with -% % parameters given above -% -% D = eval([DL.name,'();']); - else - printf('\nToolbox has not been registered. Please change SMALL_learn file.\n'); - return - end - +start=cputime; +tStart=tic; + +% toolboxes configuration file +run(fullfile(SMALL_path, 'config/SMALL_learn_config.m')); + %% % Dictionary Learning time tElapsed=toc(tStart); DL.time = cputime - start; if (DL.profile) - fprintf('\n%s finished task in %2f seconds (cpu time). \n', DL.name, DL.time); - fprintf('\n%s finished task in %2f seconds (tic-toc time). \n', DL.name, tElapsed); + fprintf('\n%s finished task in %2f seconds (cpu time). \n', DL.name, DL.time); + fprintf('\n%s finished task in %2f seconds (tic-toc time). \n', DL.name, tElapsed); end DL.time=tElapsed; -% If dictionary is given as a sparse matrix change it to full +% If dictionary is given as a sparse matrix change it to full - DL.D = full(D); - +DL.D = full(D); + end - \ No newline at end of file + diff -r 775caafd5651 -r 0d30f9074dd9 util/SMALL_solve.m --- a/util/SMALL_solve.m Wed Sep 07 14:17:55 2011 +0100 +++ b/util/SMALL_solve.m Wed Apr 11 15:56:39 2012 +0100 @@ -15,9 +15,11 @@ % 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. -% +% %% +SMALLboxInit + if isa(Problem.A,'float') A = Problem.A; SparseLab_A=Problem.A; @@ -45,72 +47,9 @@ start=cputime; tStart=tic; -if strcmpi(solver.toolbox,'sparselab') - y = eval([solver.name,'(SparseLab_A, b, n,',solver.param,');']); -elseif strcmpi(solver.toolbox,'sparsify') - if isa(Problem.A,'float') - y = eval([solver.name,'(b, A, n,',solver.param,');']); - else - y = eval([solver.name,'(b, A, n, ''P_trans'', AT,',solver.param,');']); - end -elseif (strcmpi(solver.toolbox,'spgl1')||strcmpi(solver.toolbox,'gpsr')) - y = eval([solver.name,'(b, A,',solver.param,');']); -elseif (strcmpi(solver.toolbox,'SPAMS')) - y = eval([solver.name,'(b, A, solver.param);']); -elseif (strcmpi(solver.toolbox,'SMALL')) - if isa(Problem.A,'float') - y = eval([solver.name,'(A, b, n,',solver.param,');']); - else - y = eval([solver.name,'(A, b, n,',solver.param,',AT);']); - end -elseif (strcmpi(solver.toolbox, 'ompbox')) - G=A'*A; - epsilon=solver.param.epsilon; - maxatoms=solver.param.maxatoms; - y = eval([solver.name,'(A, b, G,epsilon,''maxatoms'',maxatoms,''checkdict'',''off'');']); -elseif (strcmpi(solver.toolbox, 'ompsbox')) - basedict = Problem.basedict; - if issparse(Problem.A) - A = Problem.A; - else - A = sparse(Problem.A); - end - G = dicttsep(basedict,A,dictsep(basedict,A,speye(size(A,2)))); - epsilon=solver.param.epsilon; - maxatoms=solver.param.maxatoms; - y = eval([solver.name,'(basedict, A, b, G,epsilon,''maxatoms'',maxatoms,''checkdict'',''off'');']); - Problem.sparse=1; -elseif (strcmpi(solver.toolbox, 'ALPS')) - if ~isa(Problem.A,'float') - % ALPS does not accept implicit dictionary definition - A = opToMatrix(Problem.A, 1); - end - [y, numiter, time, y_path] = wrapper_ALPS_toolbox(b, A, solver.param); -elseif (strcmpi(solver.toolbox, 'MMbox')) - if ~isa(Problem.A,'float') - % MMbox does not accept implicit dictionary definition - A = opToMatrix(Problem.A, 1); - end - - [y, cost] = wrapper_mm_solver(b, A, solver.param); - - - - % To introduce new sparse representation algorithm put the files in - % your Matlab path. Next, unique name for your toolbox and - % prefferd API needs to be defined. - % - % elseif strcmpi(solver.toolbox,'') - % - % % - Evaluate the function (solver.name - defined in the main) with - % % parameters given above - % - % y = eval([solver.name,'();']); - -else - printf('\nToolbox has not been registered. Please change SMALL_solver file.\n'); - return -end + +% solvers configuration file +run(fullfile(SMALL_path, 'config/SMALL_solve_config.m')); %% % Sparse representation time