Mercurial > hg > camir-aes2014
view 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 |
line wrap: on
line source
function d = mirdist(x,y,dist) % d = mirdist(x,y) evaluates the distance between x and y. % x is the feature values corresponding to one audio file, and y is the % values (for the same feature) corrdponding to one (or several) % audio files. % If x and y are not decomposed into frames, % d = mirdist(x,y,f) specifies distance function. % Default value: f = 'Cosine' % If x and y are composed of clustered frames (using mircluster), the % cluster signatures are compared using Earth Mover Distance. % (Logan, Salomon, 2001) % If x and y contains peaks, the vectors representing the peak % distributions are compared using Euclidean distance. % (used with mirnovelty in Jacobson, 2006) % % The Earth Mover Distance is based on the implementation by Yossi Rubner, % wrapped for Matlab by Elias Pampalk. if not(isa(x,'mirdata')) x = miraudio(x); end if not(isa(y,'mirdata')) y = miraudio(y); end clx = get(x,'Clusters'); if isempty(clx{1}) px = get(x,'PeakPos'); if not(iscell(px)) || isempty(px{1}) || ... not(iscell(px{1})) || isempty(px{1}{1}) || not(iscell(px{1}{1})) if nargin < 3 dist = 'Cosine'; end d = get(x,'Data'); dd = d{1}{1}; if iscell(dd) dd = dd{1}; end if size(dd,2)>1 if size(dd,1)>1 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); else dd = dd'; end end e = get(y,'Data'); dt = cell(1,length(e)); for h = 1:length(e) ee = e{h}{1}; if iscell(ee) ee = ee{1}; end if size(ee,2)>1 if size(ee,1)>1 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); else ee = ee'; end end if isempty(ee) if isempty(dd) dt{h}{1} = 0; else dt{h}{1} = Inf; end else if length(dd)<length(ee) dd(length(ee)) = 0; %ee = ee(1:length(d)); elseif length(ee)<length(dd) ee(length(dd)) = 0; %dd = dd(1:length(ee)); end if length(dd) == 1 dt{h}{1} = abs(dd-ee); elseif norm(dd) && norm(ee) dt{h}{1} = pdist([dd(:)';ee(:)'],dist); else dt{h}{1} = NaN; end end end else % Euclidean distance between vectors to compare data with peaks % (used with mirnovelty in Jacobson, 2006). sig = pi/4; dx = get(x,'Data'); nx = length(px{1}{1}{1}); cx = mean(px{1}{1}{1}/length(dx{1}{1})); dy = get(y,'Data'); py = get(y,'PeakPos'); dt = cell(1,length(py)); for h = 1:length(py) ny = length(py{h}{1}{1}); cy = mean(py{h}{1}{1}/length(dy{h}{1})); dt{h}{1} = sqrt((nx*cos(sig*cx)-ny*cos(sig*cy))^2 ... +(nx*sin(sig*cx)-ny*sin(sig*cy))^2); end end else % Earth Mover's Distance to compare clustered data. cly = get(y,'Clusters'); dt = cell(1,length(cly)); for h = 1:length(cly) cost = zeros(length(clx{1}.weight),length(cly{h}.weight)); for i = 1:length(clx{1}.weight) for j = 1:length(cly{h}.weight) covx = clx{1}.covar(:,i); covy = cly{h}.covar(:,j); mux = clx{1}.centr(:,i); muy = cly{h}.centr(:,j); cost(i,j) = sum(covx./covy + covy./covx + ... (mux-muy).^2.*(1./covx + 1./covy) - 2); end end dt{h}{1} = emd_wrapper(cost,clx{1}.weight,cly{h}.weight); end end d = mirscalar(y,'Data',dt,'Title',[get(y,'Title'),' Distance'],... 'Name',get(x,'Name'),'Name2',get(y,'Name'));