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

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