annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirdist.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function d = mirdist(x,y,dist)
wolffd@0 2 % d = mirdist(x,y) evaluates the distance between x and y.
wolffd@0 3 % x is the feature values corresponding to one audio file, and y is the
wolffd@0 4 % values (for the same feature) corrdponding to one (or several)
wolffd@0 5 % audio files.
wolffd@0 6 % If x and y are not decomposed into frames,
wolffd@0 7 % d = mirdist(x,y,f) specifies distance function.
wolffd@0 8 % Default value: f = 'Cosine'
wolffd@0 9 % If x and y are composed of clustered frames (using mircluster), the
wolffd@0 10 % cluster signatures are compared using Earth Mover Distance.
wolffd@0 11 % (Logan, Salomon, 2001)
wolffd@0 12 % If x and y contains peaks, the vectors representing the peak
wolffd@0 13 % distributions are compared using Euclidean distance.
wolffd@0 14 % (used with mirnovelty in Jacobson, 2006)
wolffd@0 15 %
wolffd@0 16 % The Earth Mover Distance is based on the implementation by Yossi Rubner,
wolffd@0 17 % wrapped for Matlab by Elias Pampalk.
wolffd@0 18
wolffd@0 19 if not(isa(x,'mirdata'))
wolffd@0 20 x = miraudio(x);
wolffd@0 21 end
wolffd@0 22 if not(isa(y,'mirdata'))
wolffd@0 23 y = miraudio(y);
wolffd@0 24 end
wolffd@0 25
wolffd@0 26 clx = get(x,'Clusters');
wolffd@0 27 if isempty(clx{1})
wolffd@0 28 px = get(x,'PeakPos');
wolffd@0 29 if not(iscell(px)) || isempty(px{1}) || ...
wolffd@0 30 not(iscell(px{1})) || isempty(px{1}{1}) || not(iscell(px{1}{1}))
wolffd@0 31 if nargin < 3
wolffd@0 32 dist = 'Cosine';
wolffd@0 33 end
wolffd@0 34
wolffd@0 35 d = get(x,'Data');
wolffd@0 36 dd = d{1}{1};
wolffd@0 37 if iscell(dd)
wolffd@0 38 dd = dd{1};
wolffd@0 39 end
wolffd@0 40 if size(dd,2)>1
wolffd@0 41 if size(dd,1)>1
wolffd@0 42 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.');
wolffd@0 43 else
wolffd@0 44 dd = dd';
wolffd@0 45 end
wolffd@0 46 end
wolffd@0 47
wolffd@0 48 e = get(y,'Data');
wolffd@0 49 dt = cell(1,length(e));
wolffd@0 50 for h = 1:length(e)
wolffd@0 51 ee = e{h}{1};
wolffd@0 52 if iscell(ee)
wolffd@0 53 ee = ee{1};
wolffd@0 54 end
wolffd@0 55 if size(ee,2)>1
wolffd@0 56 if size(ee,1)>1
wolffd@0 57 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.');
wolffd@0 58 else
wolffd@0 59 ee = ee';
wolffd@0 60 end
wolffd@0 61 end
wolffd@0 62 if isempty(ee)
wolffd@0 63 if isempty(dd)
wolffd@0 64 dt{h}{1} = 0;
wolffd@0 65 else
wolffd@0 66 dt{h}{1} = Inf;
wolffd@0 67 end
wolffd@0 68 else
wolffd@0 69 if length(dd)<length(ee)
wolffd@0 70 dd(length(ee)) = 0;
wolffd@0 71 %ee = ee(1:length(d));
wolffd@0 72 elseif length(ee)<length(dd)
wolffd@0 73 ee(length(dd)) = 0;
wolffd@0 74 %dd = dd(1:length(ee));
wolffd@0 75 end
wolffd@0 76 if length(dd) == 1
wolffd@0 77 dt{h}{1} = abs(dd-ee);
wolffd@0 78 elseif norm(dd) && norm(ee)
wolffd@0 79 dt{h}{1} = pdist([dd(:)';ee(:)'],dist);
wolffd@0 80 else
wolffd@0 81 dt{h}{1} = NaN;
wolffd@0 82 end
wolffd@0 83 end
wolffd@0 84 end
wolffd@0 85 else
wolffd@0 86 % Euclidean distance between vectors to compare data with peaks
wolffd@0 87 % (used with mirnovelty in Jacobson, 2006).
wolffd@0 88 sig = pi/4;
wolffd@0 89 dx = get(x,'Data');
wolffd@0 90 nx = length(px{1}{1}{1});
wolffd@0 91 cx = mean(px{1}{1}{1}/length(dx{1}{1}));
wolffd@0 92 dy = get(y,'Data');
wolffd@0 93 py = get(y,'PeakPos');
wolffd@0 94 dt = cell(1,length(py));
wolffd@0 95 for h = 1:length(py)
wolffd@0 96 ny = length(py{h}{1}{1});
wolffd@0 97 cy = mean(py{h}{1}{1}/length(dy{h}{1}));
wolffd@0 98 dt{h}{1} = sqrt((nx*cos(sig*cx)-ny*cos(sig*cy))^2 ...
wolffd@0 99 +(nx*sin(sig*cx)-ny*sin(sig*cy))^2);
wolffd@0 100 end
wolffd@0 101 end
wolffd@0 102 else
wolffd@0 103 % Earth Mover's Distance to compare clustered data.
wolffd@0 104 cly = get(y,'Clusters');
wolffd@0 105 dt = cell(1,length(cly));
wolffd@0 106 for h = 1:length(cly)
wolffd@0 107 cost = zeros(length(clx{1}.weight),length(cly{h}.weight));
wolffd@0 108 for i = 1:length(clx{1}.weight)
wolffd@0 109 for j = 1:length(cly{h}.weight)
wolffd@0 110 covx = clx{1}.covar(:,i);
wolffd@0 111 covy = cly{h}.covar(:,j);
wolffd@0 112 mux = clx{1}.centr(:,i);
wolffd@0 113 muy = cly{h}.centr(:,j);
wolffd@0 114 cost(i,j) = sum(covx./covy + covy./covx + ...
wolffd@0 115 (mux-muy).^2.*(1./covx + 1./covy) - 2);
wolffd@0 116 end
wolffd@0 117 end
wolffd@0 118 dt{h}{1} = emd_wrapper(cost,clx{1}.weight,cly{h}.weight);
wolffd@0 119 end
wolffd@0 120 end
wolffd@0 121 d = mirscalar(y,'Data',dt,'Title',[get(y,'Title'),' Distance'],...
wolffd@0 122 'Name',get(x,'Name'),'Name2',get(y,'Name'));