ivan@140
|
1 function gamma = omp2Gabor(varargin)
|
ivan@140
|
2 %% omp2Gabor Error-constrained Orthogonal Matching Pursuit.
|
ivan@140
|
3 %
|
ivan@140
|
4 % This file is part of SMALLbox [2] and it is adaptation of Ron
|
ivan@140
|
5 % Rubenstein omp solver [1] for Gabor dictionary as defined in
|
ivan@140
|
6 % Audio Inpainting by Adler et al [3]. The dictionary is presented as
|
ivan@140
|
7 % DCT+DST and solver pics two atoms per iteration (given the frequency one
|
ivan@140
|
8 % from DCT and one from DST). For more information look in [3].
|
ivan@140
|
9 %
|
ivan@140
|
10 % GAMMA = OMP2(D,X,G,EPSILON) solves the optimization problem
|
ivan@140
|
11 %
|
ivan@140
|
12 % min |GAMMA|_0 s.t. |X - D*GAMMA|_2 <= EPSILON
|
ivan@140
|
13 % gamma
|
ivan@140
|
14 %
|
ivan@140
|
15 % for each of the signals in X, using Batch Orthogonal Matching Pursuit.
|
ivan@140
|
16 % Here, D is a dictionary with normalized columns, X is a matrix
|
ivan@140
|
17 % containing column signals, EPSILON is the error target for each signal,
|
ivan@140
|
18 % and G is the Gramm matrix D'*D. The output GAMMA is a matrix containing
|
ivan@140
|
19 % the sparse representations as its columns.
|
ivan@140
|
20 %
|
ivan@140
|
21 % GAMMA = OMP2(D,X,[],EPSILON) performs the same operation, but without
|
ivan@140
|
22 % the matrix G, using OMP-Cholesky. This call produces the same output as
|
ivan@140
|
23 % Batch-OMP, but is significantly slower. Using this syntax is only
|
ivan@140
|
24 % recommended when available memory is too small to store G.
|
ivan@140
|
25 %
|
ivan@140
|
26 % GAMMA = OMP2(DtX,XtX,G,EPSILON) is the fastest implementation of OMP2,
|
ivan@140
|
27 % but also requires the most memory. Here, DtX stores the projections
|
ivan@140
|
28 % D'*X, and XtX is a row vector containing the squared norms of the
|
ivan@140
|
29 % signals, sum(X.*X). In this case Batch-OMP is used, but without having
|
ivan@140
|
30 % to compute D'*X and XtX in advance, which slightly improves runtime.
|
ivan@140
|
31 % Note that in general, the call
|
ivan@140
|
32 %
|
ivan@140
|
33 % GAMMA = OMP2(D'*X, sum(X.*X), G, EPSILON);
|
ivan@140
|
34 %
|
ivan@140
|
35 % will be faster than the call
|
ivan@140
|
36 %
|
ivan@140
|
37 % GAMMA = OMP2(D,X,G,EPSILON);
|
ivan@140
|
38 %
|
ivan@140
|
39 % due to optimized matrix multiplications in Matlab. However, when the
|
ivan@140
|
40 % entire matrix D'*X cannot be stored in memory, one of the other two
|
ivan@140
|
41 % versions can be used. Both compute D'*X for just one signal at a time,
|
ivan@140
|
42 % and thus require much less memory.
|
ivan@140
|
43 %
|
ivan@140
|
44 % GAMMA = OMP2(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional
|
ivan@140
|
45 % parameters for OMP2. Available parameters are:
|
ivan@140
|
46 %
|
ivan@140
|
47 % 'gammamode' - Specifies the representation mode for GAMMA. Can be
|
ivan@140
|
48 % either 'full' or 'sparse', corresponding to a full or
|
ivan@140
|
49 % sparse matrix, respectively. By default, GAMMA is
|
ivan@140
|
50 % returned as a sparse matrix.
|
ivan@140
|
51 % 'maxatoms' - Limits the number of atoms in the representation of each
|
ivan@140
|
52 % signal. If specified, the number of atoms in each
|
ivan@140
|
53 % representation does not exceed this number, even if the
|
ivan@140
|
54 % error target is not met. Specifying maxatoms<0 implies
|
ivan@140
|
55 % no limit (default).
|
ivan@140
|
56 % 'messages' - Specifies whether progress messages should be displayed.
|
ivan@140
|
57 % When positive, this is the number of seconds between
|
ivan@140
|
58 % status prints. When negative, indicates that no messages
|
ivan@140
|
59 % should be displayed (this is the default).
|
ivan@140
|
60 % 'checkdict' - Specifies whether dictionary normalization should be
|
ivan@140
|
61 % verified. When set to 'on' (default) the dictionary
|
ivan@140
|
62 % atoms are verified to be of unit L2-norm. Setting this
|
ivan@140
|
63 % parameter to 'off' disables verification and accelerates
|
ivan@140
|
64 % function performance. Note that an unnormalized
|
ivan@140
|
65 % dictionary will produce invalid results.
|
ivan@140
|
66 % 'profile' - Can be either 'on' or 'off'. When 'on', profiling
|
ivan@140
|
67 % information is displayed at the end of the funciton
|
ivan@140
|
68 % execution.
|
ivan@140
|
69 %
|
ivan@140
|
70 %
|
ivan@140
|
71 % Summary of OMP2 versions:
|
ivan@140
|
72 %
|
ivan@140
|
73 % version | speed | memory
|
ivan@140
|
74 % -------------------------------------------------------------
|
ivan@140
|
75 % OMP2(DtX,XtX,G,EPSILON) | very fast | very large
|
ivan@140
|
76 % OMP2(D,X,G,EPSILON) | fast | moderate
|
ivan@140
|
77 % OMP2(D,X,[],EPSILON) | very slow | small
|
ivan@140
|
78 % -------------------------------------------------------------
|
ivan@140
|
79 %
|
ivan@140
|
80 %
|
ivan@140
|
81 % References:
|
ivan@140
|
82 % [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation
|
ivan@140
|
83 % of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit",
|
ivan@140
|
84 % Technical Report - CS, Technion, April 2008.
|
ivan@140
|
85 %
|
ivan@140
|
86 % See also OMP.
|
ivan@140
|
87
|
ivan@140
|
88
|
ivan@140
|
89 % Ron Rubinstein
|
ivan@140
|
90 % Computer Science Department
|
ivan@140
|
91 % Technion, Haifa 32000 Israel
|
ivan@140
|
92 % ronrubin@cs
|
ivan@140
|
93 %
|
ivan@140
|
94 % April 2009
|
ivan@140
|
95
|
ivan@140
|
96 %
|
ivan@140
|
97 % Centre for Digital Music, Queen Mary, University of London.
|
ivan@140
|
98 % This file copyright 2011 Ivan Damnjanovic.
|
ivan@140
|
99 %
|
ivan@140
|
100 % This program is free software; you can redistribute it and/or
|
ivan@140
|
101 % modify it under the terms of the GNU General Public License as
|
ivan@140
|
102 % published by the Free Software Foundation; either version 2 of the
|
ivan@140
|
103 % License, or (at your option) any later version. See the file
|
ivan@140
|
104 % COPYING included with this distribution for more information.
|
ivan@140
|
105 %%
|
ivan@140
|
106
|
ivan@140
|
107 % default options
|
ivan@140
|
108
|
ivan@140
|
109 sparse_gamma = 1;
|
ivan@140
|
110 msgdelta = -1;
|
ivan@140
|
111 maxatoms = -1;
|
ivan@140
|
112 checkdict = 1;
|
ivan@140
|
113 profile = 0;
|
ivan@140
|
114
|
ivan@140
|
115
|
ivan@140
|
116 % determine number of parameters
|
ivan@140
|
117
|
ivan@140
|
118 paramnum = 1;
|
ivan@140
|
119 while (paramnum<=nargin && ~ischar(varargin{paramnum}))
|
ivan@140
|
120 paramnum = paramnum+1;
|
ivan@140
|
121 end
|
ivan@140
|
122 paramnum = paramnum-1;
|
ivan@140
|
123
|
ivan@140
|
124
|
ivan@140
|
125 % parse options
|
ivan@140
|
126
|
ivan@140
|
127 for i = paramnum+1:2:length(varargin)
|
ivan@140
|
128 paramname = varargin{i};
|
ivan@140
|
129 paramval = varargin{i+1};
|
ivan@140
|
130
|
ivan@140
|
131 switch lower(paramname)
|
ivan@140
|
132
|
ivan@140
|
133 case 'gammamode'
|
ivan@140
|
134 if (strcmpi(paramval,'sparse'))
|
ivan@140
|
135 sparse_gamma = 1;
|
ivan@140
|
136 elseif (strcmpi(paramval,'full'))
|
ivan@140
|
137 sparse_gamma = 0;
|
ivan@140
|
138 else
|
ivan@140
|
139 error('Invalid GAMMA mode');
|
ivan@140
|
140 end
|
ivan@140
|
141
|
ivan@140
|
142 case 'maxatoms'
|
ivan@140
|
143 maxatoms = paramval;
|
ivan@140
|
144
|
ivan@140
|
145 case 'messages'
|
ivan@140
|
146 msgdelta = paramval;
|
ivan@140
|
147
|
ivan@140
|
148 case 'checkdict'
|
ivan@140
|
149 if (strcmpi(paramval,'on'))
|
ivan@140
|
150 checkdict = 1;
|
ivan@140
|
151 elseif (strcmpi(paramval,'off'))
|
ivan@140
|
152 checkdict = 0;
|
ivan@140
|
153 else
|
ivan@140
|
154 error('Invalid checkdict option');
|
ivan@140
|
155 end
|
ivan@140
|
156
|
ivan@140
|
157 case 'profile'
|
ivan@140
|
158 if (strcmpi(paramval,'on'))
|
ivan@140
|
159 profile = 1;
|
ivan@140
|
160 elseif (strcmpi(paramval,'off'))
|
ivan@140
|
161 profile = 0;
|
ivan@140
|
162 else
|
ivan@140
|
163 error('Invalid profile mode');
|
ivan@140
|
164 end
|
ivan@140
|
165
|
ivan@140
|
166 otherwise
|
ivan@140
|
167 error(['Unknown option: ' paramname]);
|
ivan@140
|
168 end
|
ivan@140
|
169
|
ivan@140
|
170 end
|
ivan@140
|
171
|
ivan@140
|
172
|
ivan@140
|
173 % determine call type
|
ivan@140
|
174
|
ivan@140
|
175 if (paramnum==4)
|
ivan@140
|
176
|
ivan@140
|
177 n1 = size(varargin{1},1);
|
ivan@140
|
178 n2 = size(varargin{2},1);
|
ivan@140
|
179 n3 = size(varargin{3},1);
|
ivan@140
|
180
|
ivan@140
|
181 if ( (n1>1 && n2==1) || (n1==1 && n2==1 && n3==1) ) % DtX,XtX,G,EPSILON
|
ivan@140
|
182
|
ivan@140
|
183 DtX = varargin{1};
|
ivan@140
|
184 XtX = varargin{2};
|
ivan@140
|
185 G = varargin{3};
|
ivan@140
|
186 epsilon = varargin{4};
|
ivan@140
|
187 D = [];
|
ivan@140
|
188 X = [];
|
ivan@140
|
189
|
ivan@140
|
190 else % D,X,G,EPSILON
|
ivan@140
|
191
|
ivan@140
|
192 D = varargin{1};
|
ivan@140
|
193 X = varargin{2};
|
ivan@140
|
194 G = varargin{3};
|
ivan@140
|
195 epsilon = varargin{4};
|
ivan@140
|
196 DtX = [];
|
ivan@140
|
197 XtX = [];
|
ivan@140
|
198
|
ivan@140
|
199 end
|
ivan@140
|
200
|
ivan@140
|
201 else
|
ivan@140
|
202 error('Invalid number of parameters');
|
ivan@140
|
203 end
|
ivan@140
|
204
|
ivan@140
|
205 G=[];
|
ivan@140
|
206
|
ivan@140
|
207 % verify dictionary normalization
|
ivan@140
|
208
|
ivan@140
|
209 if (checkdict)
|
ivan@140
|
210 if (isempty(G))
|
ivan@140
|
211 atomnorms = sum(D.*D);
|
ivan@140
|
212 else
|
ivan@140
|
213 atomnorms = diag(G);
|
ivan@140
|
214 end
|
ivan@140
|
215 if (any(abs(atomnorms-1) > 1e-2))
|
ivan@140
|
216 error('Dictionary columns must be normalized to unit length');
|
ivan@140
|
217 end
|
ivan@140
|
218 end
|
ivan@140
|
219
|
ivan@140
|
220
|
ivan@140
|
221 % omp
|
ivan@140
|
222
|
ivan@140
|
223 gamma = omp2mexGabor(D,X,DtX,XtX,G,epsilon,sparse_gamma,msgdelta,maxatoms,profile);
|