Mercurial > hg > camir-aes2014
comparison toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mirsimatrix/mirsimatrix.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function varargout = mirsimatrix(orig,varargin) | |
2 % m = mirsimatrix(x) computes the similarity matrix resulting from the | |
3 % mutual comparison between each possible frame analysis in x. | |
4 % By default, x is the spectrum of the frame decomposition. | |
5 % But it can be any other frame analysis. | |
6 % Optional argument: | |
7 % mirsimatrix(...,'Distance',f) specifies the name of a distance | |
8 % function, from those proposed in the Statistics Toolbox | |
9 % (help pdist). | |
10 % default value: f = 'cosine' | |
11 % mirsimatrix(...,'Dissimilarity') return the dissimilarity matrix, | |
12 % which is the intermediary result before the computation of the | |
13 % actual similarity matrix. It shows the distance between each | |
14 % possible frame analysis in x. | |
15 % mirsimatrix(...,'Similarity',f) indicates the function f specifying | |
16 % the way the distance values in the dissimilarity matrix are | |
17 % transformed into similarity values. | |
18 % Possible values: | |
19 % f = 'oneminus' (default value) | |
20 % corresponding to f(x) = 1-x | |
21 % f = 'exponential' | |
22 % corresponding to f(x)= exp(-x) | |
23 % mirsimatrix(...,'Width',w) or more simply dissimatrix(...,w) | |
24 % specifies the size of the diagonal bandwidth, in samples, | |
25 % outside which the dissimilarity will not be computed. | |
26 % if w = inf (default value), all the matrix will be computed. | |
27 % mirsimatrix(...,'Horizontal') rotates the matrix 45 degrees in order to | |
28 % make the first diagonal horizontal, and to restrict on the | |
29 % diagonal bandwidth only. | |
30 % mirsimatrix(...,'TimeLag') transforms the (non-rotated) matrix into | |
31 % a time-lag matrix, making the first diagonal horizontal as well | |
32 % (corresponding to the zero-lag line). | |
33 % | |
34 % mirsimatrix(M,r) creates a mirsimatrix similarity matrix based on | |
35 % the Matlab square matrix M, of frame rate r (in Hz.) | |
36 % By default r = 20 Hz. | |
37 % mirsimatrix(M,r,'Dissimilarity') creates instead a mirsimatrix | |
38 % dissimilarity matrix. | |
39 % | |
40 % Foote, J. & Cooper, M. (2003). Media Segmentation using Self-Similarity | |
41 % Decomposition,. In Proc. SPIE Storage and Retrieval for Multimedia | |
42 % Databases, Vol. 5021, pp. 167-75. | |
43 | |
44 % mirsimatrix(...,'Filter',10) filter along the diagonal of the matrix, | |
45 % using a uniform moving average filter of size f. The result is | |
46 % represented in a time-lag matrix. | |
47 | |
48 | |
49 distance.key = 'Distance'; | |
50 distance.type = 'String'; | |
51 distance.default = 'cosine'; | |
52 option.distance = distance; | |
53 | |
54 simf.key = 'Similarity'; | |
55 simf.type = 'String'; | |
56 simf.default = 'oneminus'; | |
57 simf.keydefault = 'Similarity'; | |
58 simf.when = 'After'; | |
59 option.simf = simf; | |
60 | |
61 dissim.key = 'Dissimilarity'; | |
62 dissim.type = 'Boolean'; | |
63 dissim.default = 0; | |
64 option.dissim = dissim; | |
65 | |
66 K.key = 'Width'; | |
67 K.type = 'Integer'; | |
68 K.default = Inf; | |
69 option.K = K; | |
70 | |
71 filt.key = 'Filter'; | |
72 filt.type = 'Integer'; | |
73 filt.default = 0; | |
74 filt.when = 'After'; | |
75 option.filt = filt; | |
76 | |
77 view.type = 'String'; | |
78 view.default = 'Standard'; | |
79 view.choice = {'Standard','Horizontal','TimeLag'}; | |
80 view.when = 'After'; | |
81 option.view = view; | |
82 | |
83 rate.type = 'Integer'; | |
84 rate.position = 2; | |
85 rate.default = 20; | |
86 option.rate = rate; | |
87 | |
88 specif.option = option; | |
89 specif.nochunk = 1; | |
90 varargout = mirfunction(@mirsimatrix,orig,varargin,nargout,specif,@init,@main); | |
91 | |
92 | |
93 function [x type] = init(x,option) | |
94 if isnumeric(x) | |
95 m.diagwidth = Inf; | |
96 m.view = 's'; | |
97 m.similarity = NaN; | |
98 m.graph = {}; | |
99 m.branch = {}; | |
100 m = class(m,'mirsimatrix',mirdata); | |
101 m = set(m,'Title','Dissimilarity matrix'); | |
102 fp = repmat(((1:size(x,1))-.5)/option.rate,[2,1]); | |
103 x = set(m,'Data',{x},'Pos',[],... | |
104 'FramePos',{{fp}},'Name',{inputname(1)}); | |
105 else | |
106 if not(isamir(x,'mirsimatrix')) | |
107 if (isamir(x,'miraudio')) | |
108 if isframed(x) | |
109 x = mirspectrum(x); | |
110 else | |
111 x = mirspectrum(x,'Frame',0.05,1); | |
112 end | |
113 end | |
114 end | |
115 end | |
116 type = 'mirsimatrix'; | |
117 | |
118 | |
119 function m = main(orig,option,postoption) | |
120 if iscell(orig) | |
121 orig = orig{1}; | |
122 end | |
123 if isa(orig,'mirsimatrix') | |
124 d = get(orig,'Data'); | |
125 for k = 1:length(d) | |
126 if iscell(option) && isfield(option,'K') && option.K < orig.diagwidth | |
127 nl = size(d{k},1); | |
128 if strcmp(orig.view,'h') | |
129 dl = (nl - option.K)/2; | |
130 dk = d{k}(ceil(dl):nl-floor(dl),:); | |
131 else | |
132 [spA,spd] = spdiags(d{k},-ceil(option.K/2):ceil(option.K/2)); | |
133 dk = full(spdiags(spA,spd,nl,size(d{k},2))); | |
134 end | |
135 d{k} = dk; | |
136 orig.diagwidth = option.K; | |
137 end | |
138 end | |
139 m = set(orig,'Data',d); | |
140 else | |
141 v = get(orig,'Data'); | |
142 d = cell(1,length(v)); | |
143 for k = 1:length(v) | |
144 vk = v{k}; | |
145 if mirwaitbar | |
146 handle = waitbar(0,'Computing dissimilarity matrix...'); | |
147 else | |
148 handle = 0; | |
149 end | |
150 if 0 %iscell(vk) | |
151 try | |
152 vk = cell2mat(vk); | |
153 end | |
154 end | |
155 if 0 %iscell(vk) %&& length(vk) > 1 %%% ATTENTION KL!!<<<<<<<<<<<< | |
156 l = length(vk); | |
157 dk = NaN(l,l); | |
158 hK = floor(option.K/2); | |
159 for i = 1:l | |
160 if handle | |
161 waitbar(i/l,handle); | |
162 end | |
163 for j = max(1,i-hK):min(l,i+hK) | |
164 dk(i,j) = KL(vk{i},vk{j}); | |
165 end | |
166 end | |
167 else | |
168 if not(iscell(vk)) | |
169 vk = {vk}; | |
170 end | |
171 for z = 1:length(vk) | |
172 vz = vk{z}; | |
173 ll = size(vz,1); | |
174 l = size(vz,2); | |
175 nc = size(vz,3); | |
176 if ll==1 && nc>1 | |
177 vz = squeeze(vz)'; | |
178 ll = nc; | |
179 nc = 1; | |
180 end | |
181 nd = size(vz,4); | |
182 if not(isempty(postoption)) && ... | |
183 strcmpi(postoption.view,'TimeLag') | |
184 lK = ceil(option.K/2); | |
185 if isinf(lK) | |
186 lK = l; | |
187 end | |
188 dk{z} = NaN(lK,l,nc); | |
189 else | |
190 dk{z} = NaN(l,l,nc); | |
191 end | |
192 for g = 1:nc | |
193 if nd == 1 | |
194 vv = vz; | |
195 else | |
196 vv = zeros(ll*nd,l); | |
197 for h = 1:nd | |
198 if iscell(vz) | |
199 for i = 1:ll | |
200 for j = 1:l | |
201 vj = vz{i,j,g,h}; | |
202 if isempty(vj) | |
203 vv((h-1)*ll+i,j) = NaN; | |
204 else | |
205 vv((h-1)*ll+i,j) = vj; | |
206 end | |
207 end | |
208 end | |
209 else | |
210 tic | |
211 vv((h-1)*ll+1:h*ll,:) = vz(:,:,g,h); | |
212 toc | |
213 end | |
214 end | |
215 end | |
216 if isinf(option.K) && not(strcmpi(postoption.view,'TimeLag')) | |
217 try | |
218 manually = 0; | |
219 dk{z}(:,:,g) = squareform(pdist(vv',option.distance)); | |
220 if option.K < Inf | |
221 [spA,spd] = spdiags(dk{z},... | |
222 -ceil(option.K/2):ceil(option.K/2)); | |
223 dk{z}(:,:,g) = full(spdiags(spA,spd,size(dk,1),size(dk{z},2))); | |
224 end | |
225 catch | |
226 %err = lasterror; | |
227 %warning(err.message) | |
228 %disp('Statistics Toolbox does not seem to be | |
229 %installed. Recompute the distance matrix manually.'); | |
230 manually = 1; | |
231 end | |
232 else | |
233 manually = 1; | |
234 end | |
235 if manually | |
236 disf = str2func(option.distance); | |
237 if strcmpi(option.distance,'cosine') | |
238 for i = 1:l | |
239 vv(:,i) = vv(:,i)/norm(vv(:,i)); | |
240 end | |
241 end | |
242 if not(isempty(postoption)) && ... | |
243 strcmpi(postoption.view,'TimeLag') | |
244 lK = ceil(option.K/2); | |
245 for i = 1:l | |
246 if mirwaitbar && (mod(i,100) == 1 || i == l) | |
247 waitbar(i/l,handle); | |
248 end | |
249 ij = min(i+lK-1,l); | |
250 dkij = disf(vv(:,i),vv(:,i:ij)); | |
251 for j = 1:ij-i+1 | |
252 dk{z}(j,i+j-1,g) = dkij(j); | |
253 end | |
254 end | |
255 else | |
256 for i = 1:l | |
257 if mirwaitbar && (mod(i,100) == 1 || i == l) | |
258 waitbar(i/l,handle); | |
259 end | |
260 j = min(i+option.K-1,l); | |
261 dkij = disf(vv(:,i),vv(:,i:j)); | |
262 dk{z}(i,i:j,g) = dkij; | |
263 dk{z}(i:j,i,g) = dkij'; | |
264 end | |
265 end | |
266 end | |
267 end | |
268 end | |
269 end | |
270 d{k} = dk; | |
271 if handle | |
272 delete(handle) | |
273 end | |
274 end | |
275 m.diagwidth = option.K; | |
276 if not(isempty(postoption)) && strcmpi(postoption.view,'TimeLag') | |
277 m.view = 'l'; | |
278 else | |
279 m.view = 's'; | |
280 end | |
281 m.similarity = 0; | |
282 m.graph = {}; | |
283 m.branch = {}; | |
284 m = class(m,'mirsimatrix',mirdata(orig)); | |
285 m = purgedata(m); | |
286 m = set(m,'Title','Dissimilarity matrix'); | |
287 m = set(m,'Data',d,'Pos',[]); | |
288 end | |
289 if not(isempty(postoption)) | |
290 if strcmpi(m.view,'s') | |
291 if strcmpi(postoption.view,'Horizontal') | |
292 for k = 1:length(d) | |
293 for z = 1:length(d{k}) | |
294 d{k}{z} = rotatesim(d{k}{z},m.diagwidth); | |
295 if option.K < m.diagwidth | |
296 W = size(d{k}{z},1); | |
297 hW = ceil(W/2); | |
298 hK = ceil(option.K/2); | |
299 d{k}{z} = d{k}{z}(hW-hK:hW+hK,:); | |
300 m.diagwidth = option.K; | |
301 end | |
302 end | |
303 end | |
304 m = set(m,'Data',d); | |
305 m.view = 'h'; | |
306 elseif strcmpi(postoption.view,'TimeLag') || postoption.filt | |
307 W = ceil(m.diagwidth/2); | |
308 for k = 1:length(d) | |
309 for z = 1:length(d{k}) | |
310 if isinf(W) | |
311 dz = NaN(size(d{k}{z})); | |
312 else | |
313 dz = NaN(W,size(d{k}{z},2)); | |
314 end | |
315 for l = 1:size(dz,1) | |
316 dz(l,l:end) = diag(d{k}{z},l-1)'; | |
317 end | |
318 if option.K < m.diagwidth | |
319 dz = dz(1:ceil(option.K/2),:); | |
320 m.diagwidth = option.K; | |
321 end | |
322 d{k}{z}= dz; | |
323 end | |
324 end | |
325 m = set(m,'Data',d); | |
326 m.view = 'l'; | |
327 end | |
328 end | |
329 if ischar(postoption.simf) | |
330 if strcmpi(postoption.simf,'Similarity') | |
331 if not(isequal(m.similarity,NaN)) | |
332 option.dissim = 0; | |
333 end | |
334 postoption.simf = 'oneminus'; | |
335 end | |
336 if isequal(m.similarity,0) && isstruct(option) ... | |
337 && isfield(option,'dissim') && not(option.dissim) | |
338 simf = str2func(postoption.simf); | |
339 for k = 1:length(d) | |
340 for z = 1:length(d{k}) | |
341 d{k}{z} = simf(d{k}{z}); | |
342 end | |
343 end | |
344 m.similarity = postoption.simf; | |
345 m = set(m,'Title','Similarity matrix','Data',d); | |
346 elseif length(m.similarity) == 1 && isnan(m.similarity) ... | |
347 && option.dissim | |
348 m.similarity = 0; | |
349 end | |
350 end | |
351 if postoption.filt | |
352 fp = get(m,'FramePos'); | |
353 for k = 1:length(d) | |
354 for z = 1:length(d{k}) | |
355 dz = filter(ones(postoption.filt,1),1,d{k}{z}); | |
356 d{k}{z} = dz(postoption.filt:end,1:end-postoption.filt+1); | |
357 fp{k}{z} = [fp{k}{z}(1,1:end-postoption.filt+1);... | |
358 fp{k}{z}(1,postoption.filt:end)]; | |
359 end | |
360 end | |
361 m = set(m,'Data',d,'FramePos',fp); | |
362 end | |
363 end | |
364 | |
365 | |
366 function S = rotatesim(d,K) | |
367 if length(d) == 1; | |
368 S = d; | |
369 else | |
370 K = min(K,size(d,1)*2); | |
371 lK = floor(K/2); | |
372 S = NaN(K,size(d,2),size(d,3)); | |
373 for k = 1:size(d,3) | |
374 for j = -lK:lK | |
375 S(lK+1+j,:,k) = [NaN(1,floor(abs(j)/2)) diag(d(:,:,k),j)' ... | |
376 NaN(1,ceil(abs(j)/2))]; | |
377 end | |
378 end | |
379 end | |
380 | |
381 function d = cosine(r,s) | |
382 d = 1-r'*s; | |
383 %nr = sqrt(r'*r); | |
384 %ns = sqrt(s'*s); | |
385 %if or(nr == 0, ns == 0); | |
386 % d = 1; | |
387 %else | |
388 % d = 1 - r'*s/nr/ns; | |
389 %end | |
390 | |
391 | |
392 function d = KL(x,y) | |
393 % Kullback-Leibler distance | |
394 if size(x,4)>1 | |
395 x(end+1:2*end,:,:,1) = x(:,:,:,2); | |
396 x(:,:,:,2) = []; | |
397 end | |
398 if size(y,4)>1 | |
399 y(end+1:2*end,:,:,1) = y(:,:,:,2); | |
400 y(:,:,:,2) = []; | |
401 end | |
402 m1 = mean(x); | |
403 m2 = mean(y); | |
404 S1 = cov(x); | |
405 S2 = cov(y); | |
406 d = (trace(S1/S2)+trace(S2/S1)+(m1-m2)'*inv(S1+S2)*(m1-m2))/2 - size(S1,1); | |
407 | |
408 | |
409 function s = exponential(d) | |
410 s = exp(-d); | |
411 | |
412 | |
413 function s = oneminus(d) | |
414 s = 1-d; |